quat.lua 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. local vector=require("vector")
  2. local matrix=require("matrix")
  3. local quat={}
  4. quat.__index=quat
  5. quat.__mul=function(a,b)
  6. local q={}
  7. q[1]=a[4]*b[1]+a[1]*b[4]+a[2]*b[3]-a[3]*b[2]
  8. q[2]=a[4]*b[2]-a[1]*b[3]+a[2]*b[4]+a[3]*b[1]
  9. q[3]=a[4]*b[3]+a[1]*b[2]-a[2]*b[1]+a[3]*b[4]
  10. q[4]=a[4]*b[4]-a[1]*b[1]-a[2]*b[2]-a[3]*b[3]
  11. return setmetatable(q,quat)
  12. end
  13. quat.identity=function(self,x,y,z,w)
  14. return setmetatable({0,0,0,1},quat)
  15. end
  16. quat.new=function(self,x,y,z,w)
  17. return setmetatable({x,y,z,w},quat)
  18. end
  19. quat.rotate=function(self,v,a)
  20. local vn=v:normal()
  21. return setmetatable({vn[1]*math.sin(a/2),vn[2]*math.sin(a/2),vn[3]*math.sin(a/2),math.cos(a/2)},quat)
  22. end
  23. quat.normal=function(self)
  24. return quat:new(vector:new(unpack(self)):normal())
  25. end
  26. quat.invert=function(self)
  27. return quat:new(-self[1],-self[2],-self[3],self[4])
  28. end
  29. quat.matrix=function(self)
  30. local xx,xy,xz=self[1]*2*self[1],self[1]*2*self[2],self[1]*2*self[3]
  31. local yy,yz,zz=self[2]*2*self[2],self[2]*2*self[3],self[3]*2*self[3]
  32. local wx,wy,wz=self[4]*2*self[1],self[4]*2*self[2],self[4]*2*self[3]
  33. local m={1-(yy+zz),xy+wz,xz-wy,0,
  34. xy-wz,1-(xx+zz),yz+wx,0,
  35. xz+wy,yz-wx,1-(xx+yy),0,
  36. 0,0,0,1}
  37. return setmetatable(m,matrix)
  38. end
  39. quat.mulvect=function(a,b)
  40. local q=a*quat:new(b[1],b[2],b[3],0)*a:invert()
  41. return vector:new(q[1],q[2],q[3])
  42. end
  43. return quat