// Make a torus without texture coordinates. public static void AddTorus(this MeshGeometry3D mesh, Point3D center, double R, double r, int numTheta, int numPhi, bool smooth = false) { // Make a point dictionary if needed. Dictionary <Point3D, int> pointDict = null; if (smooth) { pointDict = new Dictionary <Point3D, int>(); } // Generate the points. double dtheta = 2 * Math.PI / numTheta; double dphi = 2 * Math.PI / numPhi; double theta = 0; for (int t = 0; t < numTheta; t++) { double phi = 0; for (int p = 0; p < numPhi; p++) { // Find this piece's points. Point3D[] points = { G3.TorusPoint(center, R, r, theta + dtheta, phi), G3.TorusPoint(center, R, r, theta + dtheta, phi + dphi), G3.TorusPoint(center, R, r, theta, phi + dphi), G3.TorusPoint(center, R, r, theta, phi), }; // Make the polygon. mesh.AddPolygon(pointDict, points); phi += dphi; } theta += dtheta; } }
// Add a textured torus. public static void AddTexturedTorus(this MeshGeometry3D mesh, Point3D center, double R, double r, int numTheta, int numPhi, bool smooth = false) { double dtheta = 2 * Math.PI / numTheta; double dphi = 2 * Math.PI / numPhi; double theta = Math.PI; // Puts the texture's top/bottom on the inside. for (int t = 0; t < numTheta; t++) { double phi = 0; for (int p = 0; p < numPhi; p++) { // Find this piece's points. Point3D point1 = G3.TorusPoint(center, R, r, theta, phi).Round(); Point3D point2 = G3.TorusPoint(center, R, r, theta + dtheta, phi).Round(); Point3D point3 = G3.TorusPoint(center, R, r, theta + dtheta, phi + dphi).Round(); Point3D point4 = G3.TorusPoint(center, R, r, theta, phi + dphi).Round(); // Find this piece's normals. Vector3D normal1 = G3.TorusNormal(D3.Origin, R, r, theta, phi); Vector3D normal2 = G3.TorusNormal(D3.Origin, R, r, theta + dtheta, phi); Vector3D normal3 = G3.TorusNormal(D3.Origin, R, r, theta + dtheta, phi + dphi); Vector3D normal4 = G3.TorusNormal(D3.Origin, R, r, theta, phi + dphi); // Find this piece's texture coordinates. Point coords1 = new Point(1 - (double)p / numPhi, 1 - (double)t / numTheta); Point coords2 = new Point(1 - (double)p / numPhi, 1 - (double)(t + 1) / numTheta); Point coords3 = new Point(1 - (double)(p + 1) / numPhi, 1 - (double)(t + 1) / numTheta); Point coords4 = new Point(1 - (double)(p + 1) / numPhi, 1 - (double)t / numTheta); // Make the first triangle. int index = mesh.Positions.Count; mesh.Positions.Add(point1); if (smooth) { mesh.Normals.Add(normal1); } mesh.TextureCoordinates.Add(coords1); mesh.Positions.Add(point2); if (smooth) { mesh.Normals.Add(normal2); } mesh.TextureCoordinates.Add(coords2); mesh.Positions.Add(point3); if (smooth) { mesh.Normals.Add(normal3); } mesh.TextureCoordinates.Add(coords3); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); // Make the second triangle. mesh.Positions.Add(point1); if (smooth) { mesh.Normals.Add(normal1); } mesh.TextureCoordinates.Add(coords1); mesh.Positions.Add(point3); if (smooth) { mesh.Normals.Add(normal3); } mesh.TextureCoordinates.Add(coords3); mesh.Positions.Add(point4); if (smooth) { mesh.Normals.Add(normal4); } mesh.TextureCoordinates.Add(coords4); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); phi += dphi; } theta += dtheta; } // Add texture coordinates 1.01 to prevent "seams." mesh.Positions.Add(new Point3D()); mesh.TextureCoordinates.Add(new Point(1.01, 1.01)); }