from cmath import * class Similarity: """ A transformation of the form z -> Az + B or z ->Az_ + B. """ def __init__(self, a, b, flip=0): self.A = a self.B = b self.flip = flip def __repr__(self): if self.flip: return "z -> %sz_ + %s"%(`self.A`, `self.B`) return "z -> %sz + %s"%(`self.A`, `self.B`) def __mul__(self, other): flip = self.flip^other.flip if self.flip: return Similarity(self.A*other.A.conjugate(), self.A*other.B.conjugate() + self.B, flip) else: return Similarity(self.A*other.A , self.A*other.B + self.B, flip) def __call__(self, z): return self.A*z + self.B def ChainSims(left, right): """ [x1,...xn], [y1,...,ym] -> [x1y1,x1y2,...,x1yk,...,xny1,...xnyk]. """ result = [] for sim in left: result += map( sim.__mul__, right ) return result def PolygonToSimlist(polygon): """ Returns a list of similarities that map [0,1] to the sides of a polygon. """ result = [] z0 = polygon[0] for z in polygon[1:]: z1 = z result.append( Similarity(z1-z0, z0) ) z0=z1 return result def zToPixels(window_width, window_height, z_center, z_width, z): """ Computes the screen coordinates of a complex number. """ z = complex(z) pixel_size = float(z_width)/window_width left = z_center.real - window_width*pixel_size/2 top = z_center.imag + window_height*pixel_size/2 return (int((z.real - left)/pixel_size), int((top - z.imag)/pixel_size)) def SimlistToPixels(simlist, W, H, z_center=0+.4j, z_width=2): """ Returns a list of screen coordinates of the images of 0 and 1. """ points = [] for sim in simlist: points += zToPixels(W, H, z_center, z_width, sim(0)) points += zToPixels(W, H, z_center, z_width, sim(1)) return points