quickfur wrote:I've noticed that even among the 3D Catalans, the coordinates are essentially a union of the coordinates of 2 or more of xNo3o, oNx3o, and oNo3x, variously scaled. I.e. the Catalans are the convex hull of various compounds of the regular and quasi-regular polyhedra of their respective families.
Apparently in 4D this is also the case. I surmise it's true in all dimensions.
quickfur wrote:Basically, my polytope viewer is currently somewhat limited in how it expresses rotations; it does not accept rotations in matrix form, but only handles axis-aligned rotations.
[...]
Alternatively, if you could supply pre-transformed vertex coordinates of the polytope, then I could run the convex hull algorithm to create the model already in the right orientation and do the rotation that way.
class Sqrt2Number:
def __init__(self, unit_coefficient, sqrt2_coefficient):
self.coef0 = unit_coefficient
self.coef1 = sqrt2_coefficient
def __repr__(self):
(s0, s1) = (self.coef0, self.coef1)
if s1 == 0:
return repr(s0)
if s0 == 0:
return repr(s1) + "*q"
if s1 < 0:
return repr(s0) + "-" + repr(-s1) + "*q"
return repr(s0) + "+" + repr(s1) + "*q"
def __add__(self, value):
if not isinstance(value, Sqrt2Number):
value = Sqrt2Number(value, 0)
return Sqrt2Number(self.coef0 + value.coef0, self.coef1 + value.coef1)
__radd__ = __add__
def __pos__(self):
return self
def __neg__(self):
return Sqrt2Number(-self.coef0, -self.coef1)
def __sub__(self, value):
return self + -value
def __rsub__(self, value):
return -self + value
def __mul__(self, value):
if not isinstance(value, Sqrt2Number):
value = Sqrt2Number(value, 0)
(s0, s1) = (self.coef0, self.coef1)
(v0, v1) = (value.coef0, value.coef1)
return Sqrt2Number(s0*v0 + 2*s1*v1, s0*v1 + s1*v0)
__rmul__ = __mul__
x = Sqrt2Number(1, 0)
q = Sqrt2Number(0, 1)
w = Sqrt2Number(1, 1)
m = Sqrt2Number(-1, 1) # Reciprocal of w
unsigned_vertices = [
[x, x, w, w],
[x, w, x, w],
[x, w, w, x],
[w, x, x, w],
[w, x, w, x],
[w, w, x, x],
]
vertices = []
for v in unsigned_vertices:
for s0 in [1, -1]:
for s1 in [1, -1]:
for s2 in [1, -1]:
for s3 in [1, -1]:
vertices.append(
[s0*v[0], s1*v[1], s2*v[2], s3*v[3]]
)
matrix = [
[+x, -w, -x, -w],
[+x, +w, +x, -w],
[+w, +x, -w, +x],
[+w, -x, +w, +x],
]
transformed_vertices = []
for v in vertices:
transformed_vertices.append(
[sum(v[i]*matrix[i][j] for i in range(4)) for j in range(4)]
)
# Everything has a factor of 2. Divide by 2, and by w.
# (This just changes the overall size of the polytope.)
for v in transformed_vertices:
for i in range(4):
vi = v[i]
(vi0, vi1) = (vi.coef0, vi.coef1)
assert vi0 % 2 == vi1 % 2 == 0
v[i] = Sqrt2Number(vi0 // 2, vi1 // 2) * m
for v in transformed_vertices:
print(v)
[2*q, 0, 0, 0]
[-1+1*q, 1, -1-1*q, -1]
[-1+1*q, -1, 1+1*q, -1]
[-2, 0, 0, -2]
[1+1*q, -1, 1-1*q, 1]
[0, 0, -2*q, 0]
[0, -2, 2, 0]
[-1-1*q, -1, 1-1*q, -1]
[1+1*q, 1, -1+1*q, 1]
[0, 2, -2, 0]
[0, 0, 2*q, 0]
[-1-1*q, 1, -1+1*q, -1]
[2, 0, 0, 2]
[1-1*q, 1, -1-1*q, 1]
[1-1*q, -1, 1+1*q, 1]
[-2*q, 0, 0, 0]
[1+1*q, -1+1*q, 1, -1]
[0, 1*q, -1*q, -2]
[1*q, 0, 2, -1*q]
[-1, 1, 1-1*q, -1-1*q]
[1*q, -2, 0, 1*q]
[-1, -1, -1-1*q, -1+1*q]
[-1+1*q, -1-1*q, 1, 1]
[-2, -1*q, -1*q, 0]
[2, 1*q, 1*q, 0]
[1-1*q, 1+1*q, -1, -1]
[1, 1, 1+1*q, 1-1*q]
[-1*q, 2, 0, -1*q]
[1, -1, -1+1*q, 1+1*q]
[-1*q, 0, -2, 1*q]
[0, -1*q, 1*q, 2]
[-1-1*q, 1-1*q, -1, 1]
[1+1*q, 1, 1-1*q, -1]
[1*q, 1*q, -1*q, -1*q]
[0, 0, 2, -2]
[-1, -1+1*q, 1, -1-1*q]
[1*q, -1*q, -1*q, 1*q]
[-1+1*q, -1, -1-1*q, 1]
[-1, -1-1*q, 1, -1+1*q]
[-2, -2, 0, 0]
[2, 2, 0, 0]
[1, 1+1*q, -1, 1-1*q]
[1-1*q, 1, 1+1*q, -1]
[-1*q, 1*q, 1*q, -1*q]
[1, 1-1*q, -1, 1+1*q]
[0, 0, -2, 2]
[-1*q, -1*q, 1*q, 1*q]
[-1-1*q, -1, -1+1*q, 1]
[1+1*q, -1, -1+1*q, -1]
[0, 0, -2, -2]
[1*q, -1*q, 1*q, -1*q]
[-1, 1-1*q, -1, -1-1*q]
[2, -2, 0, 0]
[1-1*q, -1, -1-1*q, -1]
[1, -1-1*q, 1, 1-1*q]
[-1*q, -1*q, -1*q, -1*q]
[1*q, 1*q, 1*q, 1*q]
[-1, 1+1*q, -1, -1+1*q]
[-1+1*q, 1, 1+1*q, 1]
[-2, 2, 0, 0]
[1, -1+1*q, 1, 1+1*q]
[-1*q, 1*q, -1*q, 1*q]
[0, 0, 2, 2]
[-1-1*q, 1, 1-1*q, 1]
[1+1*q, 1-1*q, -1, -1]
[1*q, 0, -2, -1*q]
[0, -1*q, 1*q, -2]
[-1, -1, -1+1*q, -1-1*q]
[2, -1*q, -1*q, 0]
[1, -1, -1-1*q, 1-1*q]
[1-1*q, -1-1*q, 1, -1]
[-1*q, -2, 0, -1*q]
[1*q, 2, 0, 1*q]
[-1+1*q, 1+1*q, -1, 1]
[-1, 1, 1+1*q, -1+1*q]
[-2, 1*q, 1*q, 0]
[1, 1, 1-1*q, 1+1*q]
[0, 1*q, -1*q, 2]
[-1*q, 0, 2, 1*q]
[-1-1*q, -1+1*q, 1, 1]
[2, 0, 0, -2]
[1, -1+1*q, -1, -1-1*q]
[1, 1-1*q, 1, -1-1*q]
[0, 0, 0, -2*q]
[1, -1-1*q, -1, -1+1*q]
[0, -2, -2, 0]
[0, -2*q, 0, 0]
[-1, -1-1*q, -1, 1-1*q]
[1, 1+1*q, 1, -1+1*q]
[0, 2*q, 0, 0]
[0, 2, 2, 0]
[-1, 1+1*q, 1, 1-1*q]
[0, 0, 0, 2*q]
[-1, -1+1*q, -1, 1+1*q]
[-1, 1-1*q, 1, 1+1*q]
[-2, 0, 0, 2]
mr_e_man wrote::)
Maybe, instead of highlighting octahedra, just highlight two opposite sircoes, and the eight vertices (0, 0, ±2√2, 0) and (0, 0, 0, ±2√2) and (0, 0, ±2, ±2).
And I'd rather not see the far side of the polytope.
[...]
In fact, I've tried up to 4 times as long and still haven't found the cells returning to the original positions yet. It may turn out to be something as large as 12 times as long.
If you look at the above animation and trace a single octahedron, you'll see that it makes a pretty long spiralling orbit around the polytope before returning to its original position.
Also, clipping the far side of the polytope [...]
mr_e_man wrote:[...]
The symmetry is (135°, 45°), so a cell returns to its starting position after 8 cycles of the animation. But if antipodal cells look the same, it should be only 4 times as long.
[...]Also, clipping the far side of the polytope [...]
I notice some triangles are still appearing green at the limb, then turning yellow as the whole octahedron appears. Is that supposed to happen?
quickfur wrote:mr_e_man wrote:[...]
The symmetry is (135°, 45°), so a cell returns to its starting position after 8 cycles of the animation. But if antipodal cells look the same, it should be only 4 times as long.
I tried running the animation for 4x its length, there's still a skip between the end and the start. I've no idea why.
[...]Also, clipping the far side of the polytope [...]
I notice some triangles are still appearing green at the limb, then turning yellow as the whole octahedron appears. Is that supposed to happen?
This is because the while the octahedron is on the far side of the polytope, one face still lies on the limb, so that still shows up.
Users browsing this forum: No registered users and 2 guests