# SnippetVectors

#### krainert

##### Member
See below for version 5.0.

JASS:
``````library Vectors

//********************************************************************************************************************************
//* Vectors
//*
//*   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
//*   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&#039;s Vector library
//*                    setMag optimized in Vector2D
//*                    Operator &lt; overloaded for Vector2D: returns true if the magnitude of this vector is lower than the magnitude of the other vector, false otherwise
//*                    Operator &lt; 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
set zx = GetLocationZ(.loc)
set zx = zx-GetLocationZ(.loc)
set zy = GetLocationZ(.loc)
set zy = zy-GetLocationZ(.loc)
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, &quot;x&quot;)
call suite.assertRealEquals(0., v.getY(), .001, &quot;y&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(7., v.getY(), .001, &quot;y&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(7., v2.getY(), .001, &quot;y&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(2., v.getY(), .001, &quot;y&quot;)
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, &quot;dir&quot;)
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, &quot;mag&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(-3., v.getY(), .001, &quot;y&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(9., v.getY(), .001, &quot;y&quot;)
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, &quot;dotProduct&quot;)
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, &quot;angle&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(3./5., v.getY(), .001, &quot;y&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(123., v.getY(), .001, &quot;y&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(24., v.getY(), .001, &quot;y&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(-6., v.getY(), .001, &quot;y&quot;)
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 suite.assertRealEquals(68.404, v1.getX(), .001, &quot;x&quot;)
call suite.assertRealEquals(-44.097, v1.getY(), .001, &quot;y&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(-138.2, v1.getY(), .001, &quot;y&quot;)
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 suite.assertRealEquals(68.404, v.getX(), .001, &quot;x&quot;)
call suite.assertRealEquals(-44.097, v.getY(), .001, &quot;y&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(-138.2, v.getY(), .001, &quot;y&quot;)
call v.destroy()
endfunction

private function vector2D_addDM takes VUnitSuite suite returns nothing
local Vector2D v = Vector2D.createXY(4, -3)
call suite.assertRealEquals(2, v.getX(), .001, &quot;x&quot;)
call suite.assertRealEquals(-1, v.getY(), .001, &quot;y&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(-5, v.getY(), .001, &quot;y&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(0., v.getY(), .001, &quot;y&quot;)
call suite.assertRealEquals(0., v.getZ(), .001, &quot;z&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(7., v.getY(), .001, &quot;y&quot;)
call suite.assertRealEquals(4., v.getZ(), .001, &quot;z&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(7., v2.getY(), .001, &quot;y&quot;)
call suite.assertRealEquals(4., v2.getZ(), .001, &quot;z&quot;)
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, &quot;mag&quot;)
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., &quot;x&quot;)
call suite.assertRealEquals(34.5, v.getY(), .01*34.5, &quot;y&quot;)
call suite.assertRealEquals(5.1, v.getZ(), .01*5.1, &quot;z&quot;)
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, &quot;dotProduct&quot;)
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, &quot;trippleProductScalar&quot;)
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, &quot;angle&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(17.54, v1.getY(), .01*17.54, &quot;y&quot;)
call suite.assertRealEquals(-6.5, v1.getZ(), .01*6.5, &quot;z&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(-3936.7, v1.getY(), .01*3936.7, &quot;y&quot;)
call suite.assertRealEquals(-425.735, v1.getZ(), .01*425.735, &quot;z&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(1.893958895, v.getY(), .01*1.893958895, &quot;y&quot;)
call suite.assertRealEquals(.776523147, v.getZ(), .01*.776523147, &quot;z&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(-.802631579, v.getY(), .01*.802631579, &quot;y&quot;)
call suite.assertRealEquals(1.921052632, v.getZ(), .01*1.921052632, &quot;z&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(3./7.0711, v.getY(), .001, &quot;y&quot;)
call suite.assertRealEquals(5./7.0711, v.getZ(), .001, &quot;z&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(24., v.getY(), .001, &quot;y&quot;)
call suite.assertRealEquals(-2.3, v.getZ(), .001, &quot;z&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(-6., v.getY(), .001, &quot;y&quot;)
call suite.assertRealEquals(-.375, v.getZ(), .001, &quot;z&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(1.5, v.getY(), .001, &quot;y&quot;)
call suite.assertRealEquals(-2.5, v.getZ(), .001, &quot;z&quot;)
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 suite.assertRealEquals(68.404, v1.getX(), .001, &quot;x&quot;)
call suite.assertRealEquals(-44.097, v1.getY(), .001, &quot;y&quot;)
call suite.assertRealEquals(.444, v1.getZ(), .001, &quot;z&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(-138.2, v1.getY(), .001, &quot;y&quot;)
call suite.assertRealEquals(-.198, v1.getZ(), .001, &quot;z&quot;)
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 suite.assertRealEquals(68.404, v.getX(), .001, &quot;x&quot;)
call suite.assertRealEquals(-44.097, v.getY(), .001, &quot;y&quot;)
call suite.assertRealEquals(.444, v.getZ(), .001, &quot;z&quot;)
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, &quot;x&quot;)
call suite.assertRealEquals(-138.2, v.getY(), .001, &quot;y&quot;)
call suite.assertRealEquals(-.198, v.getZ(), .001, &quot;z&quot;)
call v.destroy()
endfunction

private function ini takes nothing returns nothing
//suites
local VUnitSuite vector2D = VUnitSuite.create(&quot;Vector2D&quot;)
local VUnitSuite vector3D = VUnitSuite.create(&quot;Vector3D&quot;)
//Vector2D
//Vector3D
//run
call TriggerSleepAction(0)
call vector2D.run()
call vector3D.run()
call vector2D.destroy()
call vector3D.destroy()
endfunction

endlibrary``````

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

You're missing operations like cross product and rotations. Also, you're missing stuff like checking if 2 vectors are perpendicular and finding a perpendicular vector.

It's good that you included unit vectors =D.

Also, Vector 2D and Vector 3D should be separate resources. It doesn't make sense to include both in the same lib... they are different structures. It's like creating a Tree library and including lots and lots of trees ;\.

Frankly I have no idea how to calculate cross products, rotations, and perpendicularity, but if you'll supply a formula I'll stuff it into the code.

Regarding the unification of Vector2D and Vector3D into the same library it's due to their tight relations; there are several methods converting from one to the other, and splitting up the library would probably result in some pretty messy code.

I think vectors don't help you that much, unless you don't know maths

"http://en.wikipedia.org/wiki/Pythagoras_theorem"
And this is the theorem of theorems, and you should know how to calculate these kind of stuff

I probably won't spend time on some of the more advanced functions, but you're free to contribute.
EDIT: NoobImbaPro, why wouldn't vectors be useful to one with skills in math?
Also EDIT: It should be pretty easy to expand the classes as they are now, and I don't need fancy stuff like cross product for what I'm building now - hence why I hesitate to spend time on implementing it at present.

If I know maths well, I just won't need your snippet, I don't say that this snippet is awful or something similar but I mean it will help few
Or everything I say above is totally wrong by taking for granted that programmers don't know math.

If I know maths (geometry + algebra) I know how to make them, and do it faster than writing your functions.
You organize them well, as If I make a mistake to know what part of it is wrong rather than searching many lines.
But you just cut off the knowledge, as most now will use your functions rather than getting on the procedure that will train their minds.
That's all, but don't give up, keep in mind that guys/gals need advanced things, the easy ones do not grant attention.

EDIT: I understand you, it may be helpful to refresh your knowledge but there is the word "but" yet.

JASS:
``````//
method operator [] takes integer key returns real
if key == 0 then
return x
elseif key == 1 then
return y
else
return z
endif
endmethod

method operator []= takes integer key, real value returns nothing
if key == 0 then
set .x = value
elseif key == 1 then
set .y = value
else
set .z = value
endif
endmethod``````

These methods couldn't be more useless. Not only are they harder to read
than this.x, this.y or this.z, they would be slower and also add bulk to the
script because they are non-inlining methods.

NoobImbaPro: Apparently we differ greatly in our approach to software architecture

Bribe: I agree, but someone requested the functionality, and I figured I might as well implement it.

I know man All I wanted to say is that you should implement advanced stuff.

Also check this out:
JASS:
``````method operator [] takes integer key returns real
if key == 0 then
return x
else
return y
endif
endmethod

method operator []= takes integer key, real value returns nothing
if key == 0 then
set .x = value
else
set .y = value
endif
endmethod

//kill above operators

//Better?
set MyLocalVector.x = 15
//Than:
set MyLocalVector[0]=15
//Why you put the variable key?``````

I'm not sure why someone would request something so useless, but it's not
worth implementing.

In the response to the operator overriding issue...

Here are some potential arguments against implementing (for removing) them:
- (Saves space)
- (Prevents the use of less efficient code)

And some potential arguments for implementing (against removing) them:
- Response: Space saved is negligible and virtually irrelevant
- Response: A user aiming at highly efficient code should investigate the library to find the best possible method anyway, and a user unable to realize the ineffectiveness of using the overridden operators most likely will not have been able to produce fast code in the first place
- Principal: A vector is an array, and thus it should follow the example of array access and mutation
- Pragmatic: One might hypothetically need to perform calculations on which coordinate to access or mutate, and in those cases the built-in operators could save some time and effort
- Pragmatic: One might previously have used simple arrays and then moved on to use a vector library due to a need of built-in functionality in which case the ability to quickly and superficially perform the conversion without immediately replacing every index with variables might ease the process

Based on the above, removing the functionality will result in an insignificantly minor decrease in space requirements at an undecidable cost. Hence, I choose to leave it.

With regard to the issue of implementing more advanced functionality: I may have a look at it once my schedule allows it. Most likely I will simply run through Anitarf's library and build my methods based on his (thanks, Anitarf ).

Version 2.2 released.
Vectors now encompasses most of the functionality found in Anitarf's Vector library.

In structs, you need to use top-to-bottom parsing to avoid trigger evaluations.

JASS:
``````method a...
call .b() //Bad! Creates a trigger evaluation
method b...``````

Code is looking great, I'm going to approve this!

Bribe's suggestion is a good one, as I know several people out there who do this in their own maps.

Version 2.3 released.
Link to stash of all versions provided.

Code is looking great, I'm going to approve this!
Neat, thanks.

In structs, you need to use top-to-bottom parsing to avoid trigger evaluations.
This should be fixed now. Thanks.

Version 3.0

Vectors updated to 3.0.
The API has changed almost entirely so the easiest thing to do is probably consider this a whole new library.
Perhaps most notably, all accessor methods for basic operations (e.g. unit, scale, add, sub) have been removed, and the "m" prefix on corresponding mutator methods have been omitted so that, for example, unit now mutates the vector into a unit vector with the same direction. All of these new mutator methods return the result of the operation.
Why this change? Because vJass does not feature automated garbage collection, and using non-primitive accessor methods yields considerable amounts of objects for later cleanup. Consequently, the previous accessor methods resulted in excessive amounts of tedious manual object maintenance and destruction.
Note that advanced properties (e.g. crossProduct, trippleScalarProduct, projectionVector) are still implemented as accessor methods.
Accumulative operations and operator overloading have been removed; the former were hardly standard vector functionality and can easily be achieved using the new API anyway, and the latter was of little use and either somewhat counter-intuitive or technically inefficient.
Note that several other changes have been introduced in the library but omitted in this summary.

Can someone explain to me this method

JASS:
``````    static method createTerrainNormal takes real x, real y, real sampleRadius returns Vector3D
local Vector3D v = Vector3D.allocate()
local real zx
local real zy
local location loc = Location(0.0, 0.0)
set zx = GetLocationZ(loc)
set zx = zx-GetLocationZ(loc)
set zy = GetLocationZ(loc)
set zy = zy-GetLocationZ(loc)
return v
endmethod``````

Is this the same thing as calculating a "surface normal"? Why isn't the resultant vector normalized? What's with the v.z = sampleRadius*sampleRadius? =)

General chit-chat
Help Users
• No one is chatting at the moment.
• The Helper:
alternatively if you not making at least 23 an hour you could work in an Aldi warehouse
• Varine:
Yeah I've been thinking about using AI for shit. I'm on vacation next week so I'm going to spend some time reorganizing everything and getting all my shit back in order
• Varine:
lol I technically make less than 23 right now because I'm on salary and am there all the time, but it's a lot more than a normal wage still. I also have a meeting soon to renegotiate my pay because I want about a 25% increase to account for what I'm actually doing or a re-evaluation of our duties so that that my responsibilities are more in line with my pay. Depending on how that goes I'm prepared to give notice and move on, I don't mind taking less money so I'd have time for the rest of my life, but I'd rather they just fucking pay me enough to justify the commitment on my end. Plus right now I hold pretty much all the cards since I'm the only one actually qualified for my position.
+1
• Varine:
The other chef was there before me and got his position by virtue of being the only adult when the old general manager got married and didn't want to deal with the kitchen all the time, and happened to be in the position when the GM quit. New GM is fine with front of house but doesn't know enough about the kitchen side to really do anything or notice that I'm the one primarily maintaining it. Last time I left they hired like 3 people to replace me and there was still a noticeable drop in quality, so I got offered like 6 dollars an hour more and a pretty significant summer bonus to come back
• Varine:
So honestly even if I leave I think it would last a couple of months until it's obvious that I am not exactly replaceable and then I would be in an even better position.
• Varine:
But as of right now I have two other job offers that are reasonably close to what my hourly equivalency would be, and I would probably have more time for my other projects. The gap would be pretty easy to fill up if I had time to do my side jobs. I use to do some catering and private events, personal lessons, consultations, ect, and I charge like 120 an hour for those. But they aren't consistent enough for a full time job, too small of a town. And I'm not allowed to move for another year until my probation is over
• Varine:
I guess I could get it transferred, but that seems like a hassle.
• Varine:
Plus I have a storage room full of broken consoles I need to fix. I need to build a little reflow oven so I can manufacture some mod chips still, but it'll get there.
+1
• Varine:
I would like to get out of cooking in general at some point in the next ten years, but for the time being I can make decent money and pump that into savings. I've been taking some engineering classes online, but those aren't exactly career oriented at the moment, but I think getting into electronic or computer engineering of some sort would be ideal. I'm just going to keep taking some classes here and there until there's one that I am really into.
+2
• The Helper:
There is money in fixing and reselling consoles. Problem is people know that so they are doing it
• The Helper:
If you can find a source of broken consoles though you can make money fixing them - sometimes some big money
• Varine:
I was buying them on Ebay, but it's pretty competitive, so more recently I've just been telling the thrift stores to call me and I will come take all their electronics they can't sell. I've volunteered there before and people use them like a dump sometimes, and so they just have a massive amount of broken shit they throw away
• Varine:
The local GoodWill was pretty into it, surprisingly the animal shelter store was not. The lady I talked to there seemed to think I was trying to steal stuff or something, she wasn't very nice about it. Like I'm just trying to stop you having to throw a bunch of electronics away, if you can sell it great. I'd probably pay you for the broken shit too if you wanted
• Varine:
Then I make posts on Facebook yard sale pages sometimes saying I want your old electronics, but Facebook being Facebook people on there are also wary about why I want it, then want a bunch of money like it's going to be very worth it
• Varine:
Sooner than later I'm going to get my archives business going a little more. I need some office space that is kind of hard to get at the moment, but without it, I have to be like "Yeah so go ahead and just leave your family heirlooms and hundred year old photographs here at my shitty apartment and give me a thousand dollars, and next month I'll give you a thumb drive. I promise I'll take care of them!"
+1
• Varine:
I can do some things with them at their home, but when people have thousands of slides and very delicate newspaper clippings and things, not really practical. I
• Varine:
I would be there for days, even with my camera set up slides can take a long time, and if they want perfect captures I really need to use my scanners that are professionally made for that. My camera rig works well for what it is, but for enlargements and things it's not as good.
• Varine:
I've only had a couple clients with that so far, though. I don't have a website or anything yet though.
• Varine:
Console repair can be worthwhile, but it's also not a thing I can do at scale in my house. I just don't have room for the equipment. I need an office that I can segregate out for archival and then electronic restoration.
• Varine:
But in order for that to be real, I need more time, and for more time I need to work less, and to work less I need a different job, and for a different job I need more money to fall back on so that I can make enough to just pay like, rent and utilities and use my savings to find these projects
+1
• Varine:
Another couple years. I just need to take it slow and it'll get there.
• jonas:
any chance to get that stolen money back?
• jonas:
Maybe you can do console repair just as a side thing, especially if there's so much competition business might be slow. Or do you need a lot of special equipment for that?
• jonas:
I recently bought a used sauna and the preowner told me some component is broken, I took a look and it was just a burnt fuse, really cheap to fix. I was real proud of my self since I usually have two left hands for this kinda stuff
• tom_mai78101:
I am still playing Shapez 2. What an awful thing to happen, Varine, and hopefully everything has been sorted out soon. Always use multi-factor authentication whenever you have the opportunity to do so.

### Members online

No members online now.