mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-09-01 03:02:06 +02:00
Standardize indention on spaces, not tabs.
This commit is contained in:
810
polyhedra.scad
810
polyhedra.scad
@@ -22,9 +22,9 @@ include <hull.scad>
|
||||
// Groups entries in "arr" into groups of equal values and returns index lists of those groups
|
||||
|
||||
function _unique_groups(m) = [
|
||||
for (i=[0:1:len(m)-1]) let(
|
||||
s = search([m[i]], m, 0)[0]
|
||||
) if (s[0]==i) s
|
||||
for (i=[0:1:len(m)-1]) let(
|
||||
s = search([m[i]], m, 0)[0]
|
||||
) if (s[0]==i) s
|
||||
];
|
||||
|
||||
|
||||
@@ -277,82 +277,82 @@ function _unique_groups(m) = [
|
||||
// regular_polyhedron("pentagonal hexecontahedron", or=1,facedown=false);
|
||||
// }
|
||||
module regular_polyhedron(
|
||||
name=undef,
|
||||
index=undef,
|
||||
type=undef,
|
||||
faces=undef,
|
||||
facetype=undef,
|
||||
hasfaces=undef,
|
||||
side=1,
|
||||
ir=undef,
|
||||
mr=undef,
|
||||
or=undef,
|
||||
r=undef,
|
||||
d=undef,
|
||||
anchor=[0,0,0],
|
||||
center=undef,
|
||||
rounding=0,
|
||||
repeat=true,
|
||||
facedown=true,
|
||||
draw=true,
|
||||
rotate_children=true,
|
||||
stellate = false,
|
||||
longside=undef, // special parameter for trapezohedron
|
||||
h=undef // special parameter for trapezohedron
|
||||
name=undef,
|
||||
index=undef,
|
||||
type=undef,
|
||||
faces=undef,
|
||||
facetype=undef,
|
||||
hasfaces=undef,
|
||||
side=1,
|
||||
ir=undef,
|
||||
mr=undef,
|
||||
or=undef,
|
||||
r=undef,
|
||||
d=undef,
|
||||
anchor=[0,0,0],
|
||||
center=undef,
|
||||
rounding=0,
|
||||
repeat=true,
|
||||
facedown=true,
|
||||
draw=true,
|
||||
rotate_children=true,
|
||||
stellate = false,
|
||||
longside=undef, // special parameter for trapezohedron
|
||||
h=undef // special parameter for trapezohedron
|
||||
) {
|
||||
assert(rounding>=0, "'rounding' must be nonnegative");
|
||||
entry = regular_polyhedron_info(
|
||||
"fullentry", name=name, index=index,
|
||||
type=type, faces=faces, facetype=facetype,
|
||||
hasfaces=hasfaces, side=side,
|
||||
ir=ir, mr=mr, or=or,
|
||||
r=r, d=d,
|
||||
anchor=anchor, center=center,
|
||||
facedown=facedown,
|
||||
stellate=stellate,
|
||||
longside=longside, h=h
|
||||
);
|
||||
scaled_points = entry[0];
|
||||
translation = entry[1];
|
||||
face_triangles = entry[2];
|
||||
faces = entry[3];
|
||||
face_normals = entry[4];
|
||||
in_radius = entry[5];
|
||||
if (draw){
|
||||
if (rounding==0)
|
||||
polyhedron(move(translation, p=scaled_points), faces = face_triangles);
|
||||
else {
|
||||
fn = segs(rounding);
|
||||
rounding = rounding/cos(180/fn);
|
||||
adjusted_scale = 1 - rounding / in_radius;
|
||||
minkowski(){
|
||||
sphere(r=rounding, $fn=fn);
|
||||
polyhedron(move(translation,p=adjusted_scale*scaled_points), faces = face_triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($children>0) {
|
||||
maxrange = repeat ? len(faces)-1 : $children-1;
|
||||
for(i=[0:1:maxrange]) {
|
||||
// Would like to orient so an edge (longest edge?) is parallel to x axis
|
||||
facepts = move(translation, p=select(scaled_points, faces[i]));
|
||||
center = mean(facepts);
|
||||
rotatedface = rot(from=face_normals[i], to=[0,0,1], p=move(-center, p=facepts));
|
||||
clockwise = sortidx([for(pt=rotatedface) -atan2(pt.y,pt.x)]);
|
||||
$face = rotate_children?
|
||||
path2d(select(rotatedface,clockwise)) :
|
||||
select(move(-center,p=facepts), clockwise);
|
||||
$faceindex = i;
|
||||
$center = -translation-center;
|
||||
translate(center)
|
||||
if (rotate_children) {
|
||||
rot(from=[0,0,1], to=face_normals[i])
|
||||
children(i % $children);
|
||||
} else {
|
||||
children(i % $children);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(rounding>=0, "'rounding' must be nonnegative");
|
||||
entry = regular_polyhedron_info(
|
||||
"fullentry", name=name, index=index,
|
||||
type=type, faces=faces, facetype=facetype,
|
||||
hasfaces=hasfaces, side=side,
|
||||
ir=ir, mr=mr, or=or,
|
||||
r=r, d=d,
|
||||
anchor=anchor, center=center,
|
||||
facedown=facedown,
|
||||
stellate=stellate,
|
||||
longside=longside, h=h
|
||||
);
|
||||
scaled_points = entry[0];
|
||||
translation = entry[1];
|
||||
face_triangles = entry[2];
|
||||
faces = entry[3];
|
||||
face_normals = entry[4];
|
||||
in_radius = entry[5];
|
||||
if (draw){
|
||||
if (rounding==0)
|
||||
polyhedron(move(translation, p=scaled_points), faces = face_triangles);
|
||||
else {
|
||||
fn = segs(rounding);
|
||||
rounding = rounding/cos(180/fn);
|
||||
adjusted_scale = 1 - rounding / in_radius;
|
||||
minkowski(){
|
||||
sphere(r=rounding, $fn=fn);
|
||||
polyhedron(move(translation,p=adjusted_scale*scaled_points), faces = face_triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($children>0) {
|
||||
maxrange = repeat ? len(faces)-1 : $children-1;
|
||||
for(i=[0:1:maxrange]) {
|
||||
// Would like to orient so an edge (longest edge?) is parallel to x axis
|
||||
facepts = move(translation, p=select(scaled_points, faces[i]));
|
||||
center = mean(facepts);
|
||||
rotatedface = rot(from=face_normals[i], to=[0,0,1], p=move(-center, p=facepts));
|
||||
clockwise = sortidx([for(pt=rotatedface) -atan2(pt.y,pt.x)]);
|
||||
$face = rotate_children?
|
||||
path2d(select(rotatedface,clockwise)) :
|
||||
select(move(-center,p=facepts), clockwise);
|
||||
$faceindex = i;
|
||||
$center = -translation-center;
|
||||
translate(center)
|
||||
if (rotate_children) {
|
||||
rot(from=[0,0,1], to=face_normals[i])
|
||||
children(i % $children);
|
||||
} else {
|
||||
children(i % $children);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -364,17 +364,17 @@ module regular_polyhedron(
|
||||
function _even_perms(v) = [v, [v[2], v[0], v[1]], [v[1],v[2],v[0]]];
|
||||
function _all_perms(v) = [v, [v[2], v[0], v[1]], [v[1],v[2],v[0]], [v[1],v[0],v[2]],[v[2],v[1],v[0]],[v[0],v[2],v[1]]];
|
||||
//
|
||||
// Point reflections across all planes. In the unconstrained case, this means one point becomes 8 points.
|
||||
// Point reflections across all planes. In the unconstrained case, this means one point becomes 8 points.
|
||||
//
|
||||
// sign=="even" means an even number of minus signs (odd number of plus signs)
|
||||
// sign=="odd" means an odd number of minus signs (even number of plus signs)
|
||||
//
|
||||
function _point_ref(points, sign="both") =
|
||||
unique([
|
||||
for(i=[-1,1],j=[-1,1],k=[-1,1])
|
||||
if (sign=="both" || sign=="even" && i*j*k>0 || sign=="odd" && i*j*k<0)
|
||||
each [for(point=points) vmul(point,[i,j,k])]
|
||||
]);
|
||||
unique([
|
||||
for(i=[-1,1],j=[-1,1],k=[-1,1])
|
||||
if (sign=="both" || sign=="even" && i*j*k>0 || sign=="odd" && i*j*k<0)
|
||||
each [for(point=points) vmul(point,[i,j,k])]
|
||||
]);
|
||||
//
|
||||
_tribonacci=(1+4*cosh(acosh(2+3/8)/3))/3;
|
||||
//
|
||||
@@ -384,160 +384,160 @@ _tribonacci=(1+4*cosh(acosh(2+3/8)/3))/3;
|
||||
// The polyhedra information is from Wikipedia and http://dmccooey.com/polyhedra/
|
||||
//
|
||||
_polyhedra_ = [
|
||||
// Platonic Solids
|
||||
// Platonic Solids
|
||||
|
||||
["tetrahedron", "platonic", 4,[3], 2*sqrt(2), sqrt(6)/12, sqrt(2)/4, sqrt(6)/4, 1/6/sqrt(2),
|
||||
_point_ref([[1,1,1]], sign="even")],
|
||||
["cube", "platonic", 6, [4], 2, 1/2, 1/sqrt(2), sqrt(3)/2, 1,
|
||||
_point_ref([[1,1,1]])],
|
||||
["octahedron", "platonic", 8, [3], sqrt(2), sqrt(6)/6, 1/2, sqrt(2)/2, sqrt(2)/3,
|
||||
_point_ref(_even_perms([1,0,0]))],
|
||||
["dodecahedron", "platonic", 12, [5], 2/PHI, sqrt(5/2+11*sqrt(5)/10)/2, (3+sqrt(5))/4, sqrt(3)*PHI/2, (15+7*sqrt(5))/4,
|
||||
_point_ref(concat([[1,1,1]],_even_perms([0,PHI,1/PHI])))],
|
||||
["icosahedron", "platonic", 20, [3], 2, PHI*PHI/2/sqrt(3), cos(36), sin(72), 5*(3+sqrt(5))/12,
|
||||
_point_ref(_even_perms([0,1,PHI]))],
|
||||
["tetrahedron", "platonic", 4,[3], 2*sqrt(2), sqrt(6)/12, sqrt(2)/4, sqrt(6)/4, 1/6/sqrt(2),
|
||||
_point_ref([[1,1,1]], sign="even")],
|
||||
["cube", "platonic", 6, [4], 2, 1/2, 1/sqrt(2), sqrt(3)/2, 1,
|
||||
_point_ref([[1,1,1]])],
|
||||
["octahedron", "platonic", 8, [3], sqrt(2), sqrt(6)/6, 1/2, sqrt(2)/2, sqrt(2)/3,
|
||||
_point_ref(_even_perms([1,0,0]))],
|
||||
["dodecahedron", "platonic", 12, [5], 2/PHI, sqrt(5/2+11*sqrt(5)/10)/2, (3+sqrt(5))/4, sqrt(3)*PHI/2, (15+7*sqrt(5))/4,
|
||||
_point_ref(concat([[1,1,1]],_even_perms([0,PHI,1/PHI])))],
|
||||
["icosahedron", "platonic", 20, [3], 2, PHI*PHI/2/sqrt(3), cos(36), sin(72), 5*(3+sqrt(5))/12,
|
||||
_point_ref(_even_perms([0,1,PHI]))],
|
||||
|
||||
// Archimedian Solids, listed in order by Wenniger number, W6-W18
|
||||
// Archimedian Solids, listed in order by Wenniger number, W6-W18
|
||||
|
||||
["truncated tetrahedron", "archimedean", 8,[6,3], sqrt(8), sqrt(6)/4, 3*sqrt(2)/4, sqrt(11/8), 23*sqrt(2)/12,
|
||||
_point_ref(_all_perms([1,1,3]),sign="even")],
|
||||
["truncated octahedron", "archimedean", 14, [6,4], sqrt(2), sqrt(6)/2, 1.5, sqrt(10)/2, 8*sqrt(2),
|
||||
_point_ref(_all_perms([0,1,2]))],
|
||||
["truncated cube", "archimedean", 14, [8,3], 2*(sqrt(2)-1), (1+sqrt(2))/2, 1+sqrt(2)/2, sqrt(7+4*sqrt(2))/2, 7+14*sqrt(2)/3,
|
||||
_point_ref(_all_perms([1,1,sqrt(2)-1]))],
|
||||
["truncated icosahedron", "archimedean", 32, [6, 5], 2, (3*sqrt(3)+sqrt(15))/4, 3*PHI/2, sqrt(58+18*sqrt(5))/4, (125+43*sqrt(5))/4,
|
||||
_point_ref(concat(
|
||||
_even_perms([0,1,3*PHI]),
|
||||
_even_perms([1,2+PHI,2*PHI]),
|
||||
_even_perms([PHI,2,PHI*PHI*PHI])
|
||||
))],
|
||||
["truncated dodecahedron", "archimedean", 32, [10, 3], 2*PHI-2, sqrt(7+11*PHI)/2, (3*PHI+1)/2,sqrt(11+PHI*15)/2, 5*(99+47*sqrt(5))/12,
|
||||
_point_ref(concat(
|
||||
_even_perms([0,1/PHI, 2+PHI]),
|
||||
_even_perms([1/PHI,PHI,2*PHI]),
|
||||
_even_perms([PHI,2,PHI+1])
|
||||
))],
|
||||
["cuboctahedron", "archimedean", 14, [4,3], sqrt(2), sqrt(2)/2, sqrt(3)/2, 1, 5*sqrt(2)/3,
|
||||
_point_ref(_all_perms([1,1,0]))],
|
||||
["icosidodecahedron", "archimedean", 32, [5,3], 1, sqrt(5*(5+2*sqrt(5)))/5,sqrt(5+2*sqrt(5))/2, PHI, (14+17*PHI)/3,
|
||||
_point_ref(concat(_even_perms([0,0,PHI]),_even_perms([1/2,PHI/2,PHI*PHI/2])))],
|
||||
["rhombicuboctahedron", "archimedean", 26, [4, 3], 2, (1+sqrt(2))/2, sqrt(2*(2+sqrt(2)))/2, sqrt(5+2*sqrt(2))/2, 4+10*sqrt(2)/3,
|
||||
_point_ref(_even_perms([1,1,1+sqrt(2)]))],
|
||||
["rhombicosidodecahedron", "archimedean", 62, [5,4,3], 2, 3/10*sqrt(15+20*PHI), sqrt(3/2+2*PHI), sqrt(8*PHI+7)/2, (31+58*PHI)/3,
|
||||
_point_ref(concat(
|
||||
_even_perms([1,1,PHI*PHI*PHI]),
|
||||
_even_perms([PHI*PHI,PHI,2*PHI]),
|
||||
_even_perms([2+PHI,0,PHI*PHI])
|
||||
))],
|
||||
["truncated cuboctahedron", "archimedean", 26, [8, 6, 4], 2, (1+2*sqrt(2))/2, sqrt(6*(2+sqrt(2)))/2, sqrt(13+6*sqrt(2))/2, (22+14*sqrt(2)),
|
||||
_point_ref(_all_perms([1,1+sqrt(2), 1+2*sqrt(2)]))],
|
||||
["truncated icosidodecahedron", "archimedean", 62, [10,6,4], 2*PHI - 2, sqrt(15/4+5*PHI),sqrt(9/2+6*PHI),sqrt(19/4+6*PHI), 95+50*sqrt(5),
|
||||
_point_ref(concat(
|
||||
_even_perms([1/PHI,1/PHI,3+PHI]),
|
||||
_even_perms([2/PHI,PHI,1+2*PHI]),
|
||||
_even_perms([1/PHI,PHI*PHI,3*PHI-1]),
|
||||
_even_perms([2*PHI-1,2,2+PHI]),
|
||||
_even_perms([PHI,3,2*PHI])
|
||||
))],
|
||||
["snub cube", "archimedean", 38, [4,3], 1.60972,1.14261350892596209,1.24722316799364325, 1.34371337374460170,
|
||||
sqrt((613*_tribonacci+203)/(9*(35*_tribonacci-62))),
|
||||
concat(
|
||||
_point_ref(_even_perms([1,1/_tribonacci,_tribonacci]), sign="odd"),
|
||||
_point_ref(_even_perms([1,_tribonacci,1/_tribonacci]), sign="even")
|
||||
)],
|
||||
["snub dodecahedron", "archimedean", 92, [5, 3], 1, 1.98091594728184,2.097053835252087,2.155837375115, 37.61664996273336,
|
||||
concat(
|
||||
_point_ref(_even_perms([0.374821658114562,0.330921024729844,2.097053835252088]), sign="odd"),
|
||||
_point_ref(_even_perms([0.192893711352359,1.249503788463027,1.746186440985827]), sign="odd"),
|
||||
_point_ref(_even_perms([1.103156835071754,0.847550046789061,1.646917940690374]), sign="odd"),
|
||||
_point_ref(_even_perms([0.567715369466922,0.643029605914072,1.977838965420219]), sign="even"),
|
||||
_point_ref(_even_perms([1.415265416255982,0.728335176957192,1.454024229338015]), sign="even")
|
||||
)],
|
||||
["truncated tetrahedron", "archimedean", 8,[6,3], sqrt(8), sqrt(6)/4, 3*sqrt(2)/4, sqrt(11/8), 23*sqrt(2)/12,
|
||||
_point_ref(_all_perms([1,1,3]),sign="even")],
|
||||
["truncated octahedron", "archimedean", 14, [6,4], sqrt(2), sqrt(6)/2, 1.5, sqrt(10)/2, 8*sqrt(2),
|
||||
_point_ref(_all_perms([0,1,2]))],
|
||||
["truncated cube", "archimedean", 14, [8,3], 2*(sqrt(2)-1), (1+sqrt(2))/2, 1+sqrt(2)/2, sqrt(7+4*sqrt(2))/2, 7+14*sqrt(2)/3,
|
||||
_point_ref(_all_perms([1,1,sqrt(2)-1]))],
|
||||
["truncated icosahedron", "archimedean", 32, [6, 5], 2, (3*sqrt(3)+sqrt(15))/4, 3*PHI/2, sqrt(58+18*sqrt(5))/4, (125+43*sqrt(5))/4,
|
||||
_point_ref(concat(
|
||||
_even_perms([0,1,3*PHI]),
|
||||
_even_perms([1,2+PHI,2*PHI]),
|
||||
_even_perms([PHI,2,PHI*PHI*PHI])
|
||||
))],
|
||||
["truncated dodecahedron", "archimedean", 32, [10, 3], 2*PHI-2, sqrt(7+11*PHI)/2, (3*PHI+1)/2,sqrt(11+PHI*15)/2, 5*(99+47*sqrt(5))/12,
|
||||
_point_ref(concat(
|
||||
_even_perms([0,1/PHI, 2+PHI]),
|
||||
_even_perms([1/PHI,PHI,2*PHI]),
|
||||
_even_perms([PHI,2,PHI+1])
|
||||
))],
|
||||
["cuboctahedron", "archimedean", 14, [4,3], sqrt(2), sqrt(2)/2, sqrt(3)/2, 1, 5*sqrt(2)/3,
|
||||
_point_ref(_all_perms([1,1,0]))],
|
||||
["icosidodecahedron", "archimedean", 32, [5,3], 1, sqrt(5*(5+2*sqrt(5)))/5,sqrt(5+2*sqrt(5))/2, PHI, (14+17*PHI)/3,
|
||||
_point_ref(concat(_even_perms([0,0,PHI]),_even_perms([1/2,PHI/2,PHI*PHI/2])))],
|
||||
["rhombicuboctahedron", "archimedean", 26, [4, 3], 2, (1+sqrt(2))/2, sqrt(2*(2+sqrt(2)))/2, sqrt(5+2*sqrt(2))/2, 4+10*sqrt(2)/3,
|
||||
_point_ref(_even_perms([1,1,1+sqrt(2)]))],
|
||||
["rhombicosidodecahedron", "archimedean", 62, [5,4,3], 2, 3/10*sqrt(15+20*PHI), sqrt(3/2+2*PHI), sqrt(8*PHI+7)/2, (31+58*PHI)/3,
|
||||
_point_ref(concat(
|
||||
_even_perms([1,1,PHI*PHI*PHI]),
|
||||
_even_perms([PHI*PHI,PHI,2*PHI]),
|
||||
_even_perms([2+PHI,0,PHI*PHI])
|
||||
))],
|
||||
["truncated cuboctahedron", "archimedean", 26, [8, 6, 4], 2, (1+2*sqrt(2))/2, sqrt(6*(2+sqrt(2)))/2, sqrt(13+6*sqrt(2))/2, (22+14*sqrt(2)),
|
||||
_point_ref(_all_perms([1,1+sqrt(2), 1+2*sqrt(2)]))],
|
||||
["truncated icosidodecahedron", "archimedean", 62, [10,6,4], 2*PHI - 2, sqrt(15/4+5*PHI),sqrt(9/2+6*PHI),sqrt(19/4+6*PHI), 95+50*sqrt(5),
|
||||
_point_ref(concat(
|
||||
_even_perms([1/PHI,1/PHI,3+PHI]),
|
||||
_even_perms([2/PHI,PHI,1+2*PHI]),
|
||||
_even_perms([1/PHI,PHI*PHI,3*PHI-1]),
|
||||
_even_perms([2*PHI-1,2,2+PHI]),
|
||||
_even_perms([PHI,3,2*PHI])
|
||||
))],
|
||||
["snub cube", "archimedean", 38, [4,3], 1.60972,1.14261350892596209,1.24722316799364325, 1.34371337374460170,
|
||||
sqrt((613*_tribonacci+203)/(9*(35*_tribonacci-62))),
|
||||
concat(
|
||||
_point_ref(_even_perms([1,1/_tribonacci,_tribonacci]), sign="odd"),
|
||||
_point_ref(_even_perms([1,_tribonacci,1/_tribonacci]), sign="even")
|
||||
)],
|
||||
["snub dodecahedron", "archimedean", 92, [5, 3], 1, 1.98091594728184,2.097053835252087,2.155837375115, 37.61664996273336,
|
||||
concat(
|
||||
_point_ref(_even_perms([0.374821658114562,0.330921024729844,2.097053835252088]), sign="odd"),
|
||||
_point_ref(_even_perms([0.192893711352359,1.249503788463027,1.746186440985827]), sign="odd"),
|
||||
_point_ref(_even_perms([1.103156835071754,0.847550046789061,1.646917940690374]), sign="odd"),
|
||||
_point_ref(_even_perms([0.567715369466922,0.643029605914072,1.977838965420219]), sign="even"),
|
||||
_point_ref(_even_perms([1.415265416255982,0.728335176957192,1.454024229338015]), sign="even")
|
||||
)],
|
||||
|
||||
// Catalan Solids, the duals to the Archimedean solids, listed in the corresponding order
|
||||
// Catalan Solids, the duals to the Archimedean solids, listed in the corresponding order
|
||||
|
||||
["triakis tetrahedron","catalan", 12, [3], 9/5, 5*sqrt(22)/44, 5*sqrt(2)/12, 5*sqrt(6)/12, 25*sqrt(2)/36,
|
||||
concat(
|
||||
_point_ref([9*sqrt(2)/20*[1,1,1]],sign="even"),
|
||||
_point_ref([3*sqrt(2)/4*[1,1,1]],sign="odd")
|
||||
)],
|
||||
["tetrakis hexahedron", "catalan", 24, [3], 1, 2/sqrt(5), 2*sqrt(2)/3, 2/sqrt(3), 32/9,
|
||||
_point_ref(concat([[2/3,2/3,2/3]],_even_perms([1,0,0])))],
|
||||
["triakis octahedron", "catalan", 24, [3], 2, sqrt(17*(23+16*sqrt(2)))/34, 1/2+sqrt(2)/4,(1+sqrt(2))/2,3/2+sqrt(2),
|
||||
_point_ref(concat([[1,1,1]],_even_perms([1+sqrt(2),0,0])))],
|
||||
["pentakis dodecahedron", "catalan", 60, [3], 1,sqrt(477/436+97*sqrt(5)/218), sqrt(5)/4+11/12, sqrt(7/4+sqrt(5)/3), 125*sqrt(5)/36+205/36,
|
||||
_point_ref(concat(
|
||||
_even_perms([0,(5-PHI)/6, PHI/2+2/3]),
|
||||
_even_perms([0,(PHI+1)/2,PHI/2]),[(4*PHI-1)/6 * [1,1,1]]
|
||||
))],
|
||||
["triakis icosahedron", "catalan", 60, [3], 1, sqrt((139+199*PHI)/244), (8*PHI+1)/10, sqrt(13/8+19/8/sqrt(5)), (13*PHI+3)/2,
|
||||
_point_ref(concat(
|
||||
_even_perms([(PHI+7)/10, 0, (8*PHI+1)/10]),
|
||||
_even_perms([0, 1/2, (PHI+1)/2]),[PHI/2*[1,1,1]]
|
||||
))],
|
||||
["rhombic dodecahedron", "catalan", 12, [4], sqrt(3), sqrt(2/3), 2*sqrt(2)/3, 2/sqrt(3), 16*sqrt(3)/9,
|
||||
_point_ref(concat([[1,1,1]], _even_perms([2,0,0])))],
|
||||
["rhombic triacontahedron", "catalan", 30,[4], 1, sqrt(1+2/sqrt(5)), 1+1/sqrt(5), (1+sqrt(5))/2, 4*sqrt(5+2*sqrt(5)),
|
||||
concat(
|
||||
_point_ref(_even_perms([0,sqrt(1+2/sqrt(5)), sqrt((5+sqrt(5))/10)])),
|
||||
_point_ref(_even_perms([0,sqrt(2/(5+sqrt(5))), sqrt(1+2/sqrt(5))])),
|
||||
_point_ref([sqrt((5+sqrt(5))/10)*[1,1,1]])
|
||||
)],
|
||||
["deltoidal icositetrahedron", "catalan", 24, [4], 2*sqrt(10-sqrt(2))/7, 7*sqrt((7+4*sqrt(2))/(34 * (10-sqrt(2)))),
|
||||
7*sqrt(2*(2+sqrt(2)))/sqrt(10-sqrt(2))/4, 7*sqrt(2)/sqrt(10-sqrt(2))/2,
|
||||
(14+21*sqrt(2))/sqrt(10-sqrt(2)),
|
||||
_point_ref(concat(
|
||||
_even_perms([0,1,1]), _even_perms([sqrt(2),0,0]),
|
||||
_even_perms((4+sqrt(2))/7*[1,1,1])
|
||||
))],
|
||||
["deltoidal hexecontahedron", "catalan", 60, [4], sqrt(5*(85-31*sqrt(5)))/11, sqrt(571/164+1269/164/sqrt(5)), 5/4+13/4/sqrt(5),
|
||||
sqrt(147+65*sqrt(5))/6, sqrt(29530+13204*sqrt(5))/3,
|
||||
_point_ref(concat(
|
||||
_even_perms([0,0,sqrt(5)]),
|
||||
_even_perms([0,(15+sqrt(5))/22, (25+9*sqrt(5))/22]),
|
||||
_even_perms([0,(5+3*sqrt(5))/6, (5+sqrt(5))/6]),
|
||||
_even_perms([(5-sqrt(5))/4, sqrt(5)/2, (5+sqrt(5))/4]),
|
||||
[(5+4*sqrt(5))/11*[1,1,1]]
|
||||
))],
|
||||
["disdyakis dodecahedron", "catalan", 48, [3], 1,sqrt(249/194+285/194/sqrt(2)) ,(2+3*sqrt(2))/4, sqrt(183/98+213/98/sqrt(2)),
|
||||
sqrt(6582+4539*sqrt(2))/7,
|
||||
_point_ref(concat(
|
||||
_even_perms([sqrt(183/98+213/98/sqrt(2)),0,0]),
|
||||
_even_perms(sqrt(3+3/sqrt(2))/2 * [1,1,0]),[7/sqrt(6*(10-sqrt(2)))*[1,1,1]]
|
||||
))],
|
||||
["disdyakis triacontahedron","catalan", 120, [3], sqrt(15*(85-31*sqrt(5)))/11, sqrt(3477/964+7707/964/sqrt(5)), 5/4+13/4/sqrt(5),
|
||||
sqrt(441+195*sqrt(5))/10,sqrt(17718/5+39612/5/sqrt(5)),
|
||||
_point_ref(concat(
|
||||
_even_perms([0,0,3*(5+4*sqrt(5))/11]),
|
||||
_even_perms([0,(5-sqrt(5))/2,(5+sqrt(5))/2]),
|
||||
_even_perms([0,(15+9*sqrt(5))/10,3*(5+sqrt(5))/10]),
|
||||
_even_perms([3*(15+sqrt(5))/44,3*(5+4*sqrt(5))/22, (75+27*sqrt(5))/44]), [sqrt(5)*[1,1,1]]
|
||||
))],
|
||||
["pentagonal icositetrahedron","catalan",24, [5], 0.593465355971, 1.950681331784, 2.1015938932963, 2.29400105368695, 35.6302020120713,
|
||||
concat(
|
||||
_point_ref(_even_perms([0.21879664300048044,0.740183741369857,1.0236561781126901]),sign="even"),
|
||||
_point_ref(_even_perms([0.21879664300048044,1.0236561781126901,0.740183741369857]),sign="odd"),
|
||||
_point_ref(_even_perms([1.3614101519264425,0,0])),
|
||||
_point_ref([0.7401837413698572*[1,1,1]])
|
||||
)],
|
||||
["pentagonal hexecontahedron", "catalan", 60,[5], 0.58289953474498, 3.499527848905764,3.597624822551189,3.80854772878239, 189.789852066885,
|
||||
concat(
|
||||
_point_ref(_even_perms([0.192893711352359,0.218483370127321,2.097053835252087]), sign="even"),
|
||||
_point_ref(_even_perms([0,0.7554672605165955,1.9778389654202186])),
|
||||
_point_ref(_even_perms([0,1.888445389283669154,1.1671234364753339])),
|
||||
_point_ref(_even_perms([0.56771536946692131,0.824957552676275846,1.8654013108176956657]),sign="odd"),
|
||||
_point_ref(_even_perms([0.37482165811456229,1.13706613386050418,1.746186440985826345]), sign="even"),
|
||||
_point_ref(_even_perms([0.921228888309550,0.95998770139158,1.6469179406903744]),sign="even"),
|
||||
_point_ref(_even_perms([0.7283351769571914773,1.2720962825758121,1.5277030708585051]),sign="odd"),
|
||||
_point_ref([1.222371704903623092*[1,1,1]])
|
||||
)],
|
||||
["triakis tetrahedron","catalan", 12, [3], 9/5, 5*sqrt(22)/44, 5*sqrt(2)/12, 5*sqrt(6)/12, 25*sqrt(2)/36,
|
||||
concat(
|
||||
_point_ref([9*sqrt(2)/20*[1,1,1]],sign="even"),
|
||||
_point_ref([3*sqrt(2)/4*[1,1,1]],sign="odd")
|
||||
)],
|
||||
["tetrakis hexahedron", "catalan", 24, [3], 1, 2/sqrt(5), 2*sqrt(2)/3, 2/sqrt(3), 32/9,
|
||||
_point_ref(concat([[2/3,2/3,2/3]],_even_perms([1,0,0])))],
|
||||
["triakis octahedron", "catalan", 24, [3], 2, sqrt(17*(23+16*sqrt(2)))/34, 1/2+sqrt(2)/4,(1+sqrt(2))/2,3/2+sqrt(2),
|
||||
_point_ref(concat([[1,1,1]],_even_perms([1+sqrt(2),0,0])))],
|
||||
["pentakis dodecahedron", "catalan", 60, [3], 1,sqrt(477/436+97*sqrt(5)/218), sqrt(5)/4+11/12, sqrt(7/4+sqrt(5)/3), 125*sqrt(5)/36+205/36,
|
||||
_point_ref(concat(
|
||||
_even_perms([0,(5-PHI)/6, PHI/2+2/3]),
|
||||
_even_perms([0,(PHI+1)/2,PHI/2]),[(4*PHI-1)/6 * [1,1,1]]
|
||||
))],
|
||||
["triakis icosahedron", "catalan", 60, [3], 1, sqrt((139+199*PHI)/244), (8*PHI+1)/10, sqrt(13/8+19/8/sqrt(5)), (13*PHI+3)/2,
|
||||
_point_ref(concat(
|
||||
_even_perms([(PHI+7)/10, 0, (8*PHI+1)/10]),
|
||||
_even_perms([0, 1/2, (PHI+1)/2]),[PHI/2*[1,1,1]]
|
||||
))],
|
||||
["rhombic dodecahedron", "catalan", 12, [4], sqrt(3), sqrt(2/3), 2*sqrt(2)/3, 2/sqrt(3), 16*sqrt(3)/9,
|
||||
_point_ref(concat([[1,1,1]], _even_perms([2,0,0])))],
|
||||
["rhombic triacontahedron", "catalan", 30,[4], 1, sqrt(1+2/sqrt(5)), 1+1/sqrt(5), (1+sqrt(5))/2, 4*sqrt(5+2*sqrt(5)),
|
||||
concat(
|
||||
_point_ref(_even_perms([0,sqrt(1+2/sqrt(5)), sqrt((5+sqrt(5))/10)])),
|
||||
_point_ref(_even_perms([0,sqrt(2/(5+sqrt(5))), sqrt(1+2/sqrt(5))])),
|
||||
_point_ref([sqrt((5+sqrt(5))/10)*[1,1,1]])
|
||||
)],
|
||||
["deltoidal icositetrahedron", "catalan", 24, [4], 2*sqrt(10-sqrt(2))/7, 7*sqrt((7+4*sqrt(2))/(34 * (10-sqrt(2)))),
|
||||
7*sqrt(2*(2+sqrt(2)))/sqrt(10-sqrt(2))/4, 7*sqrt(2)/sqrt(10-sqrt(2))/2,
|
||||
(14+21*sqrt(2))/sqrt(10-sqrt(2)),
|
||||
_point_ref(concat(
|
||||
_even_perms([0,1,1]), _even_perms([sqrt(2),0,0]),
|
||||
_even_perms((4+sqrt(2))/7*[1,1,1])
|
||||
))],
|
||||
["deltoidal hexecontahedron", "catalan", 60, [4], sqrt(5*(85-31*sqrt(5)))/11, sqrt(571/164+1269/164/sqrt(5)), 5/4+13/4/sqrt(5),
|
||||
sqrt(147+65*sqrt(5))/6, sqrt(29530+13204*sqrt(5))/3,
|
||||
_point_ref(concat(
|
||||
_even_perms([0,0,sqrt(5)]),
|
||||
_even_perms([0,(15+sqrt(5))/22, (25+9*sqrt(5))/22]),
|
||||
_even_perms([0,(5+3*sqrt(5))/6, (5+sqrt(5))/6]),
|
||||
_even_perms([(5-sqrt(5))/4, sqrt(5)/2, (5+sqrt(5))/4]),
|
||||
[(5+4*sqrt(5))/11*[1,1,1]]
|
||||
))],
|
||||
["disdyakis dodecahedron", "catalan", 48, [3], 1,sqrt(249/194+285/194/sqrt(2)) ,(2+3*sqrt(2))/4, sqrt(183/98+213/98/sqrt(2)),
|
||||
sqrt(6582+4539*sqrt(2))/7,
|
||||
_point_ref(concat(
|
||||
_even_perms([sqrt(183/98+213/98/sqrt(2)),0,0]),
|
||||
_even_perms(sqrt(3+3/sqrt(2))/2 * [1,1,0]),[7/sqrt(6*(10-sqrt(2)))*[1,1,1]]
|
||||
))],
|
||||
["disdyakis triacontahedron","catalan", 120, [3], sqrt(15*(85-31*sqrt(5)))/11, sqrt(3477/964+7707/964/sqrt(5)), 5/4+13/4/sqrt(5),
|
||||
sqrt(441+195*sqrt(5))/10,sqrt(17718/5+39612/5/sqrt(5)),
|
||||
_point_ref(concat(
|
||||
_even_perms([0,0,3*(5+4*sqrt(5))/11]),
|
||||
_even_perms([0,(5-sqrt(5))/2,(5+sqrt(5))/2]),
|
||||
_even_perms([0,(15+9*sqrt(5))/10,3*(5+sqrt(5))/10]),
|
||||
_even_perms([3*(15+sqrt(5))/44,3*(5+4*sqrt(5))/22, (75+27*sqrt(5))/44]), [sqrt(5)*[1,1,1]]
|
||||
))],
|
||||
["pentagonal icositetrahedron","catalan",24, [5], 0.593465355971, 1.950681331784, 2.1015938932963, 2.29400105368695, 35.6302020120713,
|
||||
concat(
|
||||
_point_ref(_even_perms([0.21879664300048044,0.740183741369857,1.0236561781126901]),sign="even"),
|
||||
_point_ref(_even_perms([0.21879664300048044,1.0236561781126901,0.740183741369857]),sign="odd"),
|
||||
_point_ref(_even_perms([1.3614101519264425,0,0])),
|
||||
_point_ref([0.7401837413698572*[1,1,1]])
|
||||
)],
|
||||
["pentagonal hexecontahedron", "catalan", 60,[5], 0.58289953474498, 3.499527848905764,3.597624822551189,3.80854772878239, 189.789852066885,
|
||||
concat(
|
||||
_point_ref(_even_perms([0.192893711352359,0.218483370127321,2.097053835252087]), sign="even"),
|
||||
_point_ref(_even_perms([0,0.7554672605165955,1.9778389654202186])),
|
||||
_point_ref(_even_perms([0,1.888445389283669154,1.1671234364753339])),
|
||||
_point_ref(_even_perms([0.56771536946692131,0.824957552676275846,1.8654013108176956657]),sign="odd"),
|
||||
_point_ref(_even_perms([0.37482165811456229,1.13706613386050418,1.746186440985826345]), sign="even"),
|
||||
_point_ref(_even_perms([0.921228888309550,0.95998770139158,1.6469179406903744]),sign="even"),
|
||||
_point_ref(_even_perms([0.7283351769571914773,1.2720962825758121,1.5277030708585051]),sign="odd"),
|
||||
_point_ref([1.222371704903623092*[1,1,1]])
|
||||
)],
|
||||
];
|
||||
|
||||
|
||||
_stellated_polyhedra_ = [
|
||||
["great dodecahedron", "icosahedron", -sqrt(5/3-PHI)],
|
||||
["small stellated dodecahedron", "dodecahedron", sqrt((5+2*sqrt(5))/5)],
|
||||
["great stellated dodecahedron", "icosahedron", sqrt(2/3+PHI)],
|
||||
["great dodecahedron", "icosahedron", -sqrt(5/3-PHI)],
|
||||
["small stellated dodecahedron", "dodecahedron", sqrt((5+2*sqrt(5))/5)],
|
||||
["great stellated dodecahedron", "icosahedron", sqrt(2/3+PHI)],
|
||||
];
|
||||
|
||||
|
||||
@@ -587,130 +587,130 @@ _stellated_polyhedra_ = [
|
||||
// longside = Specify the long side length for a trapezohedron. Ignored for other shapes.
|
||||
// h = Specify the height of the apex for a trapezohedron. Ignored for other shapes.
|
||||
function regular_polyhedron_info(
|
||||
info=undef, name=undef,
|
||||
index=undef, type=undef,
|
||||
faces=undef, facetype=undef,
|
||||
hasfaces=undef, side=1,
|
||||
ir=undef, mr=undef, or=undef,
|
||||
r=undef, d=undef,
|
||||
anchor=[0,0,0], center=undef,
|
||||
facedown=true, stellate=false,
|
||||
longside=undef, h=undef // special parameters for trapezohedron
|
||||
info=undef, name=undef,
|
||||
index=undef, type=undef,
|
||||
faces=undef, facetype=undef,
|
||||
hasfaces=undef, side=1,
|
||||
ir=undef, mr=undef, or=undef,
|
||||
r=undef, d=undef,
|
||||
anchor=[0,0,0], center=undef,
|
||||
facedown=true, stellate=false,
|
||||
longside=undef, h=undef // special parameters for trapezohedron
|
||||
) = let(
|
||||
anchor = !is_undef(center) ? [0,0,0] : anchor,
|
||||
argcount = num_defined([ir,mr,or,r,d])
|
||||
)
|
||||
assert(argcount<=1, "You must specify only one of 'ir', 'mr', 'or', 'r', and 'd'")
|
||||
let(
|
||||
//////////////////////
|
||||
//Index values into the _polyhedra_ array
|
||||
//
|
||||
pname = 0, // name of polyhedron
|
||||
class = 1, // class name (e.g. platonic, archimedean)
|
||||
facecount = 2, // number of faces
|
||||
facevertices = 3, // vertices on the faces, e.g. [3] for all triangles, [3,4] for triangles and squares
|
||||
edgelen = 4, // length of the edge for the vertex list in the database
|
||||
in_radius = 5, // in radius for unit polyhedron (shortest side 1)
|
||||
mid_radius = 6, // mid radius for unit polyhedron
|
||||
out_radius = 7, // out radius for unit polyhedron
|
||||
volume = 8, // volume of unit polyhedron (data not validated, not used right now)
|
||||
vertices = 9, // vertex list (in arbitrary order)
|
||||
//////////////////////
|
||||
r = !is_undef(d) ? d/2 : r,
|
||||
or = !is_undef(r) ? r : or,
|
||||
stellate_index = search([name], _stellated_polyhedra_, 1, 0)[0],
|
||||
name = stellate_index==[] ? name : _stellated_polyhedra_[stellate_index][1],
|
||||
stellate = stellate_index==[] ? stellate : _stellated_polyhedra_[stellate_index][2],
|
||||
indexlist = (
|
||||
name=="trapezohedron" ? [0] : [ // dumy list of one item
|
||||
for(i=[0:1:len(_polyhedra_)-1]) (
|
||||
if (
|
||||
(is_undef(name) || _polyhedra_[i][pname]==name) &&
|
||||
(is_undef(type) || _polyhedra_[i][class]==type) &&
|
||||
(is_undef(faces) || _polyhedra_[i][facecount]==faces) &&
|
||||
(
|
||||
is_undef(facetype) || 0==compare_lists(
|
||||
is_list(facetype)? reverse(sort(facetype)) : [facetype],
|
||||
_polyhedra_[i][facevertices]
|
||||
)
|
||||
) &&
|
||||
(is_undef(hasfaces) || any([for (ft=hasfaces) in_list(ft,_polyhedra_[i][facevertices])]))
|
||||
) i
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
assert(len(indexlist)>0, "No polyhedra meet your specification")
|
||||
let(validindex = is_undef(index) || (index>=0 && index<len(indexlist)))
|
||||
assert(validindex, str(
|
||||
len(indexlist),
|
||||
" polyhedra meet specifications, so 'index' must be in [0,",
|
||||
len(indexlist)-1,
|
||||
"], but 'index' is ",
|
||||
index
|
||||
))
|
||||
let(
|
||||
entry = (
|
||||
name == "trapezohedron"? (
|
||||
trapezohedron(faces=faces, side=side, longside=longside, h=h, r=r)
|
||||
) : (
|
||||
_polyhedra_[!is_undef(index)?
|
||||
indexlist[index] :
|
||||
indexlist[0]]
|
||||
)
|
||||
),
|
||||
valid_facedown = is_bool(facedown) || in_list(facedown, entry[facevertices])
|
||||
)
|
||||
assert(valid_facedown,str("'facedown' set to ",facedown," but selected polygon only has faces with size(s) ",entry[facevertices]))
|
||||
let(
|
||||
scalefactor = (
|
||||
name=="trapezohedron" ? 1 : (
|
||||
argcount == 0? side :
|
||||
!is_undef(ir)? ir/entry[in_radius] :
|
||||
!is_undef(mr)? mr/entry[mid_radius] : or/entry[out_radius]
|
||||
) / entry[edgelen]
|
||||
),
|
||||
face_triangles = hull(entry[vertices]),
|
||||
faces_normals_vertices = stellate_faces(
|
||||
entry[edgelen], stellate, entry[vertices],
|
||||
entry[facevertices]==[3]?
|
||||
[face_triangles, [for(face=face_triangles) _facenormal(entry[vertices],face)]] :
|
||||
_full_faces(entry[vertices], face_triangles)
|
||||
),
|
||||
faces = faces_normals_vertices[0],
|
||||
faces_vertex_count = [for(face=faces) len(face)],
|
||||
facedown = facedown == true ? (stellate==false? entry[facevertices][0] : 3) : facedown,
|
||||
down_direction = facedown == false? [0,0,-1] :
|
||||
faces_normals_vertices[1][search(facedown, faces_vertex_count)[0]],
|
||||
scaled_points = scalefactor * rot(p=faces_normals_vertices[2], from=down_direction, to=[0,0,-1]),
|
||||
bounds = pointlist_bounds(scaled_points),
|
||||
boundtable = [bounds[0], [0,0,0], bounds[1]],
|
||||
translation = [for(i=[0:2]) -boundtable[1+anchor[i]][i]],
|
||||
face_normals = rot(p=faces_normals_vertices[1], from=down_direction, to=[0,0,-1]),
|
||||
side_length = scalefactor * entry[edgelen]
|
||||
)
|
||||
info == "fullentry" ? [
|
||||
scaled_points,
|
||||
translation,
|
||||
stellate ? faces : face_triangles,
|
||||
faces,
|
||||
face_normals,
|
||||
side_length*entry[in_radius]
|
||||
] :
|
||||
info == "vnf" ? [move(translation,p=scaled_points), stellate ? faces : face_triangles] :
|
||||
info == "vertices" ? move(translation,p=scaled_points) :
|
||||
info == "faces" ? faces :
|
||||
info == "face normals" ? face_normals :
|
||||
info == "in_radius" ? side_length * entry[in_radius] :
|
||||
info == "mid_radius" ? side_length * entry[mid_radius] :
|
||||
info == "out_radius" ? side_length * entry[out_radius] :
|
||||
info == "index set" ? indexlist :
|
||||
info == "face vertices" ? (stellate==false? entry[facevertices] : [3]) :
|
||||
info == "edge length" ? scalefactor * entry[edgelen] :
|
||||
info == "center" ? translation :
|
||||
info == "type" ? entry[class] :
|
||||
info == "name" ? entry[pname] :
|
||||
echo_warning(str("Unknown info type '",info,"' requested"));
|
||||
anchor = !is_undef(center) ? [0,0,0] : anchor,
|
||||
argcount = num_defined([ir,mr,or,r,d])
|
||||
)
|
||||
assert(argcount<=1, "You must specify only one of 'ir', 'mr', 'or', 'r', and 'd'")
|
||||
let(
|
||||
//////////////////////
|
||||
//Index values into the _polyhedra_ array
|
||||
//
|
||||
pname = 0, // name of polyhedron
|
||||
class = 1, // class name (e.g. platonic, archimedean)
|
||||
facecount = 2, // number of faces
|
||||
facevertices = 3, // vertices on the faces, e.g. [3] for all triangles, [3,4] for triangles and squares
|
||||
edgelen = 4, // length of the edge for the vertex list in the database
|
||||
in_radius = 5, // in radius for unit polyhedron (shortest side 1)
|
||||
mid_radius = 6, // mid radius for unit polyhedron
|
||||
out_radius = 7, // out radius for unit polyhedron
|
||||
volume = 8, // volume of unit polyhedron (data not validated, not used right now)
|
||||
vertices = 9, // vertex list (in arbitrary order)
|
||||
//////////////////////
|
||||
r = !is_undef(d) ? d/2 : r,
|
||||
or = !is_undef(r) ? r : or,
|
||||
stellate_index = search([name], _stellated_polyhedra_, 1, 0)[0],
|
||||
name = stellate_index==[] ? name : _stellated_polyhedra_[stellate_index][1],
|
||||
stellate = stellate_index==[] ? stellate : _stellated_polyhedra_[stellate_index][2],
|
||||
indexlist = (
|
||||
name=="trapezohedron" ? [0] : [ // dumy list of one item
|
||||
for(i=[0:1:len(_polyhedra_)-1]) (
|
||||
if (
|
||||
(is_undef(name) || _polyhedra_[i][pname]==name) &&
|
||||
(is_undef(type) || _polyhedra_[i][class]==type) &&
|
||||
(is_undef(faces) || _polyhedra_[i][facecount]==faces) &&
|
||||
(
|
||||
is_undef(facetype) || 0==compare_lists(
|
||||
is_list(facetype)? reverse(sort(facetype)) : [facetype],
|
||||
_polyhedra_[i][facevertices]
|
||||
)
|
||||
) &&
|
||||
(is_undef(hasfaces) || any([for (ft=hasfaces) in_list(ft,_polyhedra_[i][facevertices])]))
|
||||
) i
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
assert(len(indexlist)>0, "No polyhedra meet your specification")
|
||||
let(validindex = is_undef(index) || (index>=0 && index<len(indexlist)))
|
||||
assert(validindex, str(
|
||||
len(indexlist),
|
||||
" polyhedra meet specifications, so 'index' must be in [0,",
|
||||
len(indexlist)-1,
|
||||
"], but 'index' is ",
|
||||
index
|
||||
))
|
||||
let(
|
||||
entry = (
|
||||
name == "trapezohedron"? (
|
||||
trapezohedron(faces=faces, side=side, longside=longside, h=h, r=r)
|
||||
) : (
|
||||
_polyhedra_[!is_undef(index)?
|
||||
indexlist[index] :
|
||||
indexlist[0]]
|
||||
)
|
||||
),
|
||||
valid_facedown = is_bool(facedown) || in_list(facedown, entry[facevertices])
|
||||
)
|
||||
assert(valid_facedown,str("'facedown' set to ",facedown," but selected polygon only has faces with size(s) ",entry[facevertices]))
|
||||
let(
|
||||
scalefactor = (
|
||||
name=="trapezohedron" ? 1 : (
|
||||
argcount == 0? side :
|
||||
!is_undef(ir)? ir/entry[in_radius] :
|
||||
!is_undef(mr)? mr/entry[mid_radius] : or/entry[out_radius]
|
||||
) / entry[edgelen]
|
||||
),
|
||||
face_triangles = hull(entry[vertices]),
|
||||
faces_normals_vertices = stellate_faces(
|
||||
entry[edgelen], stellate, entry[vertices],
|
||||
entry[facevertices]==[3]?
|
||||
[face_triangles, [for(face=face_triangles) _facenormal(entry[vertices],face)]] :
|
||||
_full_faces(entry[vertices], face_triangles)
|
||||
),
|
||||
faces = faces_normals_vertices[0],
|
||||
faces_vertex_count = [for(face=faces) len(face)],
|
||||
facedown = facedown == true ? (stellate==false? entry[facevertices][0] : 3) : facedown,
|
||||
down_direction = facedown == false? [0,0,-1] :
|
||||
faces_normals_vertices[1][search(facedown, faces_vertex_count)[0]],
|
||||
scaled_points = scalefactor * rot(p=faces_normals_vertices[2], from=down_direction, to=[0,0,-1]),
|
||||
bounds = pointlist_bounds(scaled_points),
|
||||
boundtable = [bounds[0], [0,0,0], bounds[1]],
|
||||
translation = [for(i=[0:2]) -boundtable[1+anchor[i]][i]],
|
||||
face_normals = rot(p=faces_normals_vertices[1], from=down_direction, to=[0,0,-1]),
|
||||
side_length = scalefactor * entry[edgelen]
|
||||
)
|
||||
info == "fullentry" ? [
|
||||
scaled_points,
|
||||
translation,
|
||||
stellate ? faces : face_triangles,
|
||||
faces,
|
||||
face_normals,
|
||||
side_length*entry[in_radius]
|
||||
] :
|
||||
info == "vnf" ? [move(translation,p=scaled_points), stellate ? faces : face_triangles] :
|
||||
info == "vertices" ? move(translation,p=scaled_points) :
|
||||
info == "faces" ? faces :
|
||||
info == "face normals" ? face_normals :
|
||||
info == "in_radius" ? side_length * entry[in_radius] :
|
||||
info == "mid_radius" ? side_length * entry[mid_radius] :
|
||||
info == "out_radius" ? side_length * entry[out_radius] :
|
||||
info == "index set" ? indexlist :
|
||||
info == "face vertices" ? (stellate==false? entry[facevertices] : [3]) :
|
||||
info == "edge length" ? scalefactor * entry[edgelen] :
|
||||
info == "center" ? translation :
|
||||
info == "type" ? entry[class] :
|
||||
info == "name" ? entry[pname] :
|
||||
echo_warning(str("Unknown info type '",info,"' requested"));
|
||||
|
||||
|
||||
|
||||
@@ -718,68 +718,68 @@ function regular_polyhedron_info(
|
||||
/// either cross product or just rotate to
|
||||
///
|
||||
function stellate_faces(scalefactor,stellate,vertices,faces_normals) =
|
||||
(stellate == false || stellate == 0)? concat(faces_normals,[vertices]) :
|
||||
let(
|
||||
faces = [for(face=faces_normals[0]) select(face,hull(select(vertices,face)))],
|
||||
direction = [for(i=[0:1:len(faces)-1]) _facenormal(vertices, faces[i])*faces_normals[1][i]>0 ? 1 : -1],
|
||||
maxvertex = len(vertices),
|
||||
newpts = [for(i=[0:1:len(faces)-1]) mean(select(vertices,faces[i]))+stellate*scalefactor*faces_normals[1][i]],
|
||||
newfaces = [for(i=[0:1:len(faces)-1], j=[0:len(faces[i])-1]) concat([i+maxvertex],select(faces[i], [j, j+direction[i]]))],
|
||||
allpts = concat(vertices, newpts),
|
||||
normals = [for(face=newfaces) _facenormal(allpts,face)]
|
||||
) [newfaces, normals, allpts];
|
||||
(stellate == false || stellate == 0)? concat(faces_normals,[vertices]) :
|
||||
let(
|
||||
faces = [for(face=faces_normals[0]) select(face,hull(select(vertices,face)))],
|
||||
direction = [for(i=[0:1:len(faces)-1]) _facenormal(vertices, faces[i])*faces_normals[1][i]>0 ? 1 : -1],
|
||||
maxvertex = len(vertices),
|
||||
newpts = [for(i=[0:1:len(faces)-1]) mean(select(vertices,faces[i]))+stellate*scalefactor*faces_normals[1][i]],
|
||||
newfaces = [for(i=[0:1:len(faces)-1], j=[0:len(faces[i])-1]) concat([i+maxvertex],select(faces[i], [j, j+direction[i]]))],
|
||||
allpts = concat(vertices, newpts),
|
||||
normals = [for(face=newfaces) _facenormal(allpts,face)]
|
||||
) [newfaces, normals, allpts];
|
||||
|
||||
|
||||
function trapezohedron(faces, r, side, longside, h) =
|
||||
assert(faces%2==0, "Number of faces must be even")
|
||||
let(
|
||||
N = faces/2,
|
||||
parmcount = num_defined([r,side,longside,h])
|
||||
)
|
||||
assert(parmcount==2,"Must define exactly two of 'r', 'side', 'longside', and 'height'")
|
||||
let(
|
||||
separation = (
|
||||
!is_undef(h) ? 2*h*sqr(tan(90/N)) :
|
||||
(!is_undef(r) && !is_undef(side))? sqrt(side*side+2*r*r*(cos(180/N)-1)) :
|
||||
(!is_undef(r) && !is_undef(longside))? 2 * sqrt(sqr(longside)-sqr(r)) / (1-sqr(tan(90/N))) * sqr(tan(90/N)) :
|
||||
2*sqr(sin(90/N))*sqrt((sqr(side) + 2*sqr(longside)*(cos(180/N)-1)) / (cos(180/N)-1) / (cos(180/N)+cos(360/N)))
|
||||
)
|
||||
)
|
||||
assert(separation==separation, "Impossible trapezohedron specification")
|
||||
let(
|
||||
h = !is_undef(h) ? h : 0.5*separation / sqr(tan(90/N)),
|
||||
r = (
|
||||
!is_undef(r) ? r :
|
||||
!is_undef(side) ? sqrt((sqr(separation) - sqr(side))/2/(cos(180/N)-1)) :
|
||||
sqrt(sqr(longside) - sqr(h-separation/2))
|
||||
),
|
||||
top = [for(i=[0:1:N-1]) [r*cos(360/N*i), r*sin(360/N*i),separation/2]],
|
||||
bot = [for(i=[0:1:N-1]) [r*cos(180/N+360/N*i), r*sin(180/N+360/N*i),-separation/2]],
|
||||
vertices = concat([[0,0,h],[0,0,-h]],top,bot)
|
||||
) [
|
||||
"trapezohedron", "trapezohedron", faces, [4],
|
||||
!is_undef(side)? side : sqrt(sqr(separation)-2*r*(cos(180/N)-1)), // actual side length
|
||||
h*r/sqrt(r*r+sqr(h+separation/2)), // in_radius
|
||||
h*r/sqrt(r*r+sqr(h-separation/2)), // mid_radius
|
||||
max(h,sqrt(r*r+sqr(separation/2))), // out_radius
|
||||
undef, // volume
|
||||
vertices
|
||||
];
|
||||
assert(faces%2==0, "Number of faces must be even")
|
||||
let(
|
||||
N = faces/2,
|
||||
parmcount = num_defined([r,side,longside,h])
|
||||
)
|
||||
assert(parmcount==2,"Must define exactly two of 'r', 'side', 'longside', and 'height'")
|
||||
let(
|
||||
separation = (
|
||||
!is_undef(h) ? 2*h*sqr(tan(90/N)) :
|
||||
(!is_undef(r) && !is_undef(side))? sqrt(side*side+2*r*r*(cos(180/N)-1)) :
|
||||
(!is_undef(r) && !is_undef(longside))? 2 * sqrt(sqr(longside)-sqr(r)) / (1-sqr(tan(90/N))) * sqr(tan(90/N)) :
|
||||
2*sqr(sin(90/N))*sqrt((sqr(side) + 2*sqr(longside)*(cos(180/N)-1)) / (cos(180/N)-1) / (cos(180/N)+cos(360/N)))
|
||||
)
|
||||
)
|
||||
assert(separation==separation, "Impossible trapezohedron specification")
|
||||
let(
|
||||
h = !is_undef(h) ? h : 0.5*separation / sqr(tan(90/N)),
|
||||
r = (
|
||||
!is_undef(r) ? r :
|
||||
!is_undef(side) ? sqrt((sqr(separation) - sqr(side))/2/(cos(180/N)-1)) :
|
||||
sqrt(sqr(longside) - sqr(h-separation/2))
|
||||
),
|
||||
top = [for(i=[0:1:N-1]) [r*cos(360/N*i), r*sin(360/N*i),separation/2]],
|
||||
bot = [for(i=[0:1:N-1]) [r*cos(180/N+360/N*i), r*sin(180/N+360/N*i),-separation/2]],
|
||||
vertices = concat([[0,0,h],[0,0,-h]],top,bot)
|
||||
) [
|
||||
"trapezohedron", "trapezohedron", faces, [4],
|
||||
!is_undef(side)? side : sqrt(sqr(separation)-2*r*(cos(180/N)-1)), // actual side length
|
||||
h*r/sqrt(r*r+sqr(h+separation/2)), // in_radius
|
||||
h*r/sqrt(r*r+sqr(h-separation/2)), // mid_radius
|
||||
max(h,sqrt(r*r+sqr(separation/2))), // out_radius
|
||||
undef, // volume
|
||||
vertices
|
||||
];
|
||||
|
||||
|
||||
function _facenormal(pts, face) = unit(cross(pts[face[2]]-pts[face[0]], pts[face[1]]-pts[face[0]]));
|
||||
|
||||
// hull() function returns triangulated faces. This function identifies the vertices that belong to each face
|
||||
// by grouping together the face triangles that share normal vectors. The output gives the face polygon
|
||||
// hull() function returns triangulated faces. This function identifies the vertices that belong to each face
|
||||
// by grouping together the face triangles that share normal vectors. The output gives the face polygon
|
||||
// point indices in arbitrary order (not usable as input to a polygon call) and a normal vector.
|
||||
|
||||
function _full_faces(pts,faces) =
|
||||
let(
|
||||
normals = [for(face=faces) quant(_facenormal(pts,face),1e-12)],
|
||||
groups = _unique_groups(normals),
|
||||
faces = [for(entry=groups) unique(flatten(select(faces, entry)))],
|
||||
facenormals = [for(entry=groups) normals[entry[0]]]
|
||||
) [faces, facenormals];
|
||||
let(
|
||||
normals = [for(face=faces) quant(_facenormal(pts,face),1e-12)],
|
||||
groups = _unique_groups(normals),
|
||||
faces = [for(entry=groups) unique(flatten(select(faces, entry)))],
|
||||
facenormals = [for(entry=groups) normals[entry[0]]]
|
||||
) [faces, facenormals];
|
||||
|
||||
|
||||
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||
|
Reference in New Issue
Block a user