How can I algorithmically generate the vertices of dodecahedron?
I would like the tetrahedron's centroid to be at (0, 0, 0)
.
From Wikipedia:
The following Cartesian coordinates define the vertices of a dodecahedron centered at the origin and suitably scaled and oriented:
(±1, ±1, ±1)
(0, ±1/φ, ±φ)
(±1/φ, ±φ, 0)
(±φ, 0, ±1/φ)
where φ = (1 + √5) / 2 is the golden ratio (also written τ) ≈ 1.618. The edge length is 2/φ = √5 – 1. The containing sphere has a radius of √3.
I find that this description is way more concise and informative than a big piece of C# code. (-:
Since the question is now the top result for a Google search (the dupe at math is #2), I figured I might as well add some code.
A full console program is below and should compile and run and be generally self-explanatory.
The algorithm was based on the Wikipedia article (thank you, mt_ from math.stackoverflow.com)
This code should print a correct list of vertices for you. Your concern is mostly with the method Program.MakeDodecahedron
, however don't just copy and paste it because you need to modify this to use your own vertex data structure instead of my mock Vertex
object. You could easily use XNA's Vector3, which has a constructor with the exact same signature as my Vertex
. Also because my Vertex.ToString
method is hacky, this program may print an ugly output table when used with Vector3
so keep that in mind.
Also, note that this is a(n imprefect) demonstration. For instance, if generating many tetrahedra, you would be needlessly recalculating constants (such as the golden ratio) for each call.
With XNA, especially if you use Microsoft.Xna.Framework
, you can also easily render your dodecahedron in 3D. You can adapt the code from this tutorial for this purpose.
using System;
using System.Collections.Generic;
namespace DodecahedronVertices
{
class Program
{
static void Main()
{
// Size parameter: This is distance of each vector from origin
var r = Math.Sqrt(3);
Console.WriteLine("Generating a dodecahedron with enclosing sphere radius: " + r);
// Make the vertices
var dodecahedron = MakeDodecahedron(r);
// Print them out
Console.WriteLine(" X Y Z");
Console.WriteLine(" ==========================");
for (var i = 0; i < dodecahedron.Count; i++)
{
var vertex = dodecahedron[i];
Console.WriteLine("{0,2}:" + vertex, i + 1);
}
Console.WriteLine("\nDone!");
Console.ReadLine();
}
/// <summary>
/// Generates a list of vertices (in arbitrary order) for a tetrahedron centered on the origin.
/// </summary>
/// <param name="r">The distance of each vertex from origin.</param>
/// <returns></returns>
private static IList<Vertex> MakeDodecahedron(double r)
{
// Calculate constants that will be used to generate vertices
var phi = (float)(Math.Sqrt(5) - 1) / 2; // The golden ratio
var a = 1 / Math.Sqrt(3);
var b = a / phi;
var c = a * phi;
// Generate each vertex
var vertices = new List<Vertex>();
foreach (var i in new[] { -1, 1 })
{
foreach (var j in new[] { -1, 1 })
{
vertices.Add(new Vertex(
0,
i * c * r,
j * b * r));
vertices.Add(new Vertex(
i * c * r,
j * b * r,
0));
vertices.Add(new Vertex(
i * b * r,
0,
j * c * r));
foreach (var k in new[] { -1, 1 })
vertices.Add(new Vertex(
i * a * r,
j * a * r,
k * a * r));
}
}
return vertices;
}
}
/// <summary>
/// A placeholder class to store data on a point in space. Don't actually use this, write a better class (or just use Vector3 from XNA).
/// </summary>
class Vertex
{
double x;
double y;
double z;
public Vertex(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
public override string ToString()
{
var s = String.Format("{0,8:F2},{1,8:F2},{2,8:F2}", x, y, z);
return s;
}
}
}
As my code is probably quite verbose and spread out, I'd recommend reading it in something which supports folding of for-loops and other code structures.
The Cartesian coordinates of a dodecahedron centered at P(0, 0, 0) and vertices bounded by a sphere of radius r are given by:
P(± r/√3, ± r/√3, ± r/√3)
P(0, ± r/(√3*φ), ± (r*φ)/√3)
P(± r/(√3*φ), ± (r*φ)/√3, 0)
P(± (r*φ)/√3, 0, ± r/(√3*φ))
where φ = (1 + √5) / 2 is the golden ratio (also written τ) ≈ 1.618.
Here's a Riemann surface stereographic projection centered at a 0 vertex. (Sorry, I can't find how to post math symbols)
Where T is the golden ratio, let a = 1/T^2 and let the complex conjugate pair b+-ic be defined with b=sqrt(5)/4 and c=sqrt(3)/4. Rotate these three points by 0, 120, and 240 degrees so you now have nine points, all inside the unit circle.
Map every point to an image outside the unit circle using the map z -> -1/z. Add a point at zero and infinity and you now have all the vertices of the dodecahedron.
If you want your dodecahedron on the sphere, do the usual stereographic back-map, making the unit circle go onto the equator. By the usual process of inscribing, this also gives you a vertex-centered cube or tetrahedron, but rotated by about 37.76 or 22.24 degrees respectively.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With