Last active
June 29, 2019 14:57
-
-
Save wware/b3b6f36da24df9061108e7f18a3fbc67 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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