mobius.py


SUBMITTED BY: Eupator

DATE: March 2, 2017, 12:41 p.m.

FORMAT: Python

SIZE: 2.0 kB

HITS: 1212

  1. #mobius.py
  2. import cmath, numpy
  3. class circle_involution:
  4. def __init__(self, center, radius):
  5. self.center = center
  6. self.radius = radius
  7. def transform(self):
  8. c = self.center
  9. r = self.radius
  10. return translation(conj(c))*self.scaling(r)*involution*self.inv_scaling(1.0/r)*self.inv_translation(-c)
  11. def of(self, z):
  12. "Apply to homogenous coordinate z."
  13. w = self.transform()*z
  14. return conj(w)
  15. def of_circle(self, center, radius):
  16. "Apply to circle involution."
  17. if radius == 0:
  18. return 0, 0
  19. # We find the involution of center, radius
  20. c = self.center
  21. r = self.radius
  22. # We conjugate it with our own involution
  23. C = translation(conj(c))*scaling(r)*involution*scaling(1.0/r)*translation(-c)
  24. D = translation(center)*scaling(radius)*involution*scaling(1.0/radius)*translation(conj(-center))
  25. E = translation(conj(c))*scaling(r)*involution*scaling(1.0/r)*translation(-c)
  26. image_transform = C*D*E
  27. # The result is itself an involution whose center/radius we return
  28. a = image_transform.item(0)
  29. b = image_transform.item(1)
  30. c = image_transform.item(2)
  31. d = image_transform.item(3)
  32. a /= c
  33. b /= c
  34. d /= c
  35. c = 1.0
  36. new_center = -d
  37. new_radius = abs(b + (new_center*conj(new_center)))**.5
  38. return new_center, new_radius
  39. def translation(t):
  40. return numpy.matrix([[1.0, t], [0.0, 1.0]])
  41. def scaling(r):
  42. return numpy.matrix([[r, 0.0], [0.0, 1.0]])
  43. def conj(z):
  44. return z - 2j*z.imag
  45. def normalize(z):
  46. "Normalize homogenous coordinates so last is 1.0"
  47. a = z.item(0)
  48. b = z.item(1)
  49. if b != 0.0 + 0j:
  50. return numpy.matrix([[a/b], [1.0 + 0j]])
  51. else:
  52. return numpy.matrix([[1.0 + 0j], [0.0 + 0j]])
  53. involution = numpy.matrix([[0.0, 1.0], [1.0, 0.0]])

comments powered by Disqus