Title: Platonic Solids Part 6: The icosahedron
This example continues the series on the Platonic solids. As I'm sure you can guess from the title, it explains how you can build an icosahedron.
Finding the Icosahedron's Vertices
Figure 1 shows an icosahedron with its hidden surfaces removed.
Figure 2 shows the same icosahedron with hidden surfaces drawn in dashed lines and its vertices labeled a through l.
The icosahedron is centered at the origin in these figures. Vertices a and l lie on the Y-axis so they have X and Z coordinates 0. Vertices b and g lie in the X-Y plane so they have Z coordinate 0.
Let Y1 be the Y coordinate of vertex a and let Y2 be the Y coordinate of vertices b through f. By symmetry, the Y coordinate of vertex l is -Y1 and the Y coordinate of vertices g through k are -Y2.
To calculate the vertices' X and Z coordinates, look at the icosahedron from the top. Consider only the positions of vertices b through f and g through k as shown in Figure 3. The two pentagons that contain those vertices allow you to calculate their X and Z coordinates.
Let S be the length of the icosahedron's edges and consider just the right half of the pentagon shown in Figure 4. You can use the angles t1, t2, t3, and t4 to calculate the points' coordinates.
Because the nodes are arranged in a pentagon, t1 = 2 * Pi / 5 and
t2 = Pi / 2 - t1
= Pi / 2 - 2 * Pi / 5
= Pi / 10
Similarly t4 = t1 / 2 = Pi / 5 and:
t3 = -(Pi / 2 - t4) = -(Pi / 2 - Pi / 5)
= -3 * Pi / 10
Using trigonometry in the t4 triangle, Sin(t4) = (S/2) / R so R = (S/2) / Sin(t4).
Then using the same triangle Cos(t4) = H / R so H = R * Cos(t4).
Using these values, you have the coordinates for points b and d:
b = ( R, Y2, 0)
d = (-H, Y2, S/2)
Similarly you can use trigonometry to calculate that the X and Z coordinates of point c are R * Sin(t2) and R * Cos(t2). For notational convenience, let these values be Cx and Cz.
Using the symmetry shown in Figure 3, you can calculate the coordinates for all of the rest of the points.
a = ( 0, Y1, 0)
b = ( R, Y2, 0)
c = ( Cx, Y2, Cz)
d = ( -H, Y2, S/2)
e = ( -H, Y2, -S/2)
f = ( Cx, Y2, -Cz)
g = ( -R, -Y2, 0)
h = (-Cx, -Y2, -Cz)
i = ( H, -Y2, -S/2)
j = ( H, -Y2, S/2)
k = (-Cx, -Y2, Cz)
l = ( 0, -Y1, 0)
Where:
S = the side length (given)
t1 = 2 * Pi / 5
t2 = Pi / 10
t4 = Pi / 5
t3 = -3 * Pi / 10
R = (S/2) / Sin(t4)
H = Cos(t4) * R
Cx = R * Sin(t2)
Cz = R * Cos(t2)
The only values left to calculate are Y1 and Y2. Consider the top of the icosahedron shown in Figure 5. Look again at Figure 4 to see how the value R fits into this picture.
We know S and R, so we can calculate H1:
H1 = Sqrt(S * S - R * R)
Now consider one of the pentagons on the side that contains the points a, b, and i as shown in Figure 6. Let H2 be the vertical distance between points a and i. You already know that the X coordinate of point i is H so the horizontal distance along the X-axis between these points is H as shown in the figure.
The hypotenuse of the triangle with sides H and H2 is the height of the pentagon containing points a, b, and i. Figure 4 shows that distance is H + R. You can now use these values to solve for H2.
H2 = Sqrt((H + R) * (H + R) - H * H)
Finally, you can use the values of H1 and H2 to calculate Y1 and Y2.
Y2 = (H2 - H1) / 2
Y1 = Y2 + H1
The Example Program
The following code shows how the example program generates the icosahedron's vertices.
// Return the vertices for an icosahedron.
private Point3D[] MakeVertices(double side_length)
{
// t1 and t3 are actually not used in calculations.
double S = side_length;
//double t1 = 2.0 * Math.PI / 5;
double t2 = Math.PI / 10.0;
double t4 = Math.PI / 5.0;
//double t3 = -3.0 * Math.PI / 10.0;
double R = (S / 2.0) / Math.Sin(t4);
double H = Math.Cos(t4) * R;
double Cx = R * Math.Sin(t2);
double Cz = R * Math.Cos(t2);
double H1 = Math.Sqrt(S * S - R * R);
double H2 = Math.Sqrt((H + R) * (H + R) - H * H);
double Y2 = (H2 - H1) / 2.0;
double Y1 = Y2 + H1;
List points = new List();
points.Add(new Point3D ( 0, Y1, 0));
points.Add(new Point3D ( R, Y2, 0));
points.Add(new Point3D ( Cx, Y2, Cz));
points.Add(new Point3D ( -H, Y2, S/2));
points.Add(new Point3D ( -H, Y2, -S/2));
points.Add(new Point3D ( Cx, Y2, -Cz));
points.Add(new Point3D ( -R, -Y2, 0));
points.Add(new Point3D (-Cx, -Y2, -Cz));
points.Add(new Point3D ( H, -Y2, -S/2));
points.Add(new Point3D ( H, -Y2, S/2));
points.Add(new Point3D (-Cx, -Y2, Cz));
points.Add(new Point3D ( 0, -Y1, 0));
// Verify that the edges have the same length.
VerifyEdgeLengths(side_length, points.ToArray());
return points.ToArray();
}
This code uses the equations above to calculate the values needed to generate the vertices' coordinates. It then creates the vertices and adds them to a list. It calls VerifyEdgeLengths to verify that the adjacent vertices are 1 unit apart and then returns the list of vertices converted into an array.
The rest of the program's code deals with using WPF to display the icosahedron's faces, its edges, and the axes.
Download the example to experiment with it and to see additional details.
|