Stap 3: Geodetische bollen
Nu zullen we kijken naar hoe een bol onderverdelen in een bepaald aantal
driehoeken van ongeveer dezelfde vorm. De hier beschreven methode is
vaak gebruikt om te bouwen van veelhoekige benaderingen van bollen, zoals gedetailleerde
in deze tutorial OpenGL: http://www.opengl.org.ru/docs/pg/0208.html.
In ons geval, zal dit de stap van gebouw voor het genereren van de gaten die zal worden
transfrom onze regelmatige bal in een geodeome-achtige.
Eerst we met een regelmatige isocahedron , die twintig driehoekige gezichten beginnen heeft, en
de interessante eigenschap dat elk van de hoekpunten op een bol liggen.
Dan voor elke driehoek, we elk van de drie randen in het midden splitsen, die
geeft ons drie extra hoekpunten die we gebruiken om het onderverdelen van genoemde driehoek
in vier kleinere driehoeken. De drie hoekpunten worden vervolgens vertaald naar buiten
Zo liggen ze op het gebied van oppervlak.
Isocahedron OpenJSCAD-script
function main(){ var X = 0.525731112119133606; var Z = 0.850650808352039932; var radius = 20; var vdata = [ [-X, 0.0, Z], [ X, 0.0, Z ], [ -X, 0.0, -Z ], [ X, 0.0, -Z ], [ 0.0, Z, X ], [ 0.0, Z, -X ], [ 0.0, -Z, X ], [ 0.0, -Z, -X ], [ Z, X, 0.0 ], [ -Z, X, 0.0 ], [ Z, -X, 0.0 ], [ -Z, -X, 0.0 ] ]; // isocahedron vertex coordinates var tindices = [ [0, 4, 1], [ 0, 9, 4 ], [ 9, 5, 4 ], [ 4, 5, 8 ], [ 4, 8, 1 ], [ 8, 10, 1 ], [ 8, 3, 10 ], [ 5, 3, 8 ], [ 5, 2, 3 ], [ 2, 7, 3 ], [ 7, 10, 3 ], [ 7, 6, 10 ], [ 7, 11, 6 ], [ 11, 0, 6 ], [ 0, 1, 6 ], [ 6, 1, 10 ], [ 9, 0, 11 ], [ 9, 11, 2 ], [ 9, 2, 5 ], [ 7, 2, 11 ] ]; // isocahedron triangles return polyhedron({ points: vdata, triangles: tindices }).scale([radius, radius, radius]); }
Vervolgens schrijven we de Subdivisie fonction voor een eenheid bol benadering:
De subdvide-functie
/* fn subdivide(v1, v2, v3, addPolyCb, depth) * brief subdivides a triangle into 4 smaller ones * params v1, v2, v3 : triangle vertices * addPolyCb : callback for add polygon notification * depth : number of remaining subdivision iterations */ function subdivide(v1, v2, v3, addPolyCb, depth) { if(depth == 0) { addPolyCb(v1, v2, v3); return; } var v12 = v1.plus(v2).unit(); // middle of v1v2 edge projected on the unit sphere var v23 = v2.plus(v3).unit(); var v31 = v3.plus(v1).unit(); var newDepth = depth - 1; subdivide(v1, v12, v31, addPolyCb, newDepth); subdivide(v2, v23, v12, addPolyCb, newDepth); subdivide(v3, v31, v23, addPolyCb, newDepth); subdivide(v12, v23, v31, addPolyCb, newDepth); }
Het proces van de Subdivisie werkt recursief; vanaf de 20 isocahedron
gezichten, elke stap van de Subdivisie vermenigvuldigt het totale aantal gezichten met 4.
Een diepte van 1 genereert bijgevolg een veelvlak 80 gezichten.
We kunnen nu een gebied benadering genereren door het aanroepen van de functie onderverdelen
iteratief over de gezichten van de isocahedron als volgt:
80 gezichten geodetische bol script
function main() { var ballDiameter = 40; var ballRadius = ballDiameter/2.; var polygons = []; // list of polygons addPolyCb = function(v1, v2, v3) { polygons.push(new CSG.Polygon([ new CSG.Vertex(new CSG.Vector3D(v3.x,v3.y,v3.z)), new CSG.Vertex(new CSG.Vector3D(v2.x,v2.y,v2.z)), new CSG.Vertex(new CSG.Vector3D(v1.x,v1.y,v1.z)) ])); } createGeodesicSphere(addPolyCb, 1); var unitSphereApprox = CSG.fromPolygons(polygons); return unitSphereApprox.scale([ballRadius, ballRadius, ballRadius]); } // subdivides a unit isocahedron n=depth times and calls a callback for each created face function createGeodesicSphere(addPolyCb, depth) { var X = 0.525731112119133606; var Z = 0.850650808352039932; var vdata = [ [-X, 0.0, Z], [ X, 0.0, Z ], [ -X, 0.0, -Z ], [ X, 0.0, -Z ], [ 0.0, Z, X ], [ 0.0, Z, -X ], [ 0.0, -Z, X ], [ 0.0, -Z, -X ], [ Z, X, 0.0 ], [ -Z, X, 0.0 ], [ Z, -X, 0.0 ], [ -Z, -X, 0.0 ] ]; var tindices = [ [0, 4, 1], [ 0, 9, 4 ], [ 9, 5, 4 ], [ 4, 5, 8 ], [ 4, 8, 1 ], [ 8, 10, 1 ], [ 8, 3, 10 ], [ 5, 3, 8 ], [ 5, 2, 3 ], [ 2, 7, 3 ], [ 7, 10, 3 ], [ 7, 6, 10 ], [ 7, 11, 6 ], [ 11, 0, 6 ], [ 0, 1, 6 ], [ 6, 1, 10 ], [ 9, 0, 11 ], [ 9, 11, 2 ], [ 9, 2, 5 ], [ 7, 2, 11 ] ]; // iterate over isocahedron triangles for(var i = 0; i < 20; i++) subdivide( new CSG.Vector3D(vdata[tindices[i][0]]), new CSG.Vector3D(vdata[tindices[i][1]]), new CSG.Vector3D(vdata[tindices[i][2]]), addPolyCb, depth); }
Dit script wilt uitvoeren, kopieer en plak de code in uw favoriete code-editor en sla
het bestand met de extensie .jscad. Vervolgens gewoon slepen en neerzetten het bestand in de recangular
gebied in de linkerbenedenhoek van uw browservenster OpenJSCAD.