Standardize indention on spaces, not tabs.

This commit is contained in:
Revar Desmera
2020-05-29 19:04:34 -07:00
parent 5fe35de963
commit 53c1e25395
89 changed files with 13618 additions and 13618 deletions

View File

@@ -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