JASS:

```
library Vectors
//********************************************************************************************************************************
//* Vectors
//*
//* ABOUT
//* Author: krainert
//* Version: 4.0
//*
//* DESCRIPTION
//* This library provides two vector classes:
//* - Vector2D representing a two-dimensional vector
//* - Vector3D representing a three-dimensional vector
//* Note: All angles are in radians
//*
//* CLASSES
//* ======== Vector2D ========
//* -- Description
//* Represents a two-dimensional vector
//* -- Static methods
//* static Vector2D create(Vector2D v) - instantiates a new two-dimensional vector as a clone of v
//* static Vector2D createXY(real x, real y) - instantiates a new two-dimensional vector with x coordinate x and y coordinate y
//* static Vector2D createDM(real d, real m) - instantiates a new two-dimensional vector with direction d and magnitude m
//* static Vector2D createNull() - instantiates a new two-dimensional vector with x and y coordinates 0
//* -- Methods
//* Vector2D clone() - returns a new clone of this vector
//* real getX() - returns the x coordinate of this vector
//* real getY() - returns the y coordinate of this vector
//* real getDir() - returns the direction of this vector
//* real getMag() - returns the magnitude of this vector
//* Vector2D setX(real x) - sets the x coordinate of this vector to x and returns the result
//* Vector2D setY(real y) - sets the y coordinate of this vector to y and returns the result
//* Vector2D setDir(real d) - sets the direction of this vector to d and returns the result
//* Vector2D setMag(real m) - sets the magnitude of this vector to m and returns the result
//* real dotProduct(Vector2D v) - returns the dot product of this vector and v
//* real angle(Vector2D v) - returns the angle between this vector and v
//* Vector2D unit() - sets the magnitude of this vector to 1 and returns the result
//* Vector2D flip() - sets the x coordinate of this vector to its previous y coordinate and the y coordinate of this vector to its previous x coordinate and returns the result
//* Vector2D invert() - sets the x coordinate of this vector to the inverse of its previous x coordinate and the y coordinate of this vector to the inverse of its previous y coordinate and returns the result
//* Vector2D scale(real s) - scales this vector by an amount equal to s and returns the result
//* Vector2D add(Vector2D v) - adds v to this vector and returns the vector
//* Vector2D sub(Vector2D v) - subtracts v from this vector and returns the result
//* Vector2D addXY(real x, real y) - adds a vector with x coordinate x and y coordinate y to this vector and returns the result
//* Vector2D subXY(real x, real y) - subtracts a vector with x coordinate x and y coordinate y from this vector and returns the result
//* Vector2D addDM(real d, real m) - adds a vector with direction d and magnitude m to this vector and returns the result
//* Vector2D subDM(real d, real m) - subtracts a vector with direction d and magnitude m from this vector and returns the result
//* ======== Vector3D ========
//* -- Description
//* Represents a three-dimensional vector
//* -- Static methods
//* static Vector3D create(Vector3D v) - instantiates a new three-dimensional vector as a clone of v
//* static Vector3D createXYZ(real x, real y, real z) - instantiates a new three-dimensional vector with x coordinate x, y coordinate y, and z coordinate z
//* static Vector3D createNull() - instantiates a new three-dimensional vector with x, y, and z coordinates 0
//* static Vector3D createTerrainNormal(real x, real y, real sampleRadius) - instantiates a new three-dimensional vector representing the normal of the terrain at the location with x coordinate x and y coordinate y with sample radius sampleRadius
//* -- Methods
//* Vector3D clone() - returns a new clone of this vector
//* real getX() - returns the x coordinate of this vector
//* real getY() - returns the y coordinate of this vector
//* real getZ() - returns the z coordinate of this vector
//* real getMag() - returns the magnitude of this vector
//* Vector3D setX(real x) - sets the x coordinate of this vector to x and returns the result
//* Vector3D setY(real y) - sets the y coordinate of this vector to y and returns the result
//* Vector3D setZ(real z) - sets the z coordinate of this vector to z and returns the result
//* Vector3D setMag(real m) - sets the magnitude of this vector to m and returns the result
//* real dotProduct(Vector3D v) - returns the dot product of this vector and v
//* real tripleProductScalar(Vector3D v1, Vector3D v2) - returns the tripple scalar product of this vector, v1, and v2
//* real angle(Vector3D v) - returns the angle between this vector and v
//* Vector3D crossProduct(Vector3D v) - sets this vector to the cross product of it and v and returns the result
//* Vector3D tripleProductVector(Vector3D v1, Vector3D v2) - sets this vector to the tripple scalar product of it, v1, and v2 and returns the result
//* Vector3D projectionVector(Vector3D dir) - sets this vector to the projection of it onto dir and returns the result
//* Vector3D projectionPlane(Vector3D normal) - sets this vector to the projection of it onto the plane with normal vector normal and returns the result
//* Vector3D unit() - sets the magnitude of this vector to 1 and returns the result
//* Vector3D invert() - sets the x coordinate of this vector to the inverse of its previous x coordinate, the y coordinate of this vector to the inverse of its previous y coordinate, and the z coordinate of this vector to the inverse of its previous z coordinate and returns the result
//* Vector3D scale(real s) - scales this vector by an amount equal to s and returns the result
//* Vector3D rotate(Vector3D axis, real angle) - rotates this vector around an axis through axis by an amount equal to angle and returns the result
//* Vector3D add(Vector3D v) - adds v to this vector and returns the result
//* Vector3D sub(Vector3D v) - subtracts v from this vector and returns the result
//* Vector3D addXYZ(real x, real y, real z) - adds a vector with x coordinate x, y coordinate y, and z coordinate z to this vector and returns the result
//* Vector3D subXYZ(real x, real y, real z) - subtracts a vector with x coordinate x, y coordinate y, and z coordinate z from this vector and returns the result
//*
//* CHANGELOG
//* 1.0 2011-07-08 Original release
//* 2.0 2011-07-13 vector redesigned and renamed to Vector2D
//* Vector3D added
//* 2.1 2011-07-17 modDir, modMag, and accumulative operations added to Vector2D
//* 2.2 2011-08-04 setMag added to Vector3D
//* crossProduct, tripleProductScalar, tripleProductVector, projectionVector, projectionPlane, rotate, mRotate, and static createTerrainNormal added to Vector3D
//* Note: the implementations of the above methods were inspired by Anitarf's Vector library
//* setMag optimized in Vector2D
//* Operator < overloaded for Vector2D: returns true if the magnitude of this vector is lower than the magnitude of the other vector, false otherwise
//* Operator < overloaded for Vector3D: returns true if the magnitude of this vector is lower than the magnitude of the other vector, false otherwise
//* Operator == overloaded for Vector2D: returns true if the x and y coordinates of this vector are equal to the x and y coordinates of the other vector respectively, false otherwise
//* Operator == overloaded for Vector3D: returns true if the x, y, and z coordinates of this vector are equal to the x, y, and z coordinates of the other vector respectively, false otherwise
//* 2.3 2011-08-05 getMag, getDir, setMag, setDir, addXY, subXY, mAddXY, and mSubXY in Vector2D relocated to prevent trigger evaluation
//* getMag, setMag, addXYZ, subXYZ, mAddXYZ, and mSubXYZ in Vector3D relocated to prevent trigger evaluation
//* 3.0 2011-10-24 Extensive API modifications and reductions
//* 4.0 2011-10-31 crossProduct, trippleProductVector, projectionVector, and projectionPlane in Vector3D changed into mutators
//* Miscellaneous corrections
//*
//********************************************************************************************************************************
globals
private constant integer MAX_2D = 8191
private constant integer MAX_3D = 8191
endglobals
struct Vector2D[MAX_2D]
private real x
private real y
static method create takes thistype v returns thistype
local thistype r = .allocate()
set r.x = v.x
set r.y = v.y
return r
endmethod
static method createXY takes real x, real y returns thistype
local thistype r = .allocate()
set r.x = x
set r.y = y
return r
endmethod
static method createDM takes real d, real m returns thistype
local thistype r = .allocate()
set r.x = Cos(d)*m
set r.y = Sin(d)*m
return r
endmethod
static method createNull takes nothing returns thistype
local thistype r = .allocate()
set r.x = 0
set r.y = 0
return r
endmethod
method onDestroy takes nothing returns nothing
endmethod
method clone takes nothing returns thistype
local thistype r = .allocate()
set r.x = .x
set r.y = .y
return r
endmethod
method getX takes nothing returns real
return .x
endmethod
method getY takes nothing returns real
return .y
endmethod
method getDir takes nothing returns real
return Atan2(.y, .x)
endmethod
method getMag takes nothing returns real
return SquareRoot(.x*.x+.y*.y)
endmethod
method setX takes real x returns thistype
set .x = x
return this
endmethod
method setY takes real y returns thistype
set .y = y
return this
endmethod
method setDir takes real d returns thistype
local real m = .getMag()
set .x = Cos(d)*m
set .y = Sin(d)*m
return this
endmethod
method setMag takes real m returns thistype
local real f = m/.getMag()
set .x = f*.x
set .y = f*.y
return this
endmethod
method dotProduct takes thistype v returns real
return .x*v.x+.y*v.y
endmethod
method angle takes thistype v returns real
return Acos(.dotProduct(v)/(.getMag()*v.getMag()))
endmethod
method unit takes nothing returns thistype
local real m = .getMag()
set .x = .x/m
set .y = .y/m
return this
endmethod
method flip takes nothing returns thistype
local real x = .x
set .x = .y
set .y = x
return this
endmethod
method invert takes nothing returns thistype
set .x = -.x
set .y = -.y
return this
endmethod
method scale takes real s returns thistype
set .x = s*.x
set .y = s*.y
return this
endmethod
method add takes thistype v returns thistype
set .x = .x+v.x
set .y = .y+v.y
return this
endmethod
method sub takes thistype v returns thistype
set .x = .x-v.x
set .y = .y-v.y
return this
endmethod
method addXY takes real x, real y returns thistype
set .x = .x+x
set .y = .y+y
return this
endmethod
method subXY takes real x, real y returns thistype
set .x = .x-x
set .y = .y-y
return this
endmethod
method addDM takes real d, real m returns thistype
set .x = .x+Cos(d)*m
set .y = .y+Sin(d)*m
return this
endmethod
method subDM takes real d, real m returns thistype
set .x = .x-Cos(d)*m
set .y = .y-Sin(d)*m
return this
endmethod
endstruct
struct Vector3D[MAX_3D]
private static location loc = Location(0., 0.)
private real x
private real y
private real z
static method create takes thistype v returns thistype
local thistype r = .allocate()
set r.x = v.x
set r.y = v.y
set r.z = v.z
return r
endmethod
static method createXYZ takes real x, real y, real z returns thistype
local thistype r = .allocate()
set r.x = x
set r.y = y
set r.z = z
return r
endmethod
static method createNull takes nothing returns thistype
local thistype r = .allocate()
set r.x = 0
set r.y = 0
set r.z = 0
return r
endmethod
static method createTerrainNormal takes real x, real y, real sampleRadius returns thistype
local thistype v = .allocate()
local real zx
local real zy
call MoveLocation(.loc, x-sampleRadius, y)
set zx = GetLocationZ(.loc)
call MoveLocation(.loc, x+sampleRadius, y)
set zx = zx-GetLocationZ(.loc)
call MoveLocation(.loc, x, y-sampleRadius)
set zy = GetLocationZ(.loc)
call MoveLocation(.loc, x, y+sampleRadius)
set zy = zy-GetLocationZ(.loc)
set sampleRadius = 2*sampleRadius
set v.x = zx*sampleRadius
set v.y = zy*sampleRadius
set v.z = sampleRadius*sampleRadius
return v
endmethod
method onDestroy takes nothing returns nothing
endmethod
method clone takes nothing returns thistype
local thistype r = .allocate()
set r.x = .x
set r.y = .y
set r.z = .z
return r
endmethod
method getX takes nothing returns real
return .x
endmethod
method getY takes nothing returns real
return .y
endmethod
method getZ takes nothing returns real
return .z
endmethod
method getMag takes nothing returns real
return SquareRoot(.x*.x+.y*.y+.z*.z)
endmethod
method setX takes real x returns thistype
set .x = x
return this
endmethod
method setY takes real y returns thistype
set .y = y
return this
endmethod
method setZ takes real z returns thistype
set .z = z
return this
endmethod
method setMag takes real m returns thistype
local real f = m/.getMag()
set .x = f*.x
set .y = f*.y
set .z = f*.z
return this
endmethod
method dotProduct takes thistype v returns real
return .x*v.x+.y*v.y+.z*v.z
endmethod
method tripleProductScalar takes thistype v1, thistype v2 returns real
return (.y*v1.z - .z*v1.y)*v2.x + (.z*v1.x - .x*v1.z)*v2.y + (.x*v1.y - .y*v1.x)*v2.z
endmethod
method angle takes thistype v returns real
return Acos(.dotProduct(v)/(.getMag()*v.getMag()))
endmethod
method crossProduct takes thistype v returns thistype
local real x = .y*v.z - .z*v.y
local real y = .z*v.x - .x*v.z
set .z = .x*v.y - .y*v.x
set .x = x
set .y = y
return this
endmethod
method tripleProductVector takes thistype v1, thistype v2 returns thistype
local real x = .y*v1.z - .z*v1.y
local real y = .z*v1.x - .x*v1.z
local real z = .x*v1.y - .y*v1.x
set .x = y*v2.z - z*v2.y
set .y = z*v2.x - x*v2.z
set .z = x*v2.y - y*v2.x
return this
endmethod
method projectionVector takes thistype dir returns thistype
local real l = (.x*dir.x + .y*dir.y + .z*dir.z) / (dir.x*dir.x + dir.y*dir.y + dir.z*dir.z)
set .x = dir.x*l
set .y = dir.y*l
set .z = dir.z*l
return this
endmethod
method projectionPlane takes thistype normal returns thistype
local real l = (.x*normal.x + .y*normal.y + .z*normal.z) / (normal.x*normal.x + normal.y*normal.y + normal.z*normal.z)
set .x = .x - normal.x*l
set .y = .y - normal.y*l
set .z = .z - normal.z*l
return this
endmethod
method unit takes nothing returns thistype
local real m = .getMag()
set .x = .x/m
set .y = .y/m
set .z = .z/m
return this
endmethod
method invert takes nothing returns thistype
set .x = -.x
set .y = -.y
set .z = -.z
return this
endmethod
method scale takes real s returns thistype
set .x = s*.x
set .y = s*.y
set .z = s*.z
return this
endmethod
method rotate takes thistype axis, real angle returns thistype
local real xx
local real xy
local real xz
local real yx
local real yy
local real yz
local real zx
local real zy
local real zz
local real al = axis.x*axis.x + axis.y*axis.y + axis.z*axis.z
local real f = (this.x*axis.x + this.y*axis.y + this.z*axis.z) / al
local real c = Cos(angle)
local real s = Sin(angle)
set zx = axis.x*f
set zy = axis.y*f
set zz = axis.z*f
set xx = this.x-zx
set xy = this.y-zy
set xz = this.z-zz
set al = SquareRoot(al)
set yx = (axis.y*xz - axis.z*xy) / al
set yy = (axis.z*xx - axis.x*xz) / al
set yz = (axis.x*xy - axis.y*xx) / al
set .x = xx*c + yx*s + zx
set .y = xy*c + yy*s + zy
set .z = xz*c + yz*s + zz
return this
endmethod
method add takes thistype v returns thistype
set .x = .x+v.x
set .y = .y+v.y
set .z = .z+v.z
return this
endmethod
method sub takes thistype v returns thistype
set .x = .x-v.x
set .y = .y-v.y
set .z = .z-v.z
return this
endmethod
method addXYZ takes real x, real y, real z returns thistype
set .x = .x+x
set .y = .y+y
set .z = .z+z
return this
endmethod
method subXYZ takes real x, real y, real z returns thistype
set .x = .x-x
set .y = .y-y
set .z = .z-z
return this
endmethod
endstruct
endlibrary
```

VUnit:

JASS:

```
library VectorsVUnit initializer ini requires Vectors, VUnit
private function vector2D_createNull takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createNull()
call suite.assertRealEquals(0., v.getX(), .001, "x")
call suite.assertRealEquals(0., v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_createXY takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(3., 7.)
call suite.assertRealEquals(3., v.getX(), .001, "x")
call suite.assertRealEquals(7., v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_create takes VUnitSuite suite returns nothing
local Vector2D v1 = Vector2D.createXY(3., 7.)
local Vector2D v2 = Vector2D.create(v1)
call suite.assertRealEquals(3., v2.getX(), .001, "x")
call suite.assertRealEquals(7., v2.getY(), .001, "y")
call v2.destroy()
call v2.destroy()
endfunction
private function vector2D_createDM takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createDM(.5*3.1416, 2.)
call suite.assertRealEquals(0., v.getX(), .001, "x")
call suite.assertRealEquals(2., v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_getDir takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(-3., 3.)
call suite.assertRealEquals(.75*3.1416, v.getDir(), .001, "dir")
call v.destroy()
endfunction
private function vector2D_getMag takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(3., -4.)
call suite.assertRealEquals(5., v.getMag(), .001, "mag")
call v.destroy()
endfunction
private function vector2D_setDir takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(0., 4.2426)
call v.setDir(-.75*3.1416)
call suite.assertRealEquals(-3., v.getX(), .001, "x")
call suite.assertRealEquals(-3., v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_setMag takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(4., 3.)
call v.setMag(15.)
call suite.assertRealEquals(12., v.getX(), .001, "x")
call suite.assertRealEquals(9., v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_dotProduct takes VUnitSuite suite returns nothing
local Vector2D v1 = Vector2D.createXY(2., 2.5)
local Vector2D v2 = Vector2D.createXY(5., 3.)
call suite.assertRealEquals(17.5, v1.dotProduct(v2), .001, "dotProduct")
call v1.destroy()
call v2.destroy()
endfunction
private function vector2D_angle takes VUnitSuite suite returns nothing
local Vector2D v1 = Vector2D.createXY(1., 1.)
local Vector2D v2 = Vector2D.createXY(-27., 27.)
call suite.assertRealEquals(.5*3.1416, v1.angle(v2), .001, "angle")
call v1.destroy()
call v2.destroy()
endfunction
private function vector2D_unit takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(4., 3.)
call v.unit()
call suite.assertRealEquals(4./5., v.getX(), .001, "x")
call suite.assertRealEquals(3./5., v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_flip takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(123., 321.)
call v.flip()
call suite.assertRealEquals(321., v.getX(), .001, "x")
call suite.assertRealEquals(123., v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_invert takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(42., -24.)
call v.invert()
call suite.assertRealEquals(-42., v.getX(), .001, "x")
call suite.assertRealEquals(24., v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_scale takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(-42., 24.)
call v.scale(-.25)
call suite.assertRealEquals(10.5, v.getX(), .001, "x")
call suite.assertRealEquals(-6., v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_add takes VUnitSuite suite returns nothing
local Vector2D v1 = Vector2D.createXY(12.101, 34.123)
local Vector2D v2 = Vector2D.createXY(56.303, -78.22)
call v1.add(v2)
call suite.assertRealEquals(68.404, v1.getX(), .001, "x")
call suite.assertRealEquals(-44.097, v1.getY(), .001, "y")
call v1.destroy()
call v2.destroy()
endfunction
private function vector2D_sub takes VUnitSuite suite returns nothing
local Vector2D v1 = Vector2D.createXY(342.23, -54.2)
local Vector2D v2 = Vector2D.createXY(-948.3, 84.)
call v1.sub(v2)
call suite.assertRealEquals(1290.53, v1.getX(), .001, "x")
call suite.assertRealEquals(-138.2, v1.getY(), .001, "y")
call v1.destroy()
call v2.destroy()
endfunction
private function vector2D_addXY takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(12.101, 34.123)
call v.addXY(56.303, -78.22)
call suite.assertRealEquals(68.404, v.getX(), .001, "x")
call suite.assertRealEquals(-44.097, v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_subXY takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(342.23, -54.2)
call v.subXY(-948.3, 84.)
call suite.assertRealEquals(1290.53, v.getX(), .001, "x")
call suite.assertRealEquals(-138.2, v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_addDM takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(4, -3)
call v.addDM(.75*3.1416, 2.8284)
call suite.assertRealEquals(2, v.getX(), .001, "x")
call suite.assertRealEquals(-1, v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector2D_subDM takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(4, -3)
call v.subDM(.75*3.1416, 2.8284)
call suite.assertRealEquals(6, v.getX(), .001, "x")
call suite.assertRealEquals(-5, v.getY(), .001, "y")
call v.destroy()
endfunction
private function vector3D_createNull takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createNull()
call suite.assertRealEquals(0., v.getX(), .001, "x")
call suite.assertRealEquals(0., v.getY(), .001, "y")
call suite.assertRealEquals(0., v.getZ(), .001, "z")
call v.destroy()
endfunction
private function vector3D_createXYZ takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createXYZ(3., 7., 4.)
call suite.assertRealEquals(3., v.getX(), .001, "x")
call suite.assertRealEquals(7., v.getY(), .001, "y")
call suite.assertRealEquals(4., v.getZ(), .001, "z")
call v.destroy()
endfunction
private function vector3D_create takes VUnitSuite suite returns nothing
local Vector3D v1 = Vector3D.createXYZ(3., 7., 4.)
local Vector3D v2 = Vector3D.create(v1)
call suite.assertRealEquals(3., v2.getX(), .001, "x")
call suite.assertRealEquals(7., v2.getY(), .001, "y")
call suite.assertRealEquals(4., v2.getZ(), .001, "z")
call v1.destroy()
call v2.destroy()
endfunction
private function vector3D_getMag takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createXYZ(1.2, 23., 3.1)
call suite.assertRealEquals(23.2390, v.getMag(), .001, "mag")
call v.destroy()
endfunction
private function vector3D_setMag takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createXYZ(12., 23., 3.4)
call v.setMag(39.19020924)
call suite.assertRealEquals(18., v.getX(), .01*18., "x")
call suite.assertRealEquals(34.5, v.getY(), .01*34.5, "y")
call suite.assertRealEquals(5.1, v.getZ(), .01*5.1, "z")
call v.destroy()
endfunction
private function vector3D_dotProduct takes VUnitSuite suite returns nothing
local Vector3D v1 = Vector3D.createXYZ(2., 2.5, 4.)
local Vector3D v2 = Vector3D.createXYZ(5., 3., 1.23)
call suite.assertRealEquals(22.42, v1.dotProduct(v2), .001, "dotProduct")
call v1.destroy()
call v2.destroy()
endfunction
private function vector3D_tripleProductScalar takes VUnitSuite suite returns nothing
local Vector3D v1 = Vector3D.createXYZ(2., 2.5, 4.)
local Vector3D v2 = Vector3D.createXYZ(5., 3., 1.23)
local Vector3D v3 = Vector3D.createXYZ(12.34, 23.45, -432.1)
call suite.assertRealEquals(3109.8285, v1.tripleProductScalar(v2, v3), .01*3109.8285, "trippleProductScalar")
call v1.destroy()
call v2.destroy()
call v3.destroy()
endfunction
private function vector3D_angle takes VUnitSuite suite returns nothing
local Vector3D v1 = Vector3D.createXYZ(2., 2.5, 4.)
local Vector3D v2 = Vector3D.createXYZ(5., 3., 1.23)
call suite.assertRealEquals(0.746151, v1.angle(v2), .01*0.123221, "angle")
call v1.destroy()
call v2.destroy()
endfunction
private function vector3D_crossProduct takes VUnitSuite suite returns nothing
local Vector3D v1 = Vector3D.createXYZ(2., 2.5, 4.)
local Vector3D v2 = Vector3D.createXYZ(5., 3., 1.23)
call v1.crossProduct(v2)
call suite.assertRealEquals(-8.925, v1.getX(), .01*8.925, "x")
call suite.assertRealEquals(17.54, v1.getY(), .01*17.54, "y")
call suite.assertRealEquals(-6.5, v1.getZ(), .01*6.5, "z")
call v1.destroy()
call v2.destroy()
endfunction
private function vector3D_tripleProductVector takes VUnitSuite suite returns nothing
local Vector3D v1 = Vector3D.createXYZ(2., 2.5, 4.)
local Vector3D v2 = Vector3D.createXYZ(5., 3., 1.23)
local Vector3D v3 = Vector3D.createXYZ(12.34, 23.45, -432.1)
call v1.tripleProductVector(v2, v3)
call suite.assertRealEquals(-7426.61, v1.getX(), .01*7426.61, "x")
call suite.assertRealEquals(-3936.7, v1.getY(), .01*3936.7, "y")
call suite.assertRealEquals(-425.735, v1.getZ(), .01*425.735, "z")
call v1.destroy()
call v2.destroy()
call v3.destroy()
endfunction
private function vector3D_projectionVector takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createXYZ(2., 2.5, 4.)
local Vector3D dir = Vector3D.createXYZ(5., 3., 1.23)
call v.projectionVector(dir)
call suite.assertRealEquals(3.156598158, v.getX(), .01*3.156598158, "x")
call suite.assertRealEquals(1.893958895, v.getY(), .01*1.893958895, "y")
call suite.assertRealEquals(.776523147, v.getZ(), .01*.776523147, "z")
call v.destroy()
call dir.destroy()
endfunction
private function vector3D_projectionPlane takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createXYZ(1., -3.5, 3.)
local Vector3D normal = Vector3D.createXYZ(1.5, 2.5, -1.)
call v.projectionPlane(normal)
call suite.assertRealEquals(2.618421053, v.getX(), .01*2.618421053, "x")
call suite.assertRealEquals(-.802631579, v.getY(), .01*.802631579, "y")
call suite.assertRealEquals(1.921052632, v.getZ(), .01*1.921052632, "z")
call v.destroy()
call normal.destroy()
endfunction
private function vector3D_unit takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createXYZ(4., 3., 5.)
call v.unit()
call suite.assertRealEquals(4./7.0711, v.getX(), .001, "x")
call suite.assertRealEquals(3./7.0711, v.getY(), .001, "y")
call suite.assertRealEquals(5./7.0711, v.getZ(), .001, "z")
call v.destroy()
endfunction
private function vector3D_invert takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createXYZ(42., -24., 2.3)
call v.invert()
call suite.assertRealEquals(-42., v.getX(), .001, "x")
call suite.assertRealEquals(24., v.getY(), .001, "y")
call suite.assertRealEquals(-2.3, v.getZ(), .001, "z")
call v.destroy()
endfunction
private function vector3D_scale takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createXYZ(-42., 24., 1.5)
call v.scale(-.25)
call suite.assertRealEquals(10.5, v.getX(), .001, "x")
call suite.assertRealEquals(-6., v.getY(), .001, "y")
call suite.assertRealEquals(-.375, v.getZ(), .001, "z")
call v.destroy()
endfunction
private function vector3D_rotate takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createXYZ(1.5, 2., -2.5)
local Vector3D axis = Vector3D.createXYZ(0., 0., 123.)
call v.rotate(axis, .5*3.1416)
call suite.assertRealEquals(-2., v.getX(), .001, "x")
call suite.assertRealEquals(1.5, v.getY(), .001, "y")
call suite.assertRealEquals(-2.5, v.getZ(), .001, "z")
call v.destroy()
call axis.destroy()
endfunction
private function vector3D_add takes VUnitSuite suite returns nothing
local Vector3D v1 = Vector3D.createXYZ(12.101, 34.123, .123)
local Vector3D v2 = Vector3D.createXYZ(56.303, -78.22, .321)
call v1.add(v2)
call suite.assertRealEquals(68.404, v1.getX(), .001, "x")
call suite.assertRealEquals(-44.097, v1.getY(), .001, "y")
call suite.assertRealEquals(.444, v1.getZ(), .001, "z")
call v1.destroy()
call v2.destroy()
endfunction
private function vector3D_sub takes VUnitSuite suite returns nothing
local Vector3D v1 = Vector3D.createXYZ(342.23, -54.2, .123)
local Vector3D v2 = Vector3D.createXYZ(-948.3, 84., .321)
call v1.sub(v2)
call suite.assertRealEquals(1290.53, v1.getX(), .001, "x")
call suite.assertRealEquals(-138.2, v1.getY(), .001, "y")
call suite.assertRealEquals(-.198, v1.getZ(), .001, "z")
call v1.destroy()
call v2.destroy()
endfunction
private function vector3D_addXYZ takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createXYZ(12.101, 34.123, .123)
call v.addXYZ(56.303, -78.22, .321)
call suite.assertRealEquals(68.404, v.getX(), .001, "x")
call suite.assertRealEquals(-44.097, v.getY(), .001, "y")
call suite.assertRealEquals(.444, v.getZ(), .001, "z")
call v.destroy()
endfunction
private function vector3D_subXYZ takes VUnitSuite suite returns nothing
local Vector3D v = Vector3D.createXYZ(342.23, -54.2, .123)
call v.subXYZ(-948.3, 84., .321)
call suite.assertRealEquals(1290.53, v.getX(), .001, "x")
call suite.assertRealEquals(-138.2, v.getY(), .001, "y")
call suite.assertRealEquals(-.198, v.getZ(), .001, "z")
call v.destroy()
endfunction
private function ini takes nothing returns nothing
//suites
local VUnitSuite vector2D = VUnitSuite.create("Vector2D")
local VUnitSuite vector3D = VUnitSuite.create("Vector3D")
//Vector2D
call vector2D.addTest(vector2D_createNull, "createNull")
call vector2D.addTest(vector2D_createXY, "createXY")
call vector2D.addTest(vector2D_create, "create")
call vector2D.addTest(vector2D_createDM, "createDM")
call vector2D.addTest(vector2D_getDir, "getDir")
call vector2D.addTest(vector2D_getMag, "getMag")
call vector2D.addTest(vector2D_setDir, "setDir")
call vector2D.addTest(vector2D_setMag, "setMag")
call vector2D.addTest(vector2D_dotProduct, "dotProduct")
call vector2D.addTest(vector2D_angle, "angle")
call vector2D.addTest(vector2D_unit, "unit")
call vector2D.addTest(vector2D_flip, "flip")
call vector2D.addTest(vector2D_invert, "invert")
call vector2D.addTest(vector2D_scale, "scale")
call vector2D.addTest(vector2D_add, "add")
call vector2D.addTest(vector2D_sub, "sub")
call vector2D.addTest(vector2D_addXY, "addXY")
call vector2D.addTest(vector2D_subXY, "subXY")
call vector2D.addTest(vector2D_addDM, "addDM")
call vector2D.addTest(vector2D_subDM, "subDM")
//Vector3D
call vector3D.addTest(vector3D_createNull, "createNull")
call vector3D.addTest(vector3D_createXYZ, "createXYZ")
call vector3D.addTest(vector3D_create, "create")
call vector3D.addTest(vector3D_getMag, "getMag")
call vector3D.addTest(vector3D_setMag, "setMag")
call vector3D.addTest(vector3D_dotProduct, "dotProduct")
call vector3D.addTest(vector3D_tripleProductScalar, "tripleProductScalar")
call vector3D.addTest(vector3D_angle, "angle")
call vector3D.addTest(vector3D_crossProduct, "crossProduct")
call vector3D.addTest(vector3D_tripleProductVector, "tripleProductVector")
call vector3D.addTest(vector3D_projectionVector, "projectionVector")
call vector3D.addTest(vector3D_projectionPlane, "projectionPlane")
call vector3D.addTest(vector3D_unit, "unit")
call vector3D.addTest(vector3D_invert, "invert")
call vector3D.addTest(vector3D_scale, "scale")
call vector3D.addTest(vector3D_rotate, "rotate")
call vector3D.addTest(vector3D_add, "add")
call vector3D.addTest(vector3D_sub, "sub")
call vector3D.addTest(vector3D_addXYZ, "addXYZ")
call vector3D.addTest(vector3D_subXYZ, "subXYZ")
//run
call TriggerSleepAction(0)
call vector2D.run()
call vector3D.run()
call vector2D.destroy()
call vector3D.destroy()
endfunction
endlibrary
```

http://krainert.com/content/vectors/