November 28, 2020, 11:11:04 AM

Author Topic: [bb] Vector 3D Math Library [v1.7] by Chroma [ 1+ years ago ]  (Read 1328 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : Vector 3D Math Library [v1.7]
Author : Chroma
Posted : 1+ years ago

Description : Here's my conversion of the Vector3D functions from C++. I originally posted this in the archives over 2 years ago.  I've recently perused the code and made some improvements.  Hopefully you'll find this immensely useful because I know I have.  Have fun!

-Last Updated on November 30, 2004

v1.0 initial release Sept 15, 2002
v1.1 fixed errors in crossproduct Sept 17, 2002
v1.2 cleaned up some functions July 15, 2004
v1.3 most functions return vectors now! July 22,2004
v1.4 added function AddVectorTimeStep for easier physics use - July 23, 2004
v1.5 vTmp was not a good idea for internal calcs - caused vector bleeding - fixed! - July 23, 2004
v1.6 changed ReverseVector to use 2 vectors for ease of use
v1.7 renamed and rearranged the code slightly


Code :
Code: BlitzBasic
  1. ;// Vector Math Library v1.7
  2. ;// by Chroma
  3.  
  4. ;// Last Update: November 30, 2004
  5. ;// Comments: Renamed and rearranged the code slightly
  6.  
  7.  
  8. ;----------------------------------------------------------------------;
  9. ;// Testing...
  10. ;// Remove ";--" in front of lines to see the Vectory Library test demo
  11. ;--Graphics 400,300,16,2
  12. ;--SetBuffer BackBuffer()
  13. ;--AppTitle "Vector 3D Math Library v1.7 - Vector Addition Test"
  14.  
  15. ;// Create two test vectors
  16. ;--this.Vector = Vector()
  17. ;--that.Vector = Vector(1,2,3)
  18.  
  19. ;// Loop
  20. ;--While Not KeyHit(1)
  21. ;--Cls
  22.  
  23. ;--Vector_Add(this,this,that)
  24. ;--Vector_Show(this,10,10,"Test")
  25.  
  26. ;--Flip
  27. ;--Wend
  28. ;--End
  29. ;//...End Test
  30. ;----------------------------------------------------------------------;
  31.  
  32.  
  33. ;// Tolerance
  34. Const tol# = 0.001
  35.  
  36.  
  37. ;// Vector Type
  38. Type Vector
  39.         Field x#
  40.         Field y#
  41.         Field z#
  42. End Type
  43.  
  44.  
  45. ;// Create a Vector
  46. ;// Example: this.Vector = Vector()
  47. ;// Example: this.Vector = Vector(1,2,3)
  48. Function Vector.Vector(x#=0,y#=0,z#=0)
  49.         v.Vector = New Vector
  50.         vx=x
  51.         vy=y
  52.         vz=z
  53.         Return v
  54. End Function
  55.  
  56.  
  57. ;// Set a Vector with New Components
  58. Function Vector_Set(v.Vector,x#,y#,z#)
  59.         vx = x
  60.         vy = y
  61.         vz = z
  62. End Function
  63.  
  64.  
  65. ;// Vector Component Set
  66. ;// Example 1: Vector_SetX(this.Vector,1.0)
  67. ;// Example 2: thisx = 1.0
  68. Function Vector_SetX(v.Vector,x#)
  69.         vx = x
  70. End Function
  71.  
  72. Function Vector_SetY(v.Vector,y#)
  73.         vy = y
  74. End Function
  75.  
  76. Function Vector_SetZ(v.Vector,z#)
  77.         vz = z
  78. End Function
  79.  
  80.  
  81. ;// Vector Component Retrieval
  82. ;// Example 1: myvar# = Vector_GetX(this.Vector)
  83. ;// Example 2: myvar# = thisx
  84. Function Vector_GetX#(v.Vector)
  85.         Return vx
  86. End Function
  87.  
  88. Function Vector_GetY#(v.Vector)
  89.         Return vy
  90. End Function
  91.  
  92. Function Vector_GetZ#(v.Vector)
  93.         Return vz
  94. End Function
  95.  
  96.  
  97. ;// Vector Addition
  98. ;// Form of: Vector1 = Vector2 + Vector3
  99. Function Vector_Add(v1.Vector,v2.Vector,v3.Vector)
  100.         v1x = v2x + v3x
  101.         v1y = v2y + v3y
  102.         v1z = v2z + v3z
  103. End Function
  104.  
  105.  
  106. ;// Vector Scalar Addition
  107. ;// Form of: Vector1 = Vector2 + Scalar#
  108. Function Vector_AddScalar(v1.Vector,v2.Vector,s#)
  109.         v1x = v2x + s
  110.         v1y = v2y + s
  111.         v1z = v2z + s
  112. End Function
  113.  
  114.  
  115. ;// Vector Addition * Time Step
  116. ;// Form of: Vector1 = Vector1 + Vector2 * Time_Step#
  117. Function Vector_AddTimeStep(v1.Vector,v2.Vector,time_step#)
  118.         v1x = v1x + v2x * time_step
  119.         v1y = v1y + v2y * time_step
  120.         v1z = v1z + v2z * time_step
  121. End Function
  122.  
  123.  
  124. ;// Vector Subtraction
  125. ;// Form of: Vector1 = Vector2 - Vector3
  126. Function Vector_Subtract(v1.Vector,v2.Vector,v3.Vector)
  127.         v1x = v2x - v3x
  128.         v1y = v2y - v3y
  129.         v1z = v2z - v3z
  130. End Function
  131.  
  132.  
  133. ;// Vector Scalar Subtraction
  134. ;// Form of: Vector1 = Vector2 - Scalar#
  135. Function Vector_SubtractScalar.Vector(v1.Vector,v2.Vector,s#)
  136.         v1x = v2x - s
  137.         v1y = v2y - s
  138.         v1z = v2z - s
  139. End Function
  140.  
  141.  
  142. ;// Vector Scalar Multiplication
  143. ;// Form of: Vector1 = Vector2 * Scalar#
  144. Function Vector_MultiplyScalar(v1.Vector,v2.Vector,s#)
  145.         v1x = v2x * s
  146.         v1y = v2y * s
  147.         v1z = v2z * s
  148. End Function
  149.  
  150.  
  151. ;// Vector Scalar Division
  152. ;// Form of: Vector1 = Vector1 / Scalar#
  153. Function Vector_DivideScalar(v1.Vector,v2.Vector,s#)
  154.         v1x = v2x / s
  155.         v1y = v2y / s
  156.         v1z = v2z / s
  157. End Function
  158.  
  159.  
  160. ;// Cross Product
  161. ;// Form of: Vector1 = U.Vector |CrossProduct| V.Vector
  162. Function Vector_CrossProduct(v1.Vector,u.Vector,v.Vector)
  163.         v1x =  uy * vz  -  uz * vy
  164.         v1y = -ux * vz  +  uz * vx
  165.         v1z =  ux * vy  -  uy * vx
  166. End Function
  167.  
  168.  
  169. ;// Dot Product
  170. Function Vector_DotProduct#(u.Vector,v.Vector)
  171.         Return ux * vx + uy * vy + uz * vz
  172. End Function
  173.  
  174.  
  175. ;// Magnitude
  176. ;// Example: this_magnitude# = Vector_Magnitude(this.Vector)
  177. Function Vector_Magnitude#(v.Vector)
  178.         Return Sqr(vx * vx + vy * vy + vz * vz)
  179. End Function
  180.  
  181.  
  182. ;// Normalize
  183. ;// Example: Vector_Normalize(this.Vector)
  184. Function Vector_Normalize(v.Vector)
  185.         mag#=Sqr(vx * vx + vy * vy + vz * vz)
  186.         vx = vx / mag
  187.         vy = vy / mag
  188.         vz = vz / mag
  189.         If (Abs(vx) < tol) vx = 0.0
  190.         If (Abs(vy) < tol) vy = 0.0
  191.         If (Abs(vz) < tol) vz = 0.0
  192. End Function
  193.  
  194.  
  195. ;// Reverse a Vector
  196. ;// Form of: Vector1 = -Vector2
  197. ;// Example: Vector_Reverse(this.Vector,that.Vector)
  198. Function Vector_Reverse(v1.Vector,v2.Vector)
  199.         v1x = -v2x
  200.         v1y = -v2y
  201.         v1z = -v2z
  202. End Function
  203.  
  204.  
  205. ;// Reset a Vector to Zero
  206. ;// Example: Vector_Reset(this.Vector)
  207. Function Vector_Reset(v.Vector)
  208.         vx = 0.0
  209.         vy = 0.0
  210.         vz = 0.0
  211. End Function
  212.  
  213.  
  214. ;// Vector 1 is set to Vector 2
  215. ;// Example 1: Vector_Clone(this.Vector,that.Vector)
  216. ;// Example 2: this.Vector = that.Vector
  217. Function Vector_Clone(v1.Vector,v2.Vector)
  218.         v1x = v2x
  219.         v1y = v2y
  220.         v1z = v2z
  221. End Function
  222.  
  223.  
  224. ;// Free a Vector
  225. ;// Example: Vector_Free(this.Vector)
  226. Function Vector_Free(v.Vector)
  227.         Delete v
  228. End Function
  229.  
  230.  
  231. ;// PositionEntity Replacement for Vector Object
  232. ;// Example: Vector_PositionEntity MyEntity,v.vector
  233. Function Vector_PositionEntity(ent,v.vector)
  234.         PositionEntity ent,vx,vy,vz
  235. End Function
  236.  
  237.  
  238. ;// Show Vector Values
  239. ;// Place This Function After Renderworld
  240. ;// Example: Vector_Show(this.Vector,15,15,"Test")
  241. Function Vector_Show(v.Vector,xpos,ypos,label$)
  242.         Text xpos,ypos, label$ + "_X=" + vx
  243.         Text xpos,ypos + 15,label$ + "_Y=" + vy
  244.         Text xpos,ypos + 30,label$ + "_Z=" + vz
  245. End Function
  246.  
  247.  
  248. ;// Degrees To Radians Conversion
  249. Function DegreesToRadians#(deg#)
  250.         Return deg * Pi / 180.0
  251. End Function
  252.  
  253.  
  254. ;// Radians To Degrees Conversion
  255. Function RadiansToDegrees#(rad#)
  256.         Return rad * 180.0 / Pi
  257. End Function


Comments :


LarsG(Posted 1+ years ago)

 Hey Chroma..I enhanced your code a little bit.. I hope you don't mind?!
Code: [Select]
Strict
'// Vector Math Library v0.9
'// by Chroma
'// rewritten, extended and OOP'ified for use in BlitzMax by LarsG

'// Last Update: June 23, 2005
'// Comments: Enhanced and OOP'ified by LarsG


'----------------------------------------------------------------------;
'// Testing...

Global vec1:TVectorF
Global vec2:TVectorF

'// Create two test vectors
vec1 = TVectorF.Create(1,2,3)
vec2 = TVectorF.Create()
Print "Vec1: "
Print vec1.show(", ")
Print "vec2 cloning vec1..."
vec2.clone(vec1)
Print "Vec2: "
Print vec2.show(", ")
Print "Adding vec2 to vec1..."
vec1.add(vec2)
Print "Vec1: "
Print vec1.Show(", ")
End
'//...End Test
'----------------------------------------------------------------------;


'// Vector Type Float (32 Bit)
Type TVectorF
Field x:Float
Field y:Float
Field z:Float

Const TOL:Float = 0.001

'**** THE METHODS *****
Function Create:TVectorF(x:Float=0, y:Float=0, z:Float=0)
Local v:TVectorF = New TVectorF
v.x = x
v.y = y
v.z = z
Return v
EndFunction

Method Set(x:Float, y:Float, z:Float)
self.x = x
self.y = y
self.z = z
EndMethod

Method SetX(x:Float)
self.x = x
EndMethod

Method SetY(y:Float)
self.y = y
EndMethod

Method SetZ(z:Float)
self.z = z
EndMethod

Method GetX:Float()
Return self.x
EndMethod

Method GetY:Float()
Return self.y
EndMethod

Method GetZ:Float()
Return self.z
EndMethod

Method Add(plus:TVectorF)
self.x :+ plus.x
self.y :+ plus.y
self.z :+ plus.z
EndMethod

Method AddScalar(scale:Float)
self.x :+ scale
self.y :+ scale
self.z :+ scale
EndMethod

Method AddTimeStep(plus:TVectorF, tstep:Float)
self.x :+ (plus.x * tstep)
self.y :+ (plus.y * tstep)
self.z :+ (plus.z * tstep)
EndMethod

Method Subtract(sub:TVectorF)
self.x :- sub.x
self.y :- sub.y
self.z :- sub.z
EndMethod

Method SubtractScalar(scale:Float)
self.x :- scale
self.y :- scale
self.z :- scale
EndMethod

Method SubtractTimeStep(sub:TVectorF, tstep:Float)
self.x :- (sub.x * tstep)
self.y :- (sub.y * tstep)
self.z :- (sub.z * tstep)
EndMethod

Method DivideScalar(scale:Float)
self.x :/ scale
self.y :/ scale
self.z :/ scale
EndMethod

Method CrossProduct(vec1:TVectorF, vec2:TVectorF)
self.x =  vec1.y * vec2.z  -  vec1.z * vec2.y
self.y = -vec1.x * vec2.z  +  vec1.z * vec2.x
self.z =  vec1.x * vec2.y  -  vec1.y * vec2.x
EndMethod

Method DotProduct:Float(vec:TVectorF)
Return vec.x * self.x + vec.y * self.y + vec.z * self.z
EndMethod

Method Magnitude:Float()
Return Sqr(self.x * self.x + self.y * Self.y + self.z * self.z)
EndMethod

Method Normalize()
Local magnitude:Float = self.Magnitude()
self.x :/ magnitude
self.y :/ magnitude
self.z :/ magnitude
If (Abs(self.x) < self.TOL) Then self.x = 0.0
If (Abs(self.y) < self.TOL) Then self.y = 0.0
If (Abs(self.z) < self.TOL) Then self.z = 0.0
EndMethod

Method Reverse(vec:TVectorF)
self.x = -vec.x
self.y = -vec.y
self.z = -vec.z
EndMethod

Method Reset()
self.x = 0
self.y = 0
self.z = 0
EndMethod

Method Clone(vec:TVectorF)
' not sure if it's neccesary to do it this way..
' oh well.. it's there anyway
' maybe self = vec will do..
self.x = vec.x
self.y = vec.y
self.z = vec.z
EndMethod

Method Show:String(sep:String)
Return String(self.x) + sep + ..
String(self.y) + sep + ..
String(self.z)
EndMethod

EndType

'// Vector Type Double (64 Bit)
Type TVectorD
Field x:Double
Field y:Double
Field z:Double

Const TOL:Double = 0.001

'**** THE METHODS *****
Function Create:TVectorD(x:Double=0, y:Double=0, z:Double=0)
Local v:TVectorD = New TVectorD
v.x = x
v.y = y
v.z = z
Return v
EndFunction

Method Set(x:Double, y:Double, z:Double)
self.x = x
self.y = y
self.z = z
EndMethod

Method SetX(x:Double)
self.x = x
EndMethod

Method SetY(y:Double)
self.y = y
EndMethod

Method SetZ(z:Double)
self.z = z
EndMethod

Method GetX:Double()
Return self.x
EndMethod

Method GetY:Double()
Return self.y
EndMethod

Method GetZ:Double()
Return self.z
EndMethod

Method Add(plus:TVectorD)
self.x :+ plus.x
self.y :+ plus.y
self.z :+ plus.z
EndMethod

Method AddScalar(scale:Double)
self.x :+ scale
self.y :+ scale
self.z :+ scale
EndMethod

Method AddTimeStep(plus:TVectorD, tstep:Double)
self.x :+ (plus.x * tstep)
self.y :+ (plus.y * tstep)
self.z :+ (plus.z * tstep)
EndMethod

Method Subtract(sub:TVectorD)
self.x :- sub.x
self.y :- sub.y
self.z :- sub.z
EndMethod

Method SubtractScalar(scale:Double)
self.x :- scale
self.y :- scale
self.z :- scale
EndMethod

Method SubtractTimeStep(sub:TVectorD, tstep:Double)
self.x :- (sub.x * tstep)
self.y :- (sub.y * tstep)
self.z :- (sub.z * tstep)
EndMethod

Method DivideScalar(scale:Double)
self.x :/ scale
self.y :/ scale
self.z :/ scale
EndMethod

Method CrossProduct(vec1:TVectorD, vec2:TVectorD)
self.x =  vec1.y * vec2.z  -  vec1.z * vec2.y
self.y = -vec1.x * vec2.z  +  vec1.z * vec2.x
self.z =  vec1.x * vec2.y  -  vec1.y * vec2.x
EndMethod

Method DotProduct:Double(vec:TVectorD)
Return vec.x * self.x + vec.y * self.y + vec.z * self.z
EndMethod

Method Magnitude:Double()
Return Sqr(self.x * self.x + self.y * Self.y + self.z * self.z)
EndMethod

Method Normalize()
Local magnitude:Double = self.Magnitude()
self.x :/ magnitude
self.y :/ magnitude
self.z :/ magnitude
If (Abs(self.x) < self.TOL) Then self.x = 0.0
If (Abs(self.y) < self.TOL) Then self.y = 0.0
If (Abs(self.z) < self.TOL) Then self.z = 0.0
EndMethod

Method Reverse(vec:TVectorD)
self.x = -vec.x
self.y = -vec.y
self.z = -vec.z
EndMethod

Method Reset()
self.x = 0
self.y = 0
self.z = 0
EndMethod

Method Clone(vec:TVectorD)
self.x = vec.x
self.y = vec.y
self.z = vec.z
EndMethod

Method Show:String(sep:String)
Return String(self.x) + sep + ..
String(self.y) + sep + ..
String(self.z)
EndMethod

EndType



Braincell(Posted 1+ years ago)

 Thanks. I will probably use some of this in my free stencil shadows library, incl your credits.


Chroma(Posted 1+ years ago)

 I'm guessing that's it converted to BMax.  Looks pretty nice.  I personally would have substituted the word "self" for "this". :)Just looking at your conversion makes me want to buy BMax right now...but I'm gonna wait until the OpenGL module is totally complete.  I hate hacking graphics.


LarsG(Posted 1+ years ago)

 Yeah.. I basically converted it.. and added the option of using Doubles as well..Hope I got it right.. (seeing as I'm not very good at this kind of math.. just followed your calculations.. :P)side note; cool that the code makes you want to buy BMax right away.. hehe.. and you should.. that way you can play with it, and make yourself familiar with it, until the 3D module is released.. :)


Chroma(Posted 1+ years ago)

 Just bought bmax today and I'm finishing up my vector lib conversion...and it's looks pretty darn similar to yours.  Nice job there LarsG. :)


Chroma(Posted 1+ years ago)

 I took out the Reset command.  Seems very unnecessary since you can just do a:vPos.Set(0,0,0)Also set the Set command to default x,y,z to 0.  So you could also just do a:vPos.Set()Edit:  Also took out the SetX,Y,Z and GetX,Y,Z since you can access them directly with something like:vPos.x = 20Local this:Float = vPos.xStill tweaking here. [/i]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal