c# - Spiked vertexes on generated Icosphere -
i've been working on program generate icosphere. (a sphere evenly distributed vertexes across face, used terrain deformation)
i have pretty done, sphere generated, subdivided , drawn. problem running somewhere in code, of vertices (the twelve starting vertexes, believe) being set twice radius, rather radius.
here 3 images, showing icosphere @ zero, 1 , 2 refinement passes:
http://i41.photobucket.com/albums/e262/cstgirllover/cho/ico0refinement.png
http://i41.photobucket.com/albums/e262/cstgirllover/cho/ico1refinement.png
http://i41.photobucket.com/albums/e262/cstgirllover/cho/ico2refinement.png
and here code generates icosahedron, , breaks down icosphere:
using system; using system.collections.generic; using system.linq; using system.text; using microsoft.xna.framework; using microsoft.xna.framework.graphics; namespace icosahedron_test { class icosahedron { int radius; // radius of planet int refinement; // number of times refine traingles int faces = 20; vector3[] basepositions; // vertex points 3 defining rectangles trixyz[] vertices; // vertex points triangles define spherical surface public icosahedron(int tradius, int trefinement, trixyz[] tvertices) { radius = tradius; refinement = trefinement; vertices = tvertices; } public trixyz[] initializearray() { double t = radius*((1+math.sqrt(5))/2); vector3[] basepositions = { //first rectangle new vector3(-radius, (float)t, 0), new vector3(radius, (float)t, 0), new vector3(-radius, (float)-t, 0), new vector3(radius, (float)-t, 0), //seconds rectangle new vector3(0, -radius, (float)t), new vector3(0, radius, (float)t), new vector3(0, -radius, (float)-t), new vector3(0, radius, (float)-t), //third rectangle new vector3((float)t, 0, -radius), new vector3((float)t, 0, radius), new vector3((float)-t, 0, -radius), new vector3((float)-t, 0, radius) }; trixyz[] vertices = { new trixyz(basepositions[5], basepositions[11], basepositions[0], 1), new trixyz(basepositions[1], basepositions[5], basepositions[0], 1), new trixyz(basepositions[7], basepositions[1], basepositions[0], 1), new trixyz(basepositions[10], basepositions[7], basepositions[0], 1), new trixyz(basepositions[11], basepositions[10], basepositions[0], 1), new trixyz(basepositions[9], basepositions[5], basepositions[1], 1), new trixyz(basepositions[4], basepositions[11], basepositions[5], 1), new trixyz(basepositions[2], basepositions[10], basepositions[11], 1), new trixyz(basepositions[6], basepositions[7], basepositions[10], 1), new trixyz(basepositions[8], basepositions[1], basepositions[7], 1), new trixyz(basepositions[4], basepositions[9], basepositions[3], 1), new trixyz(basepositions[2], basepositions[4], basepositions[3], 1), new trixyz(basepositions[6], basepositions[2], basepositions[3], 1), new trixyz(basepositions[8], basepositions[6], basepositions[3], 1), new trixyz(basepositions[9], basepositions[8], basepositions[3], 1), new trixyz(basepositions[5], basepositions[9], basepositions[4], 1), new trixyz(basepositions[11], basepositions[4], basepositions[2], 1), new trixyz(basepositions[10], basepositions[2], basepositions[6], 1), new trixyz(basepositions[7], basepositions[6], basepositions[8], 1), new trixyz(basepositions[1], basepositions[8], basepositions[9], 1), }; return vertices; } public trixyz[] refine(trixyz[] rvertices, int rrefinement, float radius) { trixyz[] tvertices; // temp list of triangles vector3 vertex1; // position of first vertex of base triangle vector3 vertex2; // position of second vertex of base triangle vector3 vertex3; // position of third vertex of base triangle int tdepth; // depth of current triangle //int listpos = 0; // base list position integer int nlistpos = 0; // new list position integer int crefine = 0; // current refinement iteration while(crefine < rrefinement) // loop until icosphere has been refined inputted number of times { tvertices = new trixyz[20 + (4*rvertices.length)]; // make temporary list empty, , long enough original 20 triangles, plus 4 per triangle each level of refinement. (int listpos = 0; listpos < rvertices.length; listpos++ ) // loop through every triangle in list { trixyz ctriangle = rvertices[listpos]; tdepth = ctriangle.getdepth; vertex1 = ctriangle.getvertex1; // point 0 vertex2 = ctriangle.getvertex2; // point 1 vertex3 = ctriangle.getvertex3; // point 2 if (tdepth == crefine + 1) // if depth of triangle in list equals current refinement iteration; // depth 1 first refinement pass, depth 2 second, etc; subdivide triangle // prevents unnecessarily re-refining old triangles { trixyz[] parts = new trixyz[5]; parts = ctriangle.subdivide(radius); tvertices[nlistpos] = parts[0]; // put original larger triangle @ front if list tvertices[nlistpos + 1] = parts[1]; // first subdivided triangle tvertices[nlistpos + 2] = parts[2]; // second subdivided triangle tvertices[nlistpos + 3] = parts[3]; // third subdivided triangle tvertices[nlistpos + 4] = parts[4]; // fourth subdivided triangle nlistpos = nlistpos + 5; // move forward in new triangle list next set of triangles doesn't overwrite set. } else if (tdepth < crefine + 1) // ifthe triangle's depth less current refinement iteration (depth 1 on refinement 2) add current triangle new list @ nlistpos { tvertices[nlistpos] = new trixyz(vertex1, vertex2, vertex3, tdepth); nlistpos++; } // shouldn't possible tdepth greater crefine } // end loop: either move next triangel in original list, or move on next level of refinement rvertices = tvertices; // replace old list new one, next time // runs through refinement process, refine new // traingles crefine++; // increase refinement interation variable either refine next set of triangles, or exit refinement loop. nlistpos = 0; // reset new list position integer overwrites exiting data } // end while loop: either move on next refinement set, or exit loop vertices = rvertices; // make sure class=level vertices return rvertices; } // end refinement class public int length { { return vertices.length; } private set { } } public vertexpositioncolor[] buildlist(trixyz[] tlist, int tdepth) { vertexpositioncolor[] finallist = new vertexpositioncolor[tlist.length*3]; // final list returned drawing int listpos = 0; // current position in final list (where vector 3 being applied) vector3 pos1; // vertex 1 position of trixyz triangle vector3 pos2; // vertex 2 position of trixyz triangle vector3 pos3; // vertex 3 position of trixyz triangle int depth; for(int ctri = 0; ctri<tlist.length; ctri+=1) // loop through trixyz list , vertexes it, apply them final draw list { pos1 = tlist[ctri].getvertex1; pos2 = tlist[ctri].getvertex2; pos3 = tlist[ctri].getvertex3; depth = tlist[ctri].getdepth; if (depth == tdepth) { finallist[listpos] = new vertexpositioncolor(pos1, color.blue); finallist[listpos + 1] = new vertexpositioncolor(pos2, color.red); finallist[listpos + 2] = new vertexpositioncolor(pos3, color.green); listpos = listpos + 3; } } return finallist; } } }
and here trixyz class, holds triangle data:
using system; using system.collections.generic; using system.linq; using system.text; using microsoft.xna.framework; using microsoft.xna.framework.graphics; namespace icosahedron_test { class trixyz { vector3 vertex1; vector3 vertex2; vector3 vertex3; int depth; float material1; // float first material value amount (in %) deals blending float material2; // float second material value amount (in %) deals blending public trixyz(vector3 pos1, vector3 pos2, vector3 pos3, int tdepth) { vertex1 = pos1; vertex2 = pos2; vertex3 = pos3; depth = tdepth; } public trixyz(vector3 pos1, vector3 pos2, vector3 pos3, int tdepth, float tmaterial1, float tmaterial2) { vertex1 = pos1; vertex2 = pos2; vertex3 = pos3; depth = tdepth; material1 = tmaterial1; material2 = tmaterial2; } // public access triangle data, read-write public vector3 getvertex1 { { return vertex1; } set { vertex1 = value; } } public vector3 getvertex2 { { return vertex2; } set { vertex2 = value; } } public vector3 getvertex3 { { return vertex3; } set { vertex3 = value; } } public int getdepth { { return depth; } set { depth = value; } } public static vector3 midpoint(vector3 pos1, vector3 pos2, float radius) { vector3 midpoint; // returned midpoint between 2 inputted vectors float x; float y; float z; x = (pos1.x + pos2.x)/2; y = (pos1.y + pos2.y)/2; z = (pos1.z + pos2.z)/2; midpoint = new vector3(x, y, z); midpoint.normalize(); midpoint = midpoint * radius; return midpoint; } public trixyz[] subdivide(float radius) { vector3 r; // placeholder new vertex position, aligned planet sphere radius vector3 uv; // new vector position trixyz[] ntriangle = new trixyz[5]; // array of triangle values return vector3 mid1 = midpoint(vertex1, vertex2, radius); vector3 mid2 = midpoint(vertex2, vertex3, radius); vector3 mid3 = midpoint(vertex3, vertex1, radius); ntriangle[0] = new trixyz(vertex1, vertex2, vertex3, depth); // put original larger triangle @ front if list ntriangle[1] = new trixyz(vertex1, mid1, mid3, depth + 1); // first subdivided triangle ntriangle[2] = new trixyz(mid1, vertex2, mid2, depth + 1); // second subdivided triangle ntriangle[3] = new trixyz(mid3, mid2, vertex3, depth + 1); // third subdivided triangle ntriangle[4] = new trixyz(mid3, mid1, mid2, depth + 1); // fourth subdivided triangle return ntriangle; } } }
any appreciate. imagine it's simple, cannot seem find problem.
it's initial vectors. if memory serves (it's been while since i've dealt icosahedrons, etc.), use golden ratio create 1 , edge length of 2 (which you're doing). perhaps normalize vectors before multiplying radius? reason because vertices never updated in code, has initial values (unless of course missed something, possible).
Comments
Post a Comment