# damn

Jul 29th, 2021
1,036
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. --By xXxMoNkEyMaNxXx elsez
2. --Roblox Lua
3. local type=type
4. local getmetatable=getmetatable
5. local setmetatable=setmetatable
6.
7. local pi=math.pi
8. local tau=2*pi
9. local sqrt=math.sqrt
10. local atan2=math.atan2
11. local exp,log=math.exp,math.log
12. local cos,sin=math.cos,math.sin
13. local acos,asin=math.acos,math.asin
14.
15. local function TYPE(x)
16.     local xMet=getmetatable(x)
17.     if type(xMet)=="table" and xMet.__type~=nil then
18.         return xMet.__type
19.     else
20.         return type(x)
21.     end
22. end
23.
24. local Q={}
25. local metatable={__type="quaternion"}
26. local alt={"w","x","y","z"}
27. function metatable.__index(q,i)
28.     return q[alt[i]]
29. end
30. local function new(w,x,y,z)
31.     return setmetatable({w=w or 1,x=x or 0,y=y or 0,z=z or 0},metatable)
32. end
33. Q.new=new
34. local function inv(q)
35.     local w,x,y,z=q.w,q.x,q.y,q.z
36.     local m=w*w+x*x+y*y+z*z
37.     if m>0 then
38.         return new(w/m,-x/m,-y/m,-z/m)
39.     else
40.         return new(0)
41.     end
42. end
43. Q.inv=inv
44.
45. --Unary minus; -q
46. local function unm(q)
47.     return new(-q.w,-q.x,-q.y,-q.z)
48. end
49. metatable.__unm=unm
50. Q.unm=unm
52.     local t0,t1=TYPE(q0),TYPE(q1)
53.     if t0=="quaternion" and t1=="quaternion" then
54.         return new(q0.w+q1.w,q0.x+q1.x,q0.y+q1.y,q0.z+q1.z)
55.     elseif t0=="quaternion" and t1=="number" then
56.         return new(q0.w+q1,q0.x,q0.y,q0.z)
57.     elseif t0=="number" and t1=="quaternion" then
58.         return new(q0+q1.w,q1.x,q1.y,q1.z)
59.     end
60. end
63. local function sub(q0,q1)
64.     local t0,t1=TYPE(q0),TYPE(q1)
65.     if t0=="quaternion" and t1=="quaternion" then
66.         return new(q0.w-q1.w,q0.x-q1.x,q0.y-q1.y,q0.z-q1.z)
67.     elseif t0=="quaternion" and t1=="number" then
68.         return new(q0.w-q1,q0.x,q0.y,q0.z)
69.     elseif t0=="number" and t1=="quaternion" then
70.         return new(q0-q1.w,-q1.x,-q1.y,-q1.z)
71.     end
72. end
73. metatable.__sub=sub
74. Q.sub=sub
75. local function mul(q0,q1)
76.     local t0,t1=TYPE(q0),TYPE(q1)
77.     if t0=="quaternion" and t1=="quaternion" then
78.         local w0,x0,y0,z0,w1,x1,y1,z1=q0.w,q0.x,q0.y,q0.z,q1.w,q1.x,q1.y,q1.z
79.         return new(w0*w1-x0*x1-y0*y1-z0*z1,w0*x1+x0*w1+y0*z1-z0*y1,w0*y1-x0*z1+y0*w1+z0*x1,w0*z1+x0*y1-y0*x1+z0*w1)
80.     elseif t0=="quaternion" and t1=="number" then
81.         return new(q0.w*q1,q0.x*q1,q0.y*q1,q0.z*q1)
82.     elseif t0=="number" and t1=="quaternion" then
83.         return new(q0*q1.w,q0*q1.x,q0*q1.y,q0*q1.z)
84.     end
85. end
86. metatable.__mul=mul
87. Q.mul=mul
88. local function div(q0,q1)
89.     local t0,t1=TYPE(q0),TYPE(q1)
90.     if t0=="quaternion" and t1=="quaternion" then
91.         local w0,x0,y0,z0,w1,x1,y1,z1=q0.w,q0.x,q0.y,q0.z,q1.w,q1.x,q1.y,q1.z
92.         local m1=w1*w1+x1*x1+y1*y1+z1*z1
93.         if m1>0 then--This is the quaternion that gets you from q1 to q0 from q1: mul(inv(q1),q0).  (quaternion division is actually ambiguous)
94.             return new((w1*w0+x1*x0+y1*y0+z1*z0)/m1,(w1*x0-x1*w0-y1*z0+z1*y0)/m1,(w1*y0+x1*z0-y1*w0-z1*x0)/m1,(w1*z0-x1*y0+y1*x0-z1*w0)/m1)
95.         else
96.             return new(0)
97.         end
98.     elseif t0=="quaternion" and t1=="number" then
99.         return new(q0.w/q1,q0.x/q1,q0.y/q1,q0.z/q1)
100.     elseif t0=="number" and t1=="quaternion" then
101.         local w1,x1,y1,z1=q1.w,q1.x,q1.y,q1.z
102.         local m1=w1*w1+x1*x1+y1*y1+z1*z1
103.         if m1>0 then
104.             local m=q0/m1
105.             return new(m*w1,-m*x1,-m*y1,-m*z1)
106.         else
107.             return new(0)
108.         end
109.     end
110. end
111. metatable.__div=div
112. Q.div=div
113. local function pow(q0,q1)
114.     local t0,t1=TYPE(q0),TYPE(q1)
115.     if t0=="quaternion" and t1=="quaternion" then
116.         local w0,x0,y0,z0=q0.w,q0.x,q0.y,q0.z
117.         local vv=x0*x0+y0*y0+z0*z0
118.         local mm=w0*w0+vv
119.         if mm>0 then
120.             if vv>0 then
121.                 local m=sqrt(mm)
122.                 local s=acos(w0/m)/sqrt(vv)
123.                 w0,x0,y0,z0=log(m),x0*s,y0*s,z0*s
124.             else
125.                 w0,x0,y0,z0=0.5*log(mm),0,0,0
126.             end
127.         else
128.             w0,x0,y0,z0=-math.huge,0,0,0
129.         end
130.         local w1,x1,y1,z1=q1.w,q1.x,q1.y,q1.z
131.         local m=exp(w0*w1-x0*x1-y0*y1-z0*z1)
132.         local x,y,z=w0*x1+x0*w1+y0*z1-z0*y1,w0*y1-x0*z1+y0*w1+z0*x1,w0*z1+x0*y1-y0*x1+z0*w1
133.         local vv=x*x+y*y+z*z
134.         if vv>0 then
135.             local v=sqrt(vv)
136.             local s=m*sin(v)/v
137.             return new(m*cos(v),x*s,y*s,z*s)
138.         else
139.             return new(m)
140.         end
141.     elseif t0=="quaternion" and t1=="number" then
142.         local w,x,y,z=q0.w,q0.x,q0.y,q0.z
143.         local vv=x*x+y*y+z*z
144.         if vv>0 then
145.             local v=sqrt(vv)
146.             local m=(w*w+vv)^(0.5*q1)
147.             local theta=q1*atan2(v,w)
148.             local s=m*sin(theta)/v
149.             return new(m*cos(theta),x*s,y*s,z*s)
150.         else
151.             if w<0 then
152.                 local m=(-w)^q1
153.                 local s=m*sin(pi*q1)*0.57735026918962576450914878050196--3^-0.5
154.                 return new(m*cos(pi*q1),s,s,s)
155.             else
156.                 return new(w^q1)
157.             end
158.         end
159.     elseif t0=="number" and t1=="quaternion" then
160.         local w,x,y,z=q1.w,q1.x,q1.y,q1.z
161.         if q0>0 then
162.             local m=q0^w
163.             local vv=x*x+y*y+z*z
164.             if vv>0 then
165.                 local v=sqrt(vv)
166.                 local s=m*sin(v)/v
167.                 return new(m*cos(v),x*s,y*s,z*s)
168.             else
169.                 return new(m)
170.             end
171.         elseif q0<0 then--Not a good idea to use this.
172.             local m=(-q0)^w
173.             local mc,ms=m*cos(pi*w),m*sin(pi*w)
174.             local vv=x*x+y*y+z*z
175.             if vv>0 then
176.                 local v=sqrt(vv)
177.                 local c,s=cos(v),sin(v)/v
178.                 local vc,vs=mc*s,ms*c*0.57735026918962576450914878050196
179.                 return new(mc*c-ms*s,vc*x+vs,vc*y+vs,vc*z+vs)--This is probably TERRIBLY wrong, but raising a negative number to the power of a quaternion is ill-defined in the first place.
180.             else
181.                 return new(c,s,s,s)
182.             end
183.         elseif w*w+x*x+y*y+z*z>0 then
184.             return new(0)
185.         else
186.             return new()--anyeting to da powa of 0 is 1 dud
187.         end
188.     end
189. end
190. metatable.__pow=pow
191. Q.pow=pow
192. local function length(q)
193.     local w,x,y,z=q.w,q.x,q.y,q.z
194.     return sqrt(w*w+x*x+y*y+z*z)
195. end
196. metatable.__len=length
197. Q.length=length
198. Q.magnitude=length
199. local function Qtostring(q,precision)
200.     precision=precision or 3
201.     return (", %."..precision.."f"):rep(4):sub(3):format(q.w,q.x,q.y,q.z)
202. end
203. metatable.__tostring=Qtostring
204. Q.tostring=Qtostring
205.
206. local function Qlog(q)
207.     local w,x,y,z=q.w,q.x,q.y,q.z
208.     local vv=x*x+y*y+z*z
209.     local mm=w*w+vv
210.     if mm>0 then
211.         if vv>0 then
212.             local m=sqrt(mm)
213.             local s=acos(w/m)/sqrt(vv)
214.             return new(log(m),x*s,y*s,z*s)
215.         else
216.             return new(0.5*log(mm))--lim v->0 x/v*acos(a/sqrt(a*a+v*v))=0 when a is positive
217.         end
218.     else
219.         return new(-math.huge)
220.     end
221. end
222. Q.log=Qlog
223.
224. local function Qexp(q)
225.     local m=exp(q.w)
226.     local x,y,z=q.x,q.y,q.z
227.     local vv=x*x+y*y+z*z
228.     if vv>0 then
229.         local v=sqrt(vv)
230.         local s=m*sin(v)/v
231.         return new(m*cos(v),x*s,y*s,z*s)
232.     else
233.         return new(m)
234.     end
235. end
236. Q.exp=Qexp
237.
238. local function Qnormalize(q)
239.     local w,x,y,z=q.w,q.x,q.y,q.z
240.     local mm=w*w+x*x+y*y+z*z
241.     if mm>0 then
242.         local m=sqrt(mm)
243.         return new(w/m,x/m,y/m,z/m)
244.     else
245.         return new()
246.     end
247. end
248. Q.normalize=Qnormalize
249. Q.unit=Qnormalize
250.
251. return Q
252.
RAW Paste Data