transform.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. '''functions for 2D affine transformations'''
  2. __all__ = (
  3. 'nullTransform',
  4. 'translate',
  5. 'scale',
  6. 'rotate',
  7. 'skewX',
  8. 'skewY',
  9. 'mmult',
  10. 'inverse',
  11. 'zTransformPoint',
  12. 'transformPoint',
  13. 'transformPoints',
  14. 'zTransformPoints',
  15. )
  16. from math import pi, cos, sin, tan
  17. # constructors for matrices:
  18. def nullTransform():
  19. return (1, 0, 0, 1, 0, 0)
  20. def translate(dx, dy):
  21. return (1, 0, 0, 1, dx, dy)
  22. def scale(sx, sy):
  23. return (sx, 0, 0, sy, 0, 0)
  24. def rotate(angle):
  25. a = angle * pi/180
  26. return (cos(a), sin(a), -sin(a), cos(a), 0, 0)
  27. def skewX(angle):
  28. a = angle * pi/180
  29. return (1, 0, tan(a), 1, 0, 0)
  30. def skewY(angle):
  31. a = angle * pi/180
  32. return (1, tan(a), 0, 1, 0, 0)
  33. def mmult(A, B):
  34. "A postmultiplied by B"
  35. # I checked this RGB
  36. # [a0 a2 a4] [b0 b2 b4]
  37. # [a1 a3 a5] * [b1 b3 b5]
  38. # [ 1 ] [ 1 ]
  39. #
  40. return (A[0]*B[0] + A[2]*B[1],
  41. A[1]*B[0] + A[3]*B[1],
  42. A[0]*B[2] + A[2]*B[3],
  43. A[1]*B[2] + A[3]*B[3],
  44. A[0]*B[4] + A[2]*B[5] + A[4],
  45. A[1]*B[4] + A[3]*B[5] + A[5])
  46. def inverse(A):
  47. "For A affine 2D represented as 6vec return 6vec version of A**(-1)"
  48. # I checked this RGB
  49. det = float(A[0]*A[3] - A[2]*A[1])
  50. R = [A[3]/det, -A[1]/det, -A[2]/det, A[0]/det]
  51. return tuple(R+[-R[0]*A[4]-R[2]*A[5],-R[1]*A[4]-R[3]*A[5]])
  52. def zTransformPoint(A,v):
  53. "Apply the homogenous part of atransformation a to vector v --> A*v"
  54. return (A[0]*v[0]+A[2]*v[1],A[1]*v[0]+A[3]*v[1])
  55. def transformPoint(A,v):
  56. "Apply transformation a to vector v --> A*v"
  57. return (A[0]*v[0]+A[2]*v[1]+A[4],A[1]*v[0]+A[3]*v[1]+A[5])
  58. def transformPoints(matrix, V):
  59. r = [transformPoint(matrix,v) for v in V]
  60. if isinstance(V,tuple): r = tuple(r)
  61. return r
  62. def zTransformPoints(matrix, V):
  63. return list(map(lambda x,matrix=matrix: zTransformPoint(matrix,x), V))