[Edu-sig] OT: calculating dodeca icosa solid assembly angles

kirby urner kirby.urner at gmail.com
Fri Jan 19 03:27:09 CET 2007

> Bonus request is if you can show me the [pythonic] math for calculating
> this simple angle.
> Thanks very much any suggestions, links etc.
> Jason

For the icosahedron, I think you should focus on the 20 almost-regular
tetrahedra, with slices parallel to the bases (the 20 facets) defining the
thin outer shell of your handsome wooden and/or plastic casement.

Your bevel angle will be the dihedral angle between the base and any
one of the three facets meeting at the apex ( = icosahedron center).

The altitude of this almost-regular tetrahedron is now of concern.

My rbf.py will have the Icosahedron in terms of its facets (tuples)
and vertex vectors (a dictionary):

IDLE 1.1
>>> import rbf
Visual 2005-01-08

>>> someicosa = rbf.Icosa()

>>> someicosa.vertices
{'Q1': vector(-0.809016994374947, 0, 0.5), 'P1':
vector(0.809016994374947, 0, 0.5), 'R1': vector(0, -0.5,
0.809016994374947), 'S1': vector(0, 0.5, -0.809016994374947), 'U1':
vector(-0.809016994374947, 0, -0.5), 'T1': vector(0.809016994374947,
0, -0.5), 'V1': vector(0, -0.5, -0.809016994374947), 'W1':
vector(-0.5, 0.809016994374947, 0), 'Y1': vector(0.5,
-0.809016994374947, 0), 'X1': vector(-0.5, -0.809016994374947, 0),
'Z1': vector(0.5, 0.809016994374947, 0), 'O1': vector(0, 0.5,

>>> someicosa.faces
[('O1', 'Q1', 'W1'), ('O1', 'Z1', 'P1'), ('P1', 'R1', 'Y1'), ('R1',
'Q1', 'X1'), ('W1', 'S1', 'U1'), ('U1', 'X1', 'V1'), ('Y1', 'T1',
'V1'), ('Z1', 'T1', 'S1'), ('O1', 'P1', 'R1'), ('O1', 'Q1', 'R1'),
('O1', 'Z1', 'W1'), ('W1', 'S1', 'Z1'), ('Q1', 'W1', 'U1'), ('Q1',
'U1', 'X1'), ('Z1', 'P1', 'T1'), ('Y1', 'P1', 'T1'), ('R1', 'Y1',
'X1'), ('V1', 'Y1', 'X1'), ('T1', 'S1', 'V1'), ('U1', 'S1', 'V1')]

So now I'll pick the first face, add the three edge vectors, and divide by 3,
to get the vector going straight from ORIGIN (icosa center) to the center
of one of its triangular faces.

>>> altitude = (1/3.0) * (someicosa.vertices['O1'] +
someicosa.vertices['Q1'] + someicosa.vertices['W1'])
>>> altitude
vector(-0.436338998124982, 0.436338998124982, 0.436338998124982)

>>> dir(altitude)
['__abs__', '__add__', '__class__', '__delattr__', '__dict__',
'__div__', '__doc__', '__getattribute__', '__getitem__', '__hash__',
'__iadd__', '__idiv__', '__imul__', '__init__', '__instance_size__',
'__isub__', '__itruediv__', '__len__', '__module__', '__mul__',
'__neg__', '__new__', '__pos__', '__reduce__', '__reduce_ex__',
'__repr__', '__rmul__', '__setattr__', '__setitem__', '__str__',
'__sub__', '__truediv__', '__weakref__', 'astuple', 'clear', 'comp',
'cross', 'diff_angle', 'dot', 'mag', 'mag2', 'norm', 'proj', 'rotate',
'x', 'y', 'z']

>>> altitude.mag

Next, I'll define the edge going from ORIGIN to a mid-edge on the surface:

>>> sideline = (1/2.0) * (someicosa.vertices['O1'] + someicosa.vertices['Q1'])

Their angle difference should give the 2nd angle of a right triangle, with the
right angle where the tetrahedron's altitude meets the face center, the
other leg being from this point to a mid Icosa edge on the surface, the
hypotenuse being the above sideline.

>>> altitude.diff_angle(sideline)

>>> from math import degrees

>>> 180 - 90 - degrees(0.36486382811348295)

>>> degrees(0.36486382811348295)

So I'm getting a bevel angle of like 69.1 degrees.

This seems about right, because the corresponding dihedral angle for a
*regular* tetrahedron is 70.53 degrees whereas here the "tent pole" is a
little shorter, so the sides rise a little less steeply.


As another check, the sideline, plus an origin-vertex edge, plus a half
edge on the surface (length = 1/2) should be a right triangle.

>>> sideline.mag2 + 0.5**2
>>> someicosa.vertices['Q1'].mag2

Edge length check:
>>> (someicosa.vertices['Q1'] - someicosa.vertices['O1']).mag


More information about the Edu-sig mailing list