# Building the Unit Icosahedron

This post builds on the concepts contained in the previous post: “The Icospherical World Model: Problem Specification and Preliminary Data Structure.”

In this post, we would like to use our atomic icospherical building block, the Triangle, to build up the basic Icosahedron, which is an icosphere of recursive depth zero.

Our first step is to simply define the 12 vertices of the unit Icosahedron. From a simple Google search, Wikipedia reveals the (really interesting) fact that an Icosahedron’s vertices can be represented by 12 vertices of three orthogonal Golden Rectangles.

A Golden Rectangle is any Rectangle in keeping with the Golden Ratio. That is, the ratio of the rectangle’s sides, a and b, is equivalent to the ratio of a+b to the longer of the two sides.

With this knowledge, generating the vertices of our icosahedron is simple:

```//////////////////////////////////////////////////////////
// GENERATE UNIT VERTICES using 3 Orthogonal Rectangles //
//                                                      //
//                    /|  - R1                          //
//                   / |                                //
//                  /  |                                //
//                 /   |                                //
//                |    |                                //
//               _|    |_______                         //
//      ________/_|   _|______/__                       //
//     |          |  |           |                      //
//     |      ____|  |______     |                      //
//     |     /    | /      /     |                      //
//     |____/     |/      /______|  - R2                //
//         /             /                              //
//        /_____________/                               //
//                |    |                                //
//         ^      |    /                                //
//        R3      |   /                                 //
//                |  /                                  //
//                | /                                   //
//                |/                                    //
//                                                      //
//////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////

// The golden ratio
float t = (1.0f + (float) Math.Sqrt(5.0)) / 2.0f;

// A collection of the 12 base vertices.
Dictionary<int, Vector3> vertices = new Dictionary<int, Vector3>();

// Trace the four vertices of a Golden rectangle [R1]

// Trace the four verices of a Golden rectangle orthagonal to the last [R2]

// Trace the four verices of a Golden rectangle orthagonal to the last two [R3]
```

Notice that we are adding these vertices to the Unit Sphere right off the bat, using the convenient private method:

```// Add a vector to the unit sphere.
{
float length = (float) Math.Sqrt(v.X*v.X + v.Y*v.Y + v.Z*v.Z);
return new Vector3(v.X/length, v.Y/length, v.Z/length);
}
```

Now that we have the vertices of the unit icosahedron, we need to create Triangles with them.

Knowing that vertices 0-3 belong to the first rectangle, vertices 4-7 belong to the second triangle, and vertices 8-11 belong to the third, we can easily construct our 20 Triangle objects using our vertices.

In our last post, we did not discuss the Triangle constructor. In the course of our development, we will create numerous different Triangle constructors for different purposes. But the constructor used below accepts the following arguments:

• Unique Index (int)
• Recursive Depth (int)
• v1 (Vector3)
• v2 (Vector3)
• v3 (Vector3)
```Dictionary<int, Triangle> faces = new Dictionary<int, Triangle>();

// 5 faces around point 0
faces.Add(0, new Triangle(0, 0, vertices, vertices, vertices));
faces.Add(1, new Triangle(1, 0, vertices, vertices, vertices));
faces.Add(2, new Triangle(2, 0, vertices, vertices, vertices));
faces.Add(3, new Triangle(3, 0, vertices, vertices, vertices));
faces.Add(4, new Triangle(4, 0, vertices, vertices, vertices));

faces.Add(5, new Triangle(5, 0, vertices, vertices, vertices));
faces.Add(6, new Triangle(6, 0, vertices, vertices, vertices));
faces.Add(7, new Triangle(7, 0, vertices, vertices, vertices));
faces.Add(8, new Triangle(8, 0, vertices, vertices, vertices));
faces.Add(9, new Triangle(9, 0, vertices, vertices, vertices));

// 5 faces around point 3
faces.Add(10, new Triangle(10, 0, vertices, vertices, vertices));
faces.Add(11, new Triangle(11, 0, vertices, vertices, vertices));
faces.Add(12, new Triangle(12, 0, vertices, vertices, vertices));
faces.Add(13, new Triangle(13, 0, vertices, vertices, vertices));
faces.Add(14, new Triangle(14, 0, vertices, vertices, vertices));

faces.Add(15, new Triangle(15, 0, vertices, vertices, vertices));
faces.Add(16, new Triangle(16, 0, vertices, vertices, vertices));
faces.Add(17, new Triangle(17, 0, vertices, vertices, vertices));
faces.Add(18, new Triangle(18, 0, vertices, vertices, vertices));
faces.Add(19, new Triangle(19, 0, vertices, vertices, vertices));
```

Now that all of our Triangles exist, we can ascribe them adjacency data.

I wish that I had an impressive, two-line, mathematically elegant method that I wrote in order to assign this adjacency data here, but I do not. I have very tediously hand-written each of the 20 faces’ adjacency data, but the good news is: once the R-0 adjacency data is written, we never need to handwrite any adjacency data again.

This is because, as we recurse each face, we can programatically generate adjacency data as we go. As long as the R0 structure has accurate adjacency data, all descendants will be able to iterate their own accurate adjacency data.

The following code is almost not worth including, but I will include it here in the off chance that some wayfaring developer on the internet is trying to replicate my code, so that they can simply have these adjacency values instead of scratching their head for an hour, turning over a d20 in their hands like I did. You may consider wrapping these assignments in a handy “setAdjacencies” method, as I have written to do in my own personal backlog.

Remember: The order of adjacencies is of crucial importance.

```// Face 0 adjacencies;