""" Express subsequent face-bonded tetrahedra as rational numbers (p/q) by Kirby Urner Jan 11, 2005 """ import math from __future__ import division def tetrahelix(): """ Start with 4 vertices sqrt(2) interdistant """ v1 = tuple([Rat(i) for i in (0,0,0)]) v2 = tuple([Rat(i) for i in (0,1,1)]) v3 = tuple([Rat(i) for i in (1,0,1)]) v4 = tuple([Rat(i) for i in (1,1,0)]) a,b,c,d = [apply(Vector,i) for i in [v1,v2,v3,v4]] loop = True while loop: print "%s\n%s\n%s\n%s\n" % (a,b,c,d) # plot the apex of subsequent tet e = (a+b+c)*Rat(2,3) - d # lose whatever vertex is > sqrt(2) distant b,c,d = filter(lambda x: (e-x).length() < 1.5, [a,b,c,d]) a = e if not raw_input("Again? (y/n)? ").upper()=="Y": loop = False class Rat(object): """ I couldn't find my old version, so quickly recoded from scratch. It's stripped down -- no powering or reciprocation """ def __init__(self,num,denom=1): f = self._gcd(num,denom) self.num = num/f self.denom = denom/f def __mul__(self,other): if type(other) == type(1): return Rat(self.num*other, self.denom) else: return Rat(self.num*other.num, self.denom*other.denom) def __add__(self,other): f = self._lcm(self.denom, other.denom) return Rat(self.num*f/self.denom + other.num * f/other.denom, f) def __neg__(self): return Rat(-self.num, self.denom) def __sub__(self,other): return self + -other def _gcd(self,a,b): while b: a,b = b,a%b return a def _lcm(self,a,b): return (a*b)/self._gcd(a,b) def __float__(self): return self.num/self.denom def __repr__(self): return "(%s/%s)" % (self.num, self.denom) class Vector(object): """ And yer classic vector object. Again, I've coded this a million times (OK, maybe 7-10 times). Again, I'm just including ops that get my tetrahelix demo to work """ def __init__(self,a,b,c): self.a = a self.b = b self.c = c def __add__(self, other): return Vector(self.a + other.a, self.b + other.b, self.c + other.c) def length(self): return math.sqrt(float(self.a*self.a + self.b*self.b + self.c*self.c)) def __neg__(self): return Vector(-self.a, -self.b, -self.c) def __sub__(self, other): return self + -other def __mul__(self, k): return Vector(self.a * k, self.b * k, self.c * k) __rmul__ = __mul__ def __repr__(self): return "Vector(%s, %s, %s)" % (self.a, self.b, self.c)