Skip to content

Instantly share code, notes, and snippets.

@Taneb
Last active October 25, 2022 17:30
Show Gist options
  • Save Taneb/69a7a026db53f08b5895032d4de75f2d to your computer and use it in GitHub Desktop.
Save Taneb/69a7a026db53f08b5895032d4de75f2d to your computer and use it in GitHub Desktop.
Duals of polyhedra in OpenSCAD
// the golden ratio
phi = (sqrt(5) + 1) / 2;
// the points of a regular dodecahedron, oriented "somehow"
dodecahedron_points =
[ [ 1 , 1 , 1 ] // 0
, [ 1 , 1 , -1 ]
, [ 1 , -1 , 1 ]
, [ 1 , -1 , -1 ]
, [ -1 , 1 , 1 ] // 4
, [ -1 , 1 , -1 ]
, [ -1 , -1 , 1 ]
, [ -1 , -1 , -1 ]
, [ 0 , phi , 1 / phi ] // 8
, [ 0 , phi , -1 / phi ]
, [ 0 , -phi , 1 / phi ]
, [ 0 , -phi , -1 / phi ]
, [ 1 / phi , 0 , phi ] // 12
, [ -1 / phi , 0 , phi ]
, [ 1 / phi , 0 , -phi ]
, [ -1 / phi , 0 , -phi ]
, [ phi , 1 / phi , 0 ] // 16
, [ phi , -1 / phi , 0 ]
, [ -phi , 1 / phi , 0 ]
, [ -phi , -1 / phi , 0 ]
];
for (i = dodecahedron_points)
assert(norm(i) == sqrt(3));
// the faces of a dodecahedron
dodecahedron_faces =
[ [ 0 , 12 , 13 , 4 , 8 ]
, [ 0 , 8 , 9 , 1 , 16 ]
, [ 0 , 16 , 17 , 2 , 12 ]
, [ 10 , 6 , 13 , 12 , 2 ]
, [ 10 , 2 , 17 , 3 , 11 ]
, [ 10 , 11 , 7 , 19 , 6 ]
, [ 15 , 7 , 11 , 3 , 14 ]
, [ 15 , 14 , 1 , 9 , 5 ]
, [ 15 , 5 , 18 , 19 , 7 ]
, [ 16 , 1 , 14 , 3 , 17 ]
, [ 13 , 6 , 19 , 18 , 4 ]
, [ 4 , 18 , 5 , 9 , 8 ]
];
// polyhedron(dodecahedron_points, dodecahedron_faces, 1);
function sum(list, i = 0, total = 0) =
len(list) == i ? total : sum(list, i+1, total + list[i]);
function dual_polyhedron_points(points, faces) =
[ for (face = faces)
sum([for (i = face) points[i]], total = [0,0,0])/len(face)
];
function index_of(needle, haystack, i = 0) = i == len(haystack) ? undef : haystack[i] == needle ? i : index_of(needle, haystack, i + 1);
function build_dual_polygon_face(info, end, next) = end == next ? [info[0][0]] :
let (i = index_of(next, [ for (t = info) t[2] ]))
concat([info[i][0]], build_dual_polygon_face(info, end, info[i][1]));
// NOTE it's really important that all the faces are the right way round!!!
function dual_polyhedron_faces(points, faces) =
[ for (i = [0:len(points) - 1])
let (
// each elem is face index containing vertex, ccw, cw
info = [
for (j = [0:len(faces) - 1])
let (face = faces[j], k = index_of(i, face))
if (k != undef)
[ j , face[(k + len(face) - 1) % len(face)], face[(k + 1) % len(face)] ]
]
)
build_dual_polygon_face(info, info[0][2], info[0][1])
];
echo(dual_polyhedron_faces(dodecahedron_points, dodecahedron_faces));
function normalize_points(points) = [ for (point = points) point/norm(point) ];
polyhedron(normalize_points(dodecahedron_points), dodecahedron_faces);
translate([2,0,0])
polyhedron(
normalize_points(dual_polyhedron_points(dodecahedron_points, dodecahedron_faces)),
dual_polyhedron_faces(dodecahedron_points, dodecahedron_faces)
);
translate([4,0,0])
polyhedron(
normalize_points(
dual_polyhedron_points(
dual_polyhedron_points(
dodecahedron_points,
dodecahedron_faces
),
dual_polyhedron_faces(
dodecahedron_points,
dodecahedron_faces
)
)
),
dual_polyhedron_faces(
dual_polyhedron_points(
dodecahedron_points,
dodecahedron_faces
),
dual_polyhedron_faces(
dodecahedron_points,
dodecahedron_faces
)
)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment