November 25, 2020, 05:33:00 AM

### Author Topic: [bmx] BMax Math Lib v3.0 by Chroma [ 1+ years ago ]  (Read 595 times)

#### BlitzBot

• Jr. Member
• Posts: 1
##### [bmx] BMax Math Lib v3.0 by Chroma [ 1+ years ago ]
« on: June 29, 2017, 12:28:39 AM »
Title : BMax Math Lib v3.0
Author : Chroma
Posted : 1+ years ago

Description : This math lib is a drastic speed increase over previous libs.  I've done extensive speed testing in massive loops and went with the fastest method every time.  Creating and returning a local type inside a method is very inefficient and slow.  I gained about a 60-100% speed increase by eliminating it.  Give this math lib a shot, you'll notice the difference.

Updating Matrix soon and throwing in some other advanced functions for good measure.

Please post any errors or bugs.

Fixed 2 errors.  Thanks for pointing em out.

Code :
Code: BlitzMax
1. ' BMax Math Lib v3.0
2. ' by Chroma
3.
4.
5. ' Internal Math Vars - Do Not Alter
6. Const Tol:Float = 0.0001
7. Global vTmp:TVector3 = New TVector3
8. Global qTmp:TQuaternion = New TQuaternion
9.
10.
11. '       ----------
12. '       ----------
13. '       ----------
14.
15.
16. ' Vector Class
17.
18. Type TVector3
19.
20.         Field x:Double, y:Double, z:Double
21.
22. '       ----------
23.
24.         'Example1: v1:TVector3 = TVector3.Create(1,2,3)
25.         Function Create:TVector3(x:Double = 0, y:Double = 0, z:Double = 0)
26.                 Local v:TVector3 = New TVector3
27.                 v.x = x
28.                 v.y = y
29.                 v.z = z
30.                 Return v
31.         End Function
32.
33.         'Example1: v.Set(1,2,3)
34.         Method Set(x:Double = 0, y:Double = 0, z:Double = 0)
35.                 self.x = x
36.                 self.y = y
37.                 self.z = z
38.         End Method
39.
40. '       ----------
41.
42.         'Example: v1 = v1 + v2 is written v1.Add( v1, v2 )
43.         Method Add(a:TVector3, b:TVector3)
44.                 self.x = a.x + b.x
45.                 self.y = a.y + b.y
46.                 self.z = a.z + b.z
47.         End Method
48.
49.         'Example: v1 = v2 + 5 is written v1.AddScalar( v2, 5 )
50.         Method AddScalar(a:TVector3, s:Double)
51.                 self.x = a.x + s
52.                 self.y = a.y + s
53.                 self.z = a.z + s
54.         End Method
55.
56. '       ----------
57.
58.         'Example: v1 = v2 - v3 is written v1.Sub( v2, v3 )
59.         Method Sub(a:TVector3, b:TVector3)
60.                 self.x = a.x - b.x
61.                 self.y = a.y - b.y
62.                 self.z = a.z - b.z
63.         End Method
64.
65.         'Example: v1 = v2 - 5 is written v1.SubScalar( v2, 5 )
66.         Method SubScalar(a:TVector3, s:Double)
67.                 self.x = a.x - s
68.                 self.y = a.y - s
69.                 self.z = a.z - s
70.         End Method
71.
72. '       ----------
73.
74.         'Example: v1 = v2 * v3 is written v1.Mul( v2, v3 )
75.         Method Mul(a:TVector3, b:TVector3)
76.                 self.x = a.x * b.x
77.                 self.y = a.y * b.y
78.                 self.z = a.z * b.z
79.         End Method
80.
81.         'Example: v1 = v2 * 5 is written v1.MulScalar( v2, 5 )
82.         Method MulScalar(a:TVector3, s:Double)
83.                 self.x = a.x * s
84.                 self.y = a.y * s
85.                 self.z = a.z * s
86.         End Method
87.
88. '       ----------
89.
90.         'Example: v1 = v2 / v3 is written v1.Div( v2, v3 )
91.         Method Div(a:TVector3, b:TVector3)
92.                 self.x = a.x / b.x
93.                 self.y = a.y / b.y
94.                 self.z = a.z / b.z
95.         End Method
96.
97.         'Example: v1 = v2 / 5 is written v1.DivScalar( v2, 5 )
98.         Method DivScalar(a:TVector3, s:Double)
99.                 self.x = a.x / s
100.                 self.y = a.y / s
101.                 self.z = a.z / s
102.         End Method
103.
104. '       ----------
105.
106.         'Example: mag:Double = v.Magnitude()
107.         Method Magnitude:Double()
108.                 Return Sqr(self.x * self.x + self.y * self.y + self.z * self.z)
109.         End Method
110.
111.         'Example: v.Normalize()
112.         Method Normalize()
113.                 Local mag:Double = self.Magnitude()
114.                 self.x :/ mag
115.                 self.y :/ mag
116.                 self.z :/ mag
117.                 If Abs(self.x) < Tol self.x = 0
118.                 If Abs(self.y) < Tol self.y = 0
119.                 If Abs(self.z) < Tol self.z = 0
120.         End Method
121.
122. '       ----------
123.
124.         'Example: v1 = v2 ^ v3 is written v1.CrossProduct( v2, v3 )
125.         Method CrossProduct(a:TVector3, b:TVector3)
126.                 self.x =  a.y * b.z - a.z * b.y
127.                 self.y = -a.x * b.z + a.z * b.x
128.                 self.z =  a.x * b.y - a.y * b.x
129.         EndMethod
130.
131.         'Example1: dotp:double = v1.DotProduct( v2 )
132.         Method DotProduct:Double( a:TVector3 )
133.                 Return self.x * a.x + self.y * a.y + self.z * a.z
134.         End Method
135.
136. '       ----------
137.
138.         'Returns Inverse Instance of a Vector
139.         Method Inverse:TVector3()
140.                 vTmp.x = -self.x
141.                 vTmp.y = -self.y
142.                 vTmp.z = -self.z
143.                 Return vTmp
144.         End Method
145.
146.         ' Example: v.GetVecFromQuat( q )
147.         Method GetVecFromQuat(a:TQuaternion)
148.                 self.x = a.x
149.                 self.y = a.y
150.                 self.z = a.z
151.         End Method
152.
153.         'Example: v.MakeEulerFromQuat( q )
154.         Method MakeEulerFromQuat(q:TQuaternion)
155.                 Local   r11#, r21#, r31#, r32#, r33#, r12#, r13#
156.                 Local   q00#, q11#, q22#, q33#
157.                 Local   tmp#
158.
159.                 q00 = q.n * q.n
160.                 q11 = q.x * q.x
161.                 q22 = q.y * q.y
162.                 q33 = q.z * q.z
163.
164.                 r11 = q00 + q11 - q22 - q33
165.                 r21 = 2 * (q.x*q.y + q.n*q.z)
166.                 r31 = 2 * (q.x*q.z - q.n*q.y)
167.                 r32 = 2 * (q.y*q.z + q.n*q.x)
168.                 r33 = q00 - q11 - q22 + q33
169.
170.                 tmp = Abs(r31)
171.                 If (tmp > 0.999999)
172.                         r12 = 2 * (q.x*q.y - q.n*q.z)
173.                         r13 = 2 * (q.x*q.z + q.n*q.y)
174.
175.                         self.x = RadiansToDegrees(0.0)                                                  ' roll
176.                         self.y = RadiansToDegrees( Float (-(Pi/2) * r31/tmp))   ' pitch
177.                         self.z = RadiansToDegrees( Float ATan2(-r12, -r31*r13))' yaw
178.                 Else
179.                         self.x = RadiansToDegrees( Float ATan2(r32, r33))               ' roll
180.                         self.y = RadiansToDegrees( Float ASin(-r31))                    ' pitch
181.                         self.z = RadiansToDegrees( Float ATan2(r21, r11))               ' yaw
182.                 EndIf
183.         End Method
184.
185. '       ----------
186.
187.         'Example: vPos.AddTimeStep( vVel, dt )
188.         Method AddTimeStep(a:TVector3, timestep:Float)
189.                 self.x :+ a.x * timestep
190.                 self.y :+ a.y * timestep
191.                 self.z :+ a.z * timestep
192.         End Method
193.
194.         'Example: vVel.AddGravity(  , dt )
195.         Method AddGravity(g:Float = 9.8, timestep:Float)
196.                 self.y :- g * timestep
197.         End Method
198.
199.         'Example1: v.Show("v",5,5)
200.         Method Show(cap:String, xpos:Int, ypos:Int, spc:Int = 12)
201.                 DrawText cap + "_x:" + self.x,xpos,ypos
202.                 DrawText cap + "_y:" + self.y,xpos,ypos + spc
203.                 DrawText cap + "_z:" + self.z,xpos,ypos + spc * 2
204.         End Method
205.
206. End Type
207.
208.
209. '       ----------
210. '       ----------
211. '       ----------
212.
213.
214. ' Quaternion Class
215.
216. Type TQuaternion
217.
218.         Field n:Double, x:Double, y:Double, z:Double
219.
220. '       ----------
221.
222.         Function Create:TQuaternion(n:Double = 1.0, x:Double = 0, y:Double = 0, z:Double = 0)
223.                 Local q:TQuaternion = New TQuaternion
224.                 q.n = n
225.                 q.x = x
226.                 q.y = y
227.                 q.z = z
228.                 Return q
229.         End Function
230.
231. '       ----------
232.
233.         ' Example: q1=q2+q3 would be q1.Add( q2, q3 )
234.         Method Add(a:TQuaternion, b:TQuaternion)
235.                 self.n = a.n + b.n
236.                 self.x = a.x + b.x
237.                 self.y = a.y + b.y
238.                 self.z = a.z + b.z
239.         End Method
240.
241. '       ----------
242.
243.         ' Example: q1=q2-q3 would be q1.Sub( q2, q3 )
244.         Method Sub(a:TQuaternion, b:TQuaternion)
245.                 self.n = a.n - b.n
246.                 self.x = a.x - b.x
247.                 self.y = a.y - b.y
248.                 self.z = a.z - b.z
249.         End Method
250.
251. '       ----------
252.
253.         ' Example: q1=q2*q3 would be q1.Mul( q2, q3 )
254.         Method Mul(a:TQuaternion, b:TQuaternion)
255.                 self.n = a.n * b.n - a.x * b.x - a.y * b.y - a.z * b.z
256.                 self.x = a.n * b.x + a.x * b.n + a.y * b.z - a.z * b.y
257.                 self.y = a.n * b.y + a.y * b.n + a.z * b.x - a.x * b.z
258.                 self.z = a.n * b.y + a.y * b.n + a.z * b.x - a.x * b.z
259.         End Method
260.
261.         ' Example: q1=q2*2 would be q1.MulScalar( q2, 2 )
262.         Method MulScalar( a:TQuaternion, s:Double )
263.                 self.n = a.n * s
264.                 self.x = a.x * s
265.                 self.y = a.y * s
266.                 self.z = a.z * s
267.         End Method
268.
269. '       ----------
270.
271.         ' Example: q1=q2/2 would be q1.DivS( q2, 2 )
272.         Method DivScalar(a:TQuaternion, s:Double )
273.                 self.n = a.n / s
274.                 self.x = a.x / s
275.                 self.y = a.y / s
276.                 self.z = a.z / s
277.         End Method
278.
279. '       ----------
280.
281.         ' Example: Local qmag:Double = q.Magnitude()
282.         Method Magnitude:Double( a:TQuaternion )
283.                 Return Sqr( a.n * a.n + a.x * a.x + a.y * a.y + a.z * a.z )
284.         End Method
285.
286. '       ----------
287.
288.         'Returns Inverse Instance of a Quaternion
289.         Method Inverse:TQuaternion()
290.                 qTmp.n =  self.n
291.                 qTmp.x = -self.x
292.                 qTmp.y = -self.y
293.                 qTmp.z = -self.z
294.                 Return qTmp
295.         End Method
296.
297. '       ----------
298.
299.         'Example: q.MakeQuatFromEuler( pitch, yaw, roll )
300.         Method MakeQuatFromEuler(x:Float, y:Float, z:Float)
301.                 Local roll:Float = DegreesToRadians(x)
302.                 Local pitch:Float = DegreesToRadians(y)
303.                 Local yaw:Float = DegreesToRadians(z)
304.
305.                 Local cyaw#, cpitch#, croll#, syaw#, spitch#, sroll#
306.                 Local cyawcpitch#, syawspitch#, cyawspitch#, syawcpitch#
307.
308.                 cyaw = Cos(0.5 * yaw)
309.                 cpitch = Cos(0.5 * pitch)
310.                 croll = Cos(0.5 * roll)
311.                 syaw = Sin(0.5 * yaw)
312.                 spitch = Sin(0.5 * pitch)
313.                 sroll = Sin(0.5 * roll)
314.
315.                 cyawcpitch = cyaw*cpitch
316.                 syawspitch = syaw*spitch
317.                 cyawspitch = cyaw*spitch
318.                 syawcpitch = syaw*cpitch
319.
320.                 self.n = Float (cyawcpitch * croll + syawspitch * sroll)
321.                 self.x = Float (cyawcpitch * sroll - syawspitch * croll)
322.                 self.y = Float (cyawspitch * croll + syawcpitch * sroll)
323.                 self.z = Float (syawcpitch * croll - cyawspitch * sroll)
324.         End Method
325.
326. '       ----------
327.
328.
329.         Method Show(cap:String = "", xpos:Int, ypos:Int, spc:Int = 12)
330.                 DrawText cap + "_w:" + self.n,xpos,ypos
331.                 DrawText cap + "_x:" + self.x,xpos,ypos + spc
332.                 DrawText cap + "_y:" + self.y,xpos,ypos + spc * 2
333.                 DrawText cap + "_z:" + self.z,xpos,ypos + spc * 3
334.         End Method
335.
336. End Type
337.
338.
339.
340. '       ----------
341. '       ----------
342. '       ----------
343.
344. ' Matrix Class
345.
346. Type TMatrix
347.
348.         Field e11:Double, e12:Double, e13:Double
349.         Field e21:Double, e22:Double, e23:Double
350.         Field e31:Double, e32:Double, e33:Double
351.
352. '       ----------
353.
354.         Function Create:TMatrix(e11!=0, e12!=0, e13!=0, e21!=0, e22!=0, e23!=0, e31!=0, e32!=0, e33!=0)
355.                 Local m:TMatrix = New TMatrix
356.                 m.e11 = e11
357.                 m.e12 = e12
358.                 m.e13 = e13
359.                 m.e21 = e21
360.                 m.e22 = e22
361.                 m.e23 = e23
362.                 m.e31 = e31
363.                 m.e32 = e32
364.                 m.e33 = e33
365.                 Return m
366.         End Function
367.
368. '       ----------
369.
370.
371. '       ----------
372.
373.
374. End Type
375.
376.
377. '       ----------
378. '       ----------
379. '       ----------
380.
381.
382. ' Degrees To Radians Conversion
383. Function DegreesToRadians:Float(deg:Float)
384.         Return deg * Pi / 180.0
385. End Function
386.
387. ' Radians To Degrees Conversion
388. Function RadiansToDegrees:Float(rad:Float)
389.         Return rad * 180.0 / Pi
390. End Function

Comments :

DaMaul(Posted 1+ years ago)

Hi, this is great :)But could you delete the old version as I managed to discover that before this!

DaMaul(Posted 1+ years ago)

By the way, I believe there's a couple of small errors in this. This line:Function Create:TQuaternion(w:Double = 1.0, x:Double = 0, y:Double = 0, z:Double = 0)Should be:Function Create:TQuaternion(n:Double = 1.0, x:Double = 0, y:Double = 0, z:Double = 0)And also the line ( in the method "AddGravity" ):self.y :- g * time_stepShould be:self.y :- g * timestepCheers!

bradford6(Posted 1+ years ago)

very nice. Question: Would using Floats instead of Doubles increase speed?

DJWoodgate(Posted 1+ years ago)

Yes, but not by much.

SimplePortal 2.3.6 © 2008-2014, SimplePortal