"""
(Python 3.x version)
4D Solutions
K. Urner
Feb 24 2008
So using simplification of 8 triangular
plus 6 square numbers, per faces of
cuboctahedron, accounting for double-
counted edges, triple-counted vertices,
leaves us 10*f*f + 2 total balls in each
shell, with f being the number of intervals,
starting with 1 for 12 around a nuclear
(which counts as 2 where f=0).
Bucky sent these scribbles to Coxeter who
approved, amazed only high school level
algebra needed. On-line Encyclopedia of
Integer Sequences gives more: 1, 12, 42, 92..
"""
def cubocta(f):
return 10 * f * f + 2
"""
By the Jitterbug Transformation, whereby
a cuboctahedron is transformed into an
icosahedron, without losing any marbles,
the above formula works for them too, i.e.
think of each of 20 triangular faces
subdivided into f ** 2 subfaces. Ratio
of non_polar:faces:edges == 1:2:3 on this
f-frequency beast, where n = v-2, i.e.
non_polar = 10 * f * f.
"""
def icosa_non_polar(f):
"""
nonpolar vertices of an
n-frequency icosahedron
"""
return cubocta(f) - 2
def icosa_faces(f):
"""
number of faces in an
n-frequency icosahedron
"""
return 2 * icosa_non_polar(f)
def icosa_edges(f):
"""
number of faces in an
n-frequency icosahedron
"""
return 3 * icosa_non_polar(f)
"""
A hexapent of the global matrix variety,
per Glenn Stockton, is such an n-frequency
icosahedra, spherically produced, with
edges eliminated so as to leave only
hexagonal and 12 pentagonal windows.
The first frequency where this works is
the soccer ball, or C60 (buckminsterfullerene),
which may be omnitriangulated by adding
12 * 5 + 20 * 6 edges to the existing
inventory of 90, along with 12 * 4 + 20 * 5
more faces for a total of 180, and 12 + 20
= 32 new vertices, for a total of 60 + 32 = 92
verticies, i.e. 90 non_polar i.e. f = 3.
A useful check on one's figures comes in
the form of Euler's Law for Polyhedra:
V + F = E + 2, for the kinds that we're
checking.
V + F = E + 2
92 + 180 = 270 + 2
N:2N:3N :: 90:180:270
"""
def hexapent(f=3):
while True:
faces = icosa_faces(f)
gm_hexagons = (faces - 12*5)//6 # de-omnitriangulating
gm_pentagons = 12 # constant
# double count every edge, divide by 2
gm_edges = (gm_hexagons * 6 + gm_pentagons * 5)//2
gm_vertices = gm_edges + 2 - (gm_hexagons + 12) # per Euler
yield (gm_vertices, gm_hexagons + gm_pentagons, gm_edges) # (V,F,E)
f = f + 3 # bump up frequency by 3
"""
Per OEIS
http://www.research.att.com/~njas/sequences/A005903
we can also generate the number gm_hexagons + gm_pentagons
as simply 30*n**2 + 2 e.g.
>>> [30*n*n + 2 for n in range(90,100)]
[243002, 248432, 253922, 259472, 265082,
270752, 276482, 282272, 288122, 294032]
"""
def test():
thegm = hexapent()
for i in range(100):
print(next(thegm))