public static void AddArcVerts(List <Vertex3DColor> verts, Vector3 pos1, Vector3 pos2, float radius, Vector4 color) { // Project points onto sphere of given radius pos1.Normalize(); pos2.Normalize(); // Determine arc degree: double dot = Vector3.Dot(pos1, pos2); if (dot != 1) { double theta = Math.Acos(dot); pos2 *= radius; pos2 *= radius; double SineTheta = Math.Sin(theta); // Slerp = Sine(theta-angle)*pos1/Sine(theta) + Sine(angle)*pos2/Sine(theta) // angle: 0 -> theta // iterate along arc, generating points each 0.2 degrees for (double angle = 0.0f; angle <= theta; angle += Math.PI / 1800.0f) { Vector3 pAngle = (float)(Math.Sin(theta - angle) / SineTheta) * pos1 + (float)(Math.Sin(angle) / SineTheta) * pos2; Vertex3DColor vertex = new Vertex3DColor(pAngle, color); verts.Add(vertex); } } }
static public IGeometry CreateIcosphere(int subDivisions) { Vertex3DColor[] verts = new Vertex3DColor[12]; Vector4 color = new Vector4(0.2f, 0.2f, 1.0f, 1.0f); Vector4 color2 = new Vector4(1.0f, 0.2f, 1.0f, 1.0f); Vector4 color3 = new Vector4(0.2f, 1.0f, 1.0f, 1.0f); const float t = 1.61803398875f; // approximation of golden ratio verts[0] = new Vertex3DColor(Vector3.Normalize(new Vector3(-1, t, 0)), color2); // Subdivision generates Sierpinski triangle at pole verts[1] = new Vertex3DColor(Vector3.Normalize(new Vector3(1, t, 0)), color); verts[2] = new Vertex3DColor(Vector3.Normalize(new Vector3(-1, -t, 0)), color); verts[3] = new Vertex3DColor(Vector3.Normalize(new Vector3(1, -t, 0)), color3); // Subdivision generates Sierpinski triangle at other pole verts[4] = new Vertex3DColor(Vector3.Normalize(new Vector3(0, -1, t)), color); verts[5] = new Vertex3DColor(Vector3.Normalize(new Vector3(0, 1, t)), color); verts[6] = new Vertex3DColor(Vector3.Normalize(new Vector3(0, -1, -t)), color); verts[7] = new Vertex3DColor(Vector3.Normalize(new Vector3(0, 1, -t)), color); verts[8] = new Vertex3DColor(Vector3.Normalize(new Vector3(t, 0, -1)), color); verts[9] = new Vertex3DColor(Vector3.Normalize(new Vector3(t, 0, 1)), color); verts[10] = new Vertex3DColor(Vector3.Normalize(new Vector3(-t, 0, -1)), color); verts[11] = new Vertex3DColor(Vector3.Normalize(new Vector3(-t, 0, 1)), color); var mesh = new Mesh <Vertex3DColor>(verts); var indices = new List <uint>(); AddIndices(ref indices, 0, 1, 7); AddIndices(ref indices, 0, 5, 1); AddIndices(ref indices, 0, 11, 5); AddIndices(ref indices, 0, 10, 11); AddIndices(ref indices, 0, 7, 10); AddIndices(ref indices, 1, 5, 9); AddIndices(ref indices, 5, 4, 9); AddIndices(ref indices, 5, 11, 4); AddIndices(ref indices, 11, 2, 4); AddIndices(ref indices, 11, 10, 2); AddIndices(ref indices, 10, 6, 2); AddIndices(ref indices, 10, 7, 6); AddIndices(ref indices, 7, 8, 6); AddIndices(ref indices, 7, 1, 8); AddIndices(ref indices, 1, 9, 8); AddIndices(ref indices, 3, 4, 2); AddIndices(ref indices, 3, 2, 6); AddIndices(ref indices, 3, 6, 8); AddIndices(ref indices, 3, 8, 9); AddIndices(ref indices, 3, 9, 4); var geometry = new Geometry <Vertex3DColor>(mesh, indices.ToArray()); int vertCount = geometry.SubDivide(subDivisions); return(geometry); }