Skip to content

Instantly share code, notes, and snippets.

@wware
Last active June 29, 2019 14:57
Show Gist options
  • Select an option

  • Save wware/b3b6f36da24df9061108e7f18a3fbc67 to your computer and use it in GitHub Desktop.

Select an option

Save wware/b3b6f36da24df9061108e7f18a3fbc67 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
"""
The top five vertices are at 72-degree increments at a height of z=A.
The next five vertices are at the same 72-degree incremenets at a
height of z=B. Next five are offset by 36 degrees, with z=-B, and last
five are also offset by 36 degrees with z=-A. The trick is to make sure
all the lengths are the same, and solve for A and B.
Let Ea and Fa be two adjacent vertices of the top five. Let Eb and Fb
be the vertices below them at z=B. Let Gb be the vertex connecting to
Eb and Fb at z=-B, then you have
d = |Ea-Fa|^2 = |Ea-Eb|^2 = |Eb-Gb|^2 = |Fb-Gb|^2
Then we can just set up an error function of the differences between
these four distances, and do gradient descent in A and B to make all
the distances equal.
Without loss of generality assume all vertices are distance 1 from the
origin.
"""
from math import pi, cos, sin
class vertices(object):
def __init__(self, A, B):
assert 0 <= A <= 1
assert 0 <= B <= 1
self.A, self.B = A, B
theta = pi * 72 / 180
ra = (1 - A**2) ** .5
rb = (1 - B**2) ** .5
self.Ea = (ra, 0, A)
self.Fa = (ra * cos(theta), ra * sin(theta), A)
self.Eb = (rb, 0, B)
self.Fb = (rb * cos(theta), rb * sin(theta), B)
self.Gb = (rb * cos(.5*theta), rb * sin(.5*theta), -B)
def error(self):
def dist(p1, p2):
return ((p1[0] - p2[0]) ** 2 +
(p1[1] - p2[1]) ** 2 +
(p1[2] - p2[2]) ** 2) ** .5
d1 = dist(self.Ea, self.Fa)
d2 = dist(self.Ea, self.Eb)
d3 = dist(self.Eb, self.Gb)
d4 = dist(self.Fb, self.Gb)
return (d1 - d2) ** 2 + (d2 - d3) ** 2 + (d3 - d4) ** 2
A, B = 0.8, 0.3
h = 1.e-12
m = 1.e-4
while True:
v1 = vertices(A, B)
v2 = vertices(A + h, B)
v3 = vertices(A, B + h)
partialA = (v2.error() - v1.error()) / h
partialB = (v3.error() - v1.error()) / h
print A, B, partialA, partialB
A -= m * partialA
B -= m * partialB
# This gives A, B = 0.79465447229, 0.187592474082
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment