Polyhedra
Introduction
In elementary geometry a polyhedron (plural polyhedra or polyhedrons) is a geometric solid in three dimensions with flat faces and straight edges.A polyhedron is made up of a finite number of polygonal faces which are parts of planes; the faces meet in pairs along edges which are straight-line segments, and the edges meet in points called vertices. Cubes, prisms and pyramids are examples of polyhedra. The polyhedron surrounds a bounded volume in three-dimensional space; sometimes this interior volume is considered to be part of the polyhedron, sometimes only the surface is considered, and occasionally only the skeleton of edges.
Many polyhedra are symmetrical. When a polyhedral name is given, such as icosidodecahedron, the most symmetrical geometry is almost always implied.
Some of the most common names in particular are often used with regular in front or implied because for each there are different types which have little in common except for having the same number of faces. The common polyhedra are the
- triangular pyramid or tetrahedron (4 triangles)
- the cube or hexahedron (6 squares)
- the octahedron (8 triangles)
- the dodecahedron (12 pentagons)
- the icosahedron (20 triangles)
Archimedean solids consist of two or three different shapes. A cuboctahedron, a truncated tetrahedron and a truncated octahedron are examples of Archimedean solids.
www.korthalsaltes.com is a fantastic resource for paper models.
Vertex Generator
Here is the openscad script to create the vertices:
//===================================== // This is public Domain Code // Contributed by: Sjoerd de Jong (@ssured) // June 2011 //===================================== /* This is a script to print vertex connectors for creating solid models Parameters for all platonic solids, archimedean solids, prisms and antiprisms are included It's also possible to model your own custom connectors, to build whatever you like You can even model a .stl file in real space, by printing all vertices... Have fun! see http://en.wikipedia.org/wiki/Uniform_polyhedron see http://en.wikipedia.org/wiki/Archimedean_solid see http://en.wikipedia.org/wiki/Platonic_solid */ // PARAMETERS YOU SHOULD CHANGE, all in mm diameter = 6; thickness = diameter/2; length = 2*diameter; // cylinder hole precision // based on http://hydraraptor.blogspot.com/2011/02/polyholes.html $fn = max(round(diameter*2),3); //For a polyhedron: //===================================================================== //supply the name: vertex(polyhedrondata[ snubcube ]); //For a prism / antiprism with n-face base, print 2n vertices (n>=2): //===================================================================== //vertex(prism(5)); //vertex(antiprism(2)); //For a n-sided polygon / dihedron, print n vertices //===================================================================== //vertex(polygon(5)); //vertex(dihedron(3)); //For a custom vertex, based on supplied vectors: //===================================================================== //determine number of edges coming in, supply vectors for all outgoing edges //vertex(custom3([1,1,1],[-1,1,1],[1,-1,1])); //vertex(custom4([1,1,5],[-1,1,5],[1,-1,5],[-1,-1,5])); //For a full custom //===================================================================== //module syntax: //module vertex([normal, offset, [vectors]]); // - normal: defines the direction perpendicular to the face of the vertex connector // when [0,0,0] is used, a normal from [offset]->[0,0,0] is used, also a hole is added in this direction // - offset: offset of the base for vectors, for ease of building a connector not centered at [0,0,0] // - [vectors]: vectors for all outgoing edges from this connector // ===================================================================== // SCAD MODELING STARTS FROM HERE // Constants m=0.0; radius = diameter / 2; // for convenience tau = (1 + sqrt(5)) / 2; // golden ratio, used a lot xi = (pow(17+3*sqrt(33),1/3)-pow(-17+3*sqrt(33),1/3)-1)/3; // used for snub cube xis = pow(tau/2+0.5*sqrt(tau-5/27),1/3)+pow(tau/2-0.5*sqrt(tau-5/27),1/3); // used for snub dodecahedron alpha = xis - 1/xis; // used for snub dodecahedron beta = xis*tau+tau*tau+tau/xis; // used for snub dodecahedron // Polyhederon definitions: // platonic solid tetrahedron = 0; // print 4 cube = 1; // print 8 octahedron = 2; // print 6 dodecahedron = 3; // print 20 icosahedron = 4; // print 12 // archimedean solids truncatedtetrahedron = 5; // print 12 cuboctahedron = 6; // print 12 truncatedcube = 7; // print 24 truncatedoctahedron = 8; // print 24 rhombicuboctahedron = 9; // print 24 truncatedcuboctahedron = 10; // print 48 snubcube = 11; // print 24 icosidodecahedron = 12; // print 30 truncateddodecahedron = 13; // print 60 truncatedicosahedron = 14; // print 60 rhombicosidodecahedron = 15; // print 60 truncatedicosidodecahedron = 16; // print 120 snubdodecahedron = 17; // print 60 polyhedrondata = [ [/*tetrahedron*/[0,0,0], [ 1 ,1, 1], [[1,-1,-1], [-1,1,-1], [-1,-1,1]] , 3, [3,3,3]], [/*cube*/[0,0,0], [-1,-1,-1], [[1,-1,-1], [-1,1,-1], [-1,-1,1]] , 3, [4,4,4]], [/*octahedron*/[0,0,0], [ 0, 0,-1], [[1,0,0],[0,1,0],[-1,0,0],[0,-1,0]], 4, [3,3,3,3]], [/*dodecahedron*/[0,0,0], [ 1, 1, 1], [[0,1/tau,tau],[1/tau,tau,0],[tau,0,1/tau]], 3, [5,5,5]], [/*icosahedron*/[0,0,0], [0,1,-tau], [[0,-1,-tau],[-tau,0,-1],[-1,tau,0],[1,tau,0],[tau,0,-1]], 5, [3,3,3,3,3]], [/*truncatedtetrahedron*/[0,0,0], [-3, -1, 1], [[-3, 1, -1],[-1,-3,1], [-1, -1, 3]], 3, [6,3,6]], [/*cuboctahedron*/[0,0,0], [1,0,-1], [[0,-1,-1],[0,1,-1],[1,1,0],[1,-1,0]], 4, [4,3,4,3]], [/*truncatedcube*/[0,0,0], [1,1,-sqrt(2)+1], [[1,1,sqrt(2)-1],[sqrt(2)-1,1,-1],[1,sqrt(2)-1,-1]], 3, [8,3,8]], [/*truncatedoctahedron*/[0,0,0], [0,1,-2], [[1,0,-2],[-1,0,-2],[0,2,-1]], 3, [4,6,6]], [/*rhombicuboctahedron*/[0,0,0], [1,-1,-1-sqrt(2)], [[-1,-1,-1-sqrt(2)],[1,1,-1-sqrt(2)],[1+sqrt(2),-1,-1],[1,-1-sqrt(2),-1]], 4, [4,4,3,4]], [/*truncatedcuboctahedron*/[0,0,0], [1+sqrt(2),1,-1-sqrt(8)], [[1+sqrt(2),-1,-1-sqrt(8)],[1,1+sqrt(2),-1-sqrt(8)],[1+sqrt(8),1,-1-sqrt(2)]], 3, [8,6,4]], [/*snubcube*/[0,0,0], [1,-xi,-1/xi], [[-xi,-1,-1/xi],[xi,1,-1/xi],[1/xi,xi,-1],[1/xi,-1,-xi],[xi,-1/xi,-1]], 5, [4,3,3,3,3]], [/*icosidodecahedron*/[0,0,0], [0,0,-tau], [[0.5,tau/2,-(1+tau)/2],[-0.5,tau/2,-(1+tau)/2],[-0.5,-tau/2,-(1+tau)/2],[0.5,-tau/2,-(1+tau)/2]], 4, [3,5,3,5]], [/*truncateddodecahedron*/[0,0,0], [0,1/tau,2+tau], [[0,-1/tau,2+tau],[1/tau,tau,2*tau],[-1/tau,tau,2*tau]], 3, [10,3,10]], [/*truncatedicosahedron*/[0,0,0], [0,1,3*tau], [[0,-1,3*tau],[-tau,2,1+2*tau],[tau,2,1+2*tau]], 3, [6,5,6]], [/*rhombicosidodecahedron*/[0,0,0], [1,-1,pow(tau,3)], [[-1,-1,pow(tau,3)],[1,1,pow(tau,3)],[tau*tau,-tau,2*tau],[0,-tau*tau,2+tau]], 4, [4,5,4,3]], [/*truncatedicosidodecahedron*/[0,0,0], [1/tau,1/tau,3+tau], [[-1/tau,1/tau,3+tau],[1/tau,-1/tau,3+tau],[2/tau,tau,2*tau+1]], 3, [4,10,6]], [/*snubdodecahedron*/[0,0,0], [2*alpha,-2,2*beta], [[-2*alpha,2,2*beta],[(alpha+beta/tau-tau),-(alpha*tau-beta+1/tau),alpha/tau+beta*tau+1],[(alpha+beta/tau+tau),-(-alpha*tau+beta+1/tau),alpha/tau+beta*tau-1],[-alpha+beta/tau-tau,-(alpha*tau+beta-1/tau),-alpha/tau+beta*tau+1],[-(alpha+beta/tau-tau),(alpha*tau-beta+1/tau),alpha/tau+beta*tau+1]], 5, [3,5,3,3,3]] ]; // Prism definitions function prismcoord(n,k,z) = [cos(k*360/n)/(2*sin(180/n)),sin(k*360/n)/(2*sin(180/n)),z]; function prism(n) = [[0,0,0],prismcoord(n,0,0.5),[prismcoord(n,0,-0.5),prismcoord(n,1,0.5),prismcoord(n,n-1,0.5)],3,[4,n,4]]; // Antiprism definitions function antiprismcoord(n,k) = [cos(k*180/n),sin(k*180/n),pow(-1,k)*sqrt(0.5*(cos(180/n)-cos(360/n)))]; function antiprism(n) = [[0,0,0],antiprismcoord(n,0),[antiprismcoord(n,1),antiprismcoord(n,2),antiprismcoord(n,2*n-2),antiprismcoord(n,2*n-1)],4,[3,n,3,3]]; // Polygon definition (dihedron) function dihedron(n) = [[0,0,0],prismcoord(n,0,0),[prismcoord(n,1,0),prismcoord(n,n-1,0)],2,[n,n]]; function polygon(n) = dihedron(n); // custom connector functions function custom3(v1,v2,v3) = [CenterOfGravity3(v1,v2,v3),[0,0,0],[v1,v2,v3]]; function custom4(v1,v2,v3,v4) = [CenterOfGravity4(v1,v2,v3,v4),[0,0,0],[v1,v2,v3,v4]]; function custom5(v1,v2,v3,v4,v5) = [CenterOfGravity5(v1,v2,v3,v4,v5),[0,0,0],[v1,v2,v3,v4,v5]]; function custom6(v1,v2,v3,v4,v5,v6) = [CenterOfGravity6(v1,v2,v3,v4,v5,v6),[0,0,0],[v1,v2,v3,v4,v5,v6]]; // TESTING // Assert all supplied angles and functions are correct // Done by computing internal angles, and comparing these to expected regular polygon angles function polyangle(n) = 180-360/n; module assert(params) { name = params[0]; origin = params[1]; endpoints = params[2]; numpoints = params[3]; expectedpolygons = params[4]; if (numpoints > 0){ // echo("Asserting",pindex,name); for (i = [0:numpoints-1]){ if(abs(VANG(VSUB(endpoints[i],origin),VSUB(endpoints[(i+1==numpoints)?0:i+1],origin))-polyangle(expectedpolygons[i]))>0.01) { echo("FAIL:",name," i ",i," poly ",expectedpolygons[i]," exp angle ",polyangle(expectedpolygons[i])," - found:",VANG(VSUB(endpoints[i],origin),VSUB(endpoints[(i+1==numpoints)?0:i+1],origin))); } } } } for (assertionindex = [0:snubdodecahedron]){ assert(polyhedrondata[assertionindex]); if (assertionindex > 1){ assert(prism(assertionindex)); assert(antiprism(assertionindex)); assert(dihedron(assertionindex)); } } // VECTOR MATH FUNCTIONS, from http://www.thingiverse.com/thing:9447 // Made by William A Adams function VSUM(v1, v2) = [v1[0]+v2[0], v1[1]+v2[1], v1[2]+v2[2]]; function VSUB(v1, v2) = [v1[0]-v2[0], v1[1]-v2[1], v1[2]-v2[2]]; function VMULT(v1, v2) = [v1[0]*v2[0], v1[1]*v2[1], v1[2]*v2[2]]; // Magnitude of a vector // Gives the Euclidean norm function VLENSQR(v) = (v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); function VLEN(v) = sqrt(VLENSQR(v)); function VMAG(v) = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); // Returns the unit vector associated with a vector function VUNIT(v) = v/VMAG(v); function VNORM(v) = v/VMAG(v); // The scalar, or 'dot' product // law of cosines // if VDOT(v1,v2) == 0, they are perpendicular function SPROD(v1,v2) = v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]; function VDOT(v1v2) = SPROD(v1v2[0], v1v2[1]); // The vector, or Cross product // Given an array that contains two vectors function VPROD(vs) = [ (vs[0][1]*vs[1][2])-(vs[1][1]*vs[0][2]), (vs[0][2]*vs[1][0])-(vs[1][2]*vs[0][0]), (vs[0][0]*vs[1][1])-(vs[1][0]*vs[0][1])]; function VCROSS(v1, v2) = VPROD([v1,v2]); // Calculate the angle between two vectors function VANG(v1, v2) = acos(VDOT([v1,v2])/(VMAG(v1)*VMAG(v2))); // Calculate the signed angle between two vectors, seen from normal n // source: http://tomyeah.com/signed-angle-between-two-vectors3d-in-cc/ function VSANG(v1, v2, n) = atan2(SPROD(VNORM(n),VCROSS(VNORM(v1),VNORM(v2))),SPROD(VNORM(v1),VNORM(v2))); // returns a semi random vector perpendicular to the original vector function VPERP(v) = [v[1], -v[0], 0]; // inverts a vector function VINV(v) = [-v[0], -v[1], -v[2]]; function AvgThree(v1,v2,v3) = (v1+v2+v3)/3; function AvgFour(v1,v2,v3,v4) = (v1+v2+v3+v4)/4; function AvgFive(v1,v2,v3,v4,v5) = (v1+v2+v3+v4+v5)/5; function AvgSix(v1,v2,v3,v4,v5,v6) = (v1+v2+v3+v4+v5+v6)/6; function CenterOfGravity3(p0, p1, p2) = [ AvgThree(p0[0], p1[0], p2[0]), AvgThree(p0[1], p1[1], p2[1]), AvgThree(p0[2], p1[2], p2[2])]; function CenterOfGravity4(p0, p1, p2, p3) = [ AvgFour(p0[0], p1[0], p2[0], p3[0]), AvgFour(p0[1], p1[1], p2[1], p3[1]), AvgFour(p0[2], p1[2], p2[2], p3[2])]; function CenterOfGravity5(p0, p1, p2, p3, p4) = [ AvgFive(p0[0], p1[0], p2[0], p3[0], p4[0]), AvgFive(p0[1], p1[1], p2[1], p3[1], p4[1]), AvgFive(p0[2], p1[2], p2[2], p3[2], p4[2])]; function CenterOfGravity6(p0, p1, p2, p3, p4, p5) = [ AvgSix(p0[0], p1[0], p2[0], p3[0], p4[0], p5[0]), AvgSix(p0[1], p1[1], p2[1], p3[1], p4[1], p5[0]), AvgSix(p0[2], p1[2], p2[2], p3[2], p4[2], p5[0])]; // FROM HERE THE ACTUAL RENDERING module vertex_edge_holder(angle) { difference() { // compensate for the previous rotation translate([0, -radius*cos(angle)-thickness*(sin(angle)+0.5), radius*sin(angle)+0*thickness*cos(angle)]) // rotate the edges rotate ([angle,0,0]) // make the cylinder ellpitical to compensate for wall thickness scale([1,(radius*cos(angle)+thickness)/(radius + thickness),1]) // work with double length elements, will be truncated translate([0,0,-1*length]){ difference() { union(){ cylinder(h = 2*length, r = radius + thickness); translate([-0.5*sqrt(2)*(radius+thickness),0,0]) cube([sqrt(2)*(radius+thickness),2*length,2*length]); } translate([(angle<45)?-0.5:-0.5*radius, -2*length-radius, length]) cube([(angle<45)?1:radius,2*length,2*length]); } } // remove all excess connector material translate([-2.5*length,m,-2.5*length]) cube(5*length); } } module vertex_edge(angle) { translate([0, -radius*cos(angle)-thickness*(sin(angle)+0.5), radius*sin(angle)+0*thickness*cos(angle)]) rotate ([angle,0,0]) cylinder(5*length, radius, radius); } module vertex(params) { normal = params[0]; origin = params[1]; endpoints = params[2]; // construct new coordinate system based on supplied normal or the origin location zdir = VMAG(normal) > 0 ? VNORM(normal) : VNORM(VINV(origin)); ydir = -VNORM(VCROSS(zdir, VSUB(endpoints[0],origin))); xdir = -VNORM(VCROSS(zdir, ydir)); // // uncomment for an example of the rotation // // rotation to put zdir on z axis // zrotate = [(zdir[2]==0 && zdir[1]==0) ? 0 : atan2(zdir[1],zdir[2]), acos(zdir[0])-90, 0]; // rotate(zrotate) // { // cyl([0,0,0],xdir,40,0.5); // cyl([0,0,0],ydir,40,0.5); // cyl([0,0,0],zdir,40,0.5); // } //dimensions of the connector are based upon the first edge angle = VANG(zdir,VSUB(endpoints[0],origin)); height = cos(angle)*(length + 0*thickness) + 2 * radius * sin(angle); //adjust angles for easy printing mirror((angle>45)?[0,0,1]:[0,0,0]) translate((angle>45)?[0,0,-height]:[0,0,0]) //create the vertex intersection() { difference() { union(){ for (endpoint = endpoints) { rotate([0,0,VSANG(xdir,VSUB(endpoint,origin),zdir)+90]) vertex_edge_holder(VANG(zdir,VSUB(endpoint,origin))); } if (VMAG(normal) == 0) { cylinder(5*length,radius+thickness,radius+thickness,true); } } for (endpoint = endpoints) { rotate([0,0,VSANG(xdir,VSUB(endpoint,origin),zdir)+90]) vertex_edge(VANG(zdir,VSUB(endpoint,origin))); } if (VMAG(normal) == 0) { cylinder(5*length,radius,radius,true); } } //remove excess material cylinder(height, 5*length, 5*length); } }
Tetra-octahedral bars & nodes grid structure
Cutaway, Hollow Elements
Polyhedron Facets
Snap-together polyhedron verticies
Face-centered Cubic Voroni Tetrahedron
Stellated octahedron
A Relationship between the Cube, Tetrahedron, Octahedron, and Rhombic Dodecahedron from the Wolfram Demonstrations Project by Sándor Kabai