plot_rotation.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. try:
  2. from ctypes import c_float
  3. except ImportError:
  4. pass
  5. import pyglet.gl as pgl
  6. from math import sqrt as _sqrt, acos as _acos
  7. def cross(a, b):
  8. return (a[1] * b[2] - a[2] * b[1],
  9. a[2] * b[0] - a[0] * b[2],
  10. a[0] * b[1] - a[1] * b[0])
  11. def dot(a, b):
  12. return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
  13. def mag(a):
  14. return _sqrt(a[0]**2 + a[1]**2 + a[2]**2)
  15. def norm(a):
  16. m = mag(a)
  17. return (a[0] / m, a[1] / m, a[2] / m)
  18. def get_sphere_mapping(x, y, width, height):
  19. x = min([max([x, 0]), width])
  20. y = min([max([y, 0]), height])
  21. sr = _sqrt((width/2)**2 + (height/2)**2)
  22. sx = ((x - width / 2) / sr)
  23. sy = ((y - height / 2) / sr)
  24. sz = 1.0 - sx**2 - sy**2
  25. if sz > 0.0:
  26. sz = _sqrt(sz)
  27. return (sx, sy, sz)
  28. else:
  29. sz = 0
  30. return norm((sx, sy, sz))
  31. rad2deg = 180.0 / 3.141592
  32. def get_spherical_rotatation(p1, p2, width, height, theta_multiplier):
  33. v1 = get_sphere_mapping(p1[0], p1[1], width, height)
  34. v2 = get_sphere_mapping(p2[0], p2[1], width, height)
  35. d = min(max([dot(v1, v2), -1]), 1)
  36. if abs(d - 1.0) < 0.000001:
  37. return None
  38. raxis = norm( cross(v1, v2) )
  39. rtheta = theta_multiplier * rad2deg * _acos(d)
  40. pgl.glPushMatrix()
  41. pgl.glLoadIdentity()
  42. pgl.glRotatef(rtheta, *raxis)
  43. mat = (c_float*16)()
  44. pgl.glGetFloatv(pgl.GL_MODELVIEW_MATRIX, mat)
  45. pgl.glPopMatrix()
  46. return mat