# 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; Listpoints = 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 and look at the code for details.

Pingback: Build a geodesic sphere with WPF and C# - C# HelperC# Helper

Hi Rods, I have a question, why does the value of t3 is negative, thank you ?

It’s negative because it’s a clockwise angle. Normally angles in .NET are measured counter clockwise from the horizontal X axis pointing to the right. Basically this one goes down instead of up.

Wait why do you make it a clockwise angle instead of counter clockwise just like the others ?

That’s just the way it works out with the layout in Figure 4. To make it a positive angle, you would need to use the segment connecting the center to point d as the triangle’s adjacent side. It doesn’t lie on the X or Z axis so that would be hard.

I also want to learn Java to, Do you have any book, tutorial or any resource for learning Java ?. Thanks you.

Sorry but I don’t. I haven’t used Java in a long time and haven’t written any books about it.

And when I change the order at which the vertices were added, I see a big difference. If I Change:

AddTriangle(solid_mesh, points[0], points[2], points[1]);

AddTriangle(solid_mesh, points[0], points[3], points[2]);

AddTriangle(solid_mesh, points[0], points[4], points[3]);

AddTriangle(solid_mesh, points[0], points[5], points[4]);

AddTriangle(solid_mesh, points[0], points[1], points[5]);

into:

AddTriangle(solid_mesh, points[0], points[1], points[2]);

AddTriangle(solid_mesh, points[0], points[2], points[3]); AddTriangle(solid_mesh, points[0], points[3], points[4]);

AddTriangle(solid_mesh, points[0], points[4], points[5]);

AddTriangle(solid_mesh, points[0], points[5], points[1]);

will make the top faces of the icosahedron completely disappears, Could you explain me why, thanks.

The points on the triangles must be outwardly-oriented. See the section “The Coordinate System” in this post:

This is the way the drawing system decides whether it’s looking at a triangle from the top (so it draws the triangle) or the bottom (and it doesn’t draw the triangle).

So if you change the order of the points in a triangle, it may disappear.

You can also set the triangle’s

BackMaterialproperty to a material. Then it will appear when viewed from either side, but it’s less efficient.Thanks, that’s very nice of you.

I see, If the order at which I add the vertices is counter clockwise, It will understand that face will be looking from the outside and draw it.

Exactly. They must be counter-clockwise as seen from the position of the camera.

setting side_length to 1.051463 will approximately make all the points have a magnitude value of ~ 1 , any ideas why is that ?

The original equations assume the side length is 1. If you use those, then the vertices are 1.051463 away from the origin. If you divide all of the vertex coordinates by that number, then they will all be 1 away from the origin.