v2d

v2 - a minimalistic 2d vector class

Usage no npm install needed!

<script type="module">
  import v2d from 'https://cdn.skypack.dev/v2d';
</script>

README

License npm npm no dependencies

v2 - A Minimalistic 2D Vector Class

v2 is not really a class, but merely a creator function generating plain javascript objects. So v2(3,4) creates the plain object {x:3,y:4}. Then v2 also serves as a namespace holding a minimal set of static vector functions. Those static functions expect objects like {x:<number>,y:<number>}.

The advantage here over class-based vector libraries is the more universal approach that seemlessly also works with other objects that happen to own an x and y member.

var cir = { x:100, y:200, r: 50 }, 
    pnt = { x: 30, y:150 },
    dist = v2.len(v2.dif(cir,pnt)) - 50;  // dist = 36.02325

An x/y-getter and - for some readonly functions not even necessary - x/y-setter is also sufficient.

var box = {
   x0:100, y0:200, b:100, h:60,
   // center point
   get x()  { return this.x0 + this.b/2; },
   set x(v) { this.x0 += v - (this.x0 + this.b/2); },
   get y()  { return this.y0 + this.h/2; },
   set y(v) { this.y0 += v - (this.y0 + this.h/2); }
}
v2.add(box,{x:50,y:75})    // box = { x0:150, y0:275, b:100, h:60 }

With this convention v2 should perfectly harmonize with custom objects as well as possible ECMAScript 7 typed objects.

An alternative representation using arrays [3,4] shows comparable performance results at creation and access time. But the code is mostly less readable with array notation compared with object notation {x:3,y:4}. Another advantage of object notation is to also deal with alternate polar coordinates {r:5,w:0.927} without problems, as the coordinates format is inline documented, in contrast to array notation [5,0.927] where you have to guess.

v2 differs three types of vector functions:

  • analyse functions (isZero, isEq, isEps, isUnit, isPolar, isCartesian, sqr, len, angle)
  • operator functions (unit, neg, tilde, sum, dif, rot, scl, trf, simtrf, dot, perp, polar, cartesian)
  • mutator functions (iunit, ineg, itilde, add, sub, irot, iscl, itrf, isimtrf, copy, ipolar, icartesian)

Whereas operator functions never modify their vector arguments, mutator functions intentionly do exactly that for memory saving and performance reasons. So consider the vector expression s(a+b-c), scaling the sum of three vectors a, b, c by s. An appropriate v2 representation using operator functions reads

   v2.scl(v2.sum(a,v2.dif(b,c)),s)

None of the used vectors a, b, c are modified. Instead three temporary vector objects are created. But when using mutator functions as an alternative

   v2.iscl(v2.isum(a,v2.idif(b,c)),s)

no temporary vector objects are created, which can significantly save memory and performs much better. Instead vectors a and b loose their original values holding intermediate values then. You may read those applied functions as inplace scale, inplace sum and inplace difference.

Considering this, best strategy with that example would be to let the innermost function create a temp object and reuse it then with the other outer functions, as in

   v2.iscl(v2.isum(v2.dif(b,c),a),s)
//     |       |       |_  create and return temp object
//     |       |_  inplace add to first argument
//     |_ inplace scale first argument 
// algebraic equivalence:
// var tmp = b-c; tmp += a; tmp *= s;

v2 is minimal, can perfectly deal with custom objects and is well suited for graphics, physics and engineering applications. It is tiny. v2 weights 15 kB uncompressed and 3 kb minified.

Vector-2D Math Resources

Vector-2D Math Resources

Node Installation

npm install v2d

var v2 = require('v2d');
var u = v2(3,4);

Browser

<script src="v2.js"></script>
<script>
   var u = v2(3,4);
</script>

Test

npm run test

GitCDN

Use the link https://gitcdn.xyz/repo/goessner/v2/master/v2.min.js for getting the latest commit as a raw file.

In HTML use ...

<script src="https://gitcdn.xyz/repo/goessner/v2/master/v2.min.js"></script>

License

v2 is licensed under the terms of the MIT License. See LICENSE-MIT for details.

Change Log

All notable changes to this project will be documented in this file. This project adheres to Semantic Versioning.

1.3.8 - 2016-12-07

Modified

  • scl and iscl function: default value [=1] of second parameter factor removed. Value 0 is allowed and supported now.

1.3.1 - 2016-07-05

Added

  • isimtrf function for applying inplace similarity transform.
  • Examples to API docs added.

1.3.0 - 2016-07-04

Added

  • polar function for converting to polar coordinates.
  • cartesian function for converting from polar to cartesian coordinates.
  • ipolar function for inplace converting to polar coordinates.
  • icartesian function for inplace converting from polar to cartesian coordinates.

Modified

  • toPolar previous converting function marked as obsolete. Use polar instead.
  • fromPolar previous converting function marked as obsolete. Use cartesian instead.

1.2.0 - 2016-05-14

Added

`simtrf` function for applying efficient similarity transformation @goessner.

1.1.0 - 2016-01-08

Added

toPolar function @goessner.
fromPolar function @goessner.
CHANGELOG.md @goessner.

API

Kind: global class

v2(x,y) ⇒ object

Create a plain 2D vector object {x:number,y:number} without using new.

Example

var u1 = v2(3,4),      // create vector as an alternative ...
    u2 = {x:3,y:4};    // ... to simple object notation.

v2.zero

Null vector.

Kind: static property of v2

v2.EPS

Epsilon (1.49e-8) to test null vectors and unit vectors against.

Kind: static property of v2

v2.isZero(u) ⇒ boolean

Test for zero vector.
u === 0

Kind: static method of v2
Returns: boolean - is zero vector.

Param Type Description
u v2 2D cartesian vector

Example

var u1 = v2(3,4), u2 = {x:-3,y:-4};
v2.isZero(v2.add(u1,u2);   // true
v2.isZero(v2.sub(u1,u2);   // false

v2.isEq(u, v) ⇒ boolan

Equality of two vectors. u === v

Kind: static method of v2
Returns: boolan - equality.

Param Type Description
u v2 2D cartesian vector
v v2 2D cartesian vector

Example

var u1 = v2(3,4), u2 = v2(1,2), u3 = {x:3,y:4};
v2.isEq(u1,u2);       // false
v2.isEq(u1,u3);       // true

v2.isEps(u, v) ⇒ boolean

Test, if a vector -- or the difference of two vectors -- is smaller than v2.EPS.
|u - v| < v2.EPS

Kind: static method of v2
Returns: boolean - nearly equal or zero.

Param Type Description
u v2 Vector to test.
v v2 | undefined Vector to build the difference with u [optional].

Example

var u1 = v2(1e-10,2e-9), u2 = {x:3e-9,y:-4e-11};
v2.isEps(u1);         // true
v2.isEps(u1,u2);      // true, with difference
                      // {x:-2.9e-9, y:2.04e-9} 

v2.isUnit(u) ⇒ boolean

Test, if vector is a unit vector.
|u| === 1

Kind: static method of v2

Param Type Description
u v2 Vector to test.

Example

var u1 = {x:3/5,y:4/5}, u2 = v2(3,-4);
v2.isUnit(u1);        // true
v2.isUnit(u2);        // false

v2.isCartesian(u) ⇒ boolean

Test, if vector has cartesian coordinates {x,y}.

Kind: static method of v2

Param Type Description
u v2 Vector to test.

Example

var u1 = v2(3,4), u2 = {r:5,w:0.9273}, 
    u3 = {r:5,w:0.9273,x:3,y:4};
v2.isCartesian(u1);   // true
v2.isCartesian(u2);   // false
v2.isCartesian(u3);   // true

v2.isPolar(u) ⇒ boolean

Test, if vector has polar coordinates {r,w}.

Kind: static method of v2

Param Type Description
u v2 Vector to test.

Example

var u1 = v2(3,4), u2 = {r:5,w:0.9273}, 
    u3 = {r:5,w:0.9273,x:3,y:4};
v2.isPolar(u1);   // false
v2.isPolar(u2);   // true
v2.isPolar(u3);   // true

v2.len(u) ⇒ number

Length / Euclidean Norm of vector.
len = sqrt(u.x^2 + u.x^2)

Kind: static method of v2
Returns: number - length of vector.

Param Type Description
u v2 2D cartesian vector

Example

var u = {x:3,y:4};
v2.len(u);   // 5

v2.sqr(u) ⇒ number

Squared Length of vector.
u*u = u.x^2 + u.x^2

Kind: static method of v2
Returns: number - squared length of vector.

Param Type Description
u v2 2D cartesian vector

Example

var u = v2(3,4);
v2.sqr(u);   // 25

v2.angle(u, [v]) ⇒ number

Angle from u to v or from positive x-axis to u - if v is missing. [radians].
atan(~u*v)/(u*v)

Kind: static method of v2
Returns: number - angle from u to v or from positive x-axis
to u.

Param Type Description
u v2 2D cartesian vector
[v] v2 2D cartesian vector

Example

var u1 = v2(3,4), u2 = v2(-4,3);
v2.angle(u1);     // 0.9273
v2.angle(u1,u2);  // 1.5708 (pi/2)

v2.copy(u, v) ⇒ v2

Assign vector u to v.
v = u

Kind: static method of v2
Returns: v2 - destination vector o.

Param Type Description
u v2 2D source vector
v v2 | undefined 2D destination vector [optional].

Example

var u1 = v2(3,4), u2 = {x:2,y:1}, u3;
v2.copy(u1,u2);    // u2 = {x:3,y:4}
u3 = v2.copy(u1);  // u3 = {x:3,y:4}

v2.neg(u) ⇒ v2

Negative vector.
-u

Kind: static method of v2
Returns: v2 - 2D cartesian vector negated.

Param Type Description
u v2 2D cartesian vector

Example

v2.neg({x:2,y:1});  // {x:-2,y:-1}

v2.tilde(u) ⇒ v2

Orthogonal vector - rotated by 90 degrees counterclockwise. Also called perp operator.
~u = {x:-u.y,y:u.x}

Kind: static method of v2
Returns: v2 - 2D orthogonal vector.

Param Type Description
u v2 2D cartesian vector

Example

v2.tilde({x:3,y:4});  // {x:-4,y:3}

v2.unit(u) ⇒ v2

Unit vector of a vector.
u / |u|

Kind: static method of v2
Returns: v2 - 2D unit cartesian vector.

Param Type Description
u v2 2D cartesian vector

Example

v2.unit({x:3,y:4});  // {x:0.6,y:0.8}

v2.cartesian(u) ⇒ object

Cartesian vector from polar vector.
If argument is already cartesian it is simply returned.
{x:u.r*cos(u.w),y:u.r*sin(u.w)}

Kind: static method of v2
Returns: object - 2D cartesian vector {x,y}.

Param Type Description
u v2 2D polar vector {r,w}.

Example

var u1 = {r:5,w:0.9273}, u2 = {x:3,y:4}; 
v2.cartesian(u1);       // {x:3,y:4};
v2.cartesian(u2);       // {x:3,y:4};

v2.polar(u) ⇒ object

Polar vector from a cartesian vector.
If argument is already polar it is simply returned.
{r:sqrt(u.x^2+u.y^2),w:atan2(u.y,u.x)}

Kind: static method of v2
Returns: object - 2D polar vector {r,w}.

Param Type Description
u v2 2D cartesian vector {x,y}.

Example

var u1 = {r:5,w:0.9273}, u2 = {x:3,y:4}; 
v2.polar(u1);       // {r:5,w:0.9273};
v2.polar(u2);       // {r:5,w:0.9273};

v2.toPolar(u) ⇒ object

Convert cartesian vector to polar vector.
Obsolete: use v2.polar instead.

Kind: static method of v2
Returns: object - 2D polar vector.

Param Type Description
u v2 2D cartesian vector

v2.fromPolar(u) ⇒ v2

Convert polar vector {r,w} to cartesian vector.
Obsolete: use v2.cartesian instead.
{x:u.r*cos(u.w),y:u.r*sin(u.w)}

Kind: static method of v2
Returns: v2 - 2D cartesian vector

Param Type Description
u object 2D polar vector.

v2.sum(u, v) ⇒ v2

Sum of two vectors.
u + v

Kind: static method of v2
Returns: v2 - 2D cartesian vector sum.

Param Type Description
u v2 2D cartesian vector
v v2 2D cartesian vector

Example

var u1 = {x:3,y:4}, u2 = {x:1,y:2}; 
v2.sum(u1,u2);      // {x:4,y:6};

v2.dif(u, v) ⇒ v2

Difference of two vectors.
u - v

Kind: static method of v2
Returns: v2 - 2D cartesian vector difference.

Param Type Description
u v2 2D cartesian vector
v v2 2D cartesian vector

Example

var u1 = {x:3,y:4}, u2 = {x:1,y:2}; 
v2.dif(u1,u2);      // {x:2,y:2};

v2.dot(u, v) ⇒ number

Scalar (dot) product of two vectors (inner product).
u * v = u.x*v.x + u.y*v.y

Kind: static method of v2
Returns: number - scalar product.

Param Type Description
u v2 2D cartesian vector
v v2 2D cartesian vector

Example

var u1 = {x:3,y:4}, u2 = {x:1,y:2}, u3 = {x:-4,y:3}; 
v2.dot(u1,u2);      // 11;
v2.dot(u1,u3);      // 0;
v2.dot(u2,u3);      // 2;

v2.perp(u, v) ⇒ number

perp dot product of two 2D cartesian vectors (outer product or area product).
~u * v = u.x*v.y - u.y*v.x
Same as : v2.dot(v2.tilde(u),v)
Result is equal to the value of the z-coordinate of the vector from the cross product of the corresponding 3D vectors.

Kind: static method of v2
Returns: number - perp dot product (~u*v).

Param Type Description
u v2 2D cartesian vector
v v2 2D cartesian vector

Example

var u1 = {x:3,y:4}, u2 = {x:6,y:8}, u3 = {x:1,y:2}; 
v2.perp(u1,u2);      // 0;
v2.perp(u1,u3);      // 2;
v2.perp(u2,u3);      // 4;

v2.scl(u, [s]) ⇒ v2

Scale a vector by multiplication.
u*s

Kind: static method of v2
Returns: v2 - 2D cartesian vector scaled.

Param Type Default Description
u v2 2D cartesian vector
[s] number Scaling factor

Example

v2.scl({x:3,y:4},2);      // {x:6,y:8};
v2.scl({x:3,y:4},-1);     // {x:-3,y:-4};

v2.rot(u, [w]) ⇒ v2

Rotate a vector by angle w [radians].

Kind: static method of v2
Returns: v2 - 2D cartesian vector rotated.

Param Type Default Description
u v2 2D cartesian vector
[w] number 0 Rotation angle in radians

Example

v2.rot({x:3,y:4},-Math.PI/2);   // {x:4,y:-3};

v2.trf(u, a, b, c, d, [e], [f]) ⇒ v2

Transform a vector by 2x3 matrix (SVG).
[a c e] [x] = [x']
[b d f] [y] = [y']
[0 0 1] [1] = [1]

Kind: static method of v2
Returns: v2 - 2D cartesian vector transformed.

Param Type Default Description
u v2 2D cartesian vector
a number m11
b number m21
c number m12
d number m22
[e] number 0 x-translation
[f] number 0 y-translation

Example

v2.trf({x:3,y:4},2,0,0,1,4,5);   // {x:10,y:9};

v2.simtrf(u, [a], [b]) ⇒ v2

Apply similarity transformation to a vector.
a*u + b*~u

Kind: static method of v2
Returns: v2 - 2D cartesian vector transformed.

Param Type Default Description
u v2 2D cartesian vector
[a] number 1 Scale u by a.
[b] number 0 Scale ~u by b.

Example

v2.simtrf({x:3,y:4},2,1);   // {x:2,y:11};

v2.icartesian(u) ⇒ object

Inplace convert polar vector to cartesian vector.
{x:u.r*cos(u.w),y:u.r*sin(u.w)}

Kind: static method of v2
Returns: object - 2D cartesian vector.

Param Type Description
u v2 2D polar vector.

Example

var u1 = {r:5,w:0.9273}, u2 = {x:3,y:4}; 
v2.icartesian(u1);       // u1 = {x:3,y:4};
v2.icartesian(u2);       // u2 = {x:3,y:4};

v2.ipolar(u) ⇒ object

Inplace convert cartesian vector to polar vector.
{r:sqrt(u.x^2+u.y^2),w:atan2(u.y,u.x)}

Kind: static method of v2
Returns: object - 2D polar vector.

Param Type Description
u v2 2D cartesian vector

Example

var u1 = {r:5,w:0.9273}, u2 = {x:3,y:4}; 
v2.ipolar(u1);       // u1 = {r:5,w:0.9273};
v2.ipolar(u2);       // u2 = {r:5,w:0.9273};

v2.ineg(u) ⇒ v2

Inplace negate a vector.
u = -u

Kind: static method of v2
Returns: v2 - 2D vector u negated.

Param Type Description
u v2 2D cartesian vector

Example

let u = {x:2,y:1};
v2.ineg(u);  // u = {x:-2,y:-1}

v2.itilde(u) ⇒ v2

Inplace create orthogonal vector - rotated by 90 degrees counterclockwise.
u = {x:-u.y,y:u.x}

Kind: static method of v2
Returns: v2 - orthogonal cartesian vector u.

Param Type Description
u v2 2D cartesian vector

Example

let u = {x:3,y:4};
v2.tilde(u);  // u = {x:-4,y:3}

v2.iunit(u) ⇒ v2

Inplace create unit vector of a vector.
u = u / |u|

Kind: static method of v2
Returns: v2 - 2D unit cartesian vector.

Param Type Description
u v2 2D cartesian vector

Example

let u = {x:3,y:4};
v2.unit(u);  // u = {x:0.6,y:0.8}

v2.isum(u, v) ⇒ v2

Add vector v to u (inplace sum).
u += v

Kind: static method of v2
Returns: v2 - Result vector u.

Param Type Description
u v2 2D cartesian vector
v v2 2D cartesian vector

Example

var u1 = {x:3,y:4}, u2 = {x:1,y:2}; 
v2.isum(u1,u2);      // u1 = {x:4,y:6};

v2.idif(u, v) ⇒ v2

Subtract vector v from u (inplace difference).
u -= v

Kind: static method of v2
Returns: v2 - result vector u.

Param Type Description
u v2 2D cartesian vector
v v2 2D cartesian vector

Example

var u1 = {x:3,y:4}, u2 = {x:1,y:2}; 
v2.idif(u1,u2);      // u1 = {x:2,y:2};

v2.iscl(u, [s]) ⇒ v2

Inplace scale a vector.
u *= s

Kind: static method of v2
Returns: v2 - cartesian vector u scaled.

Param Type Default Description
u v2 2D cartesian vector
[s] number 1 Scaling factor

Example

let u = {x:3,y:4};
v2.scl(u,2);      // u = {x:6,y:8};

v2.irot(u, [w]) ⇒ v2

Inplace rotate a vector by angle w [radians].

Kind: static method of v2
Returns: v2 - vector u rotated.

Param Type Default Description
u v2 2D cartesian vector
[w] number 0 Rotation angle in radians.

Example

let u = {x:3,y:4};
v2.rot(u,-Math.PI/2);   // u = {x:4,y:-3};

v2.itrf(u, a, b, c, d, e, f) ⇒ v2

Inplace transform a vector by 2x3 matrix (SVG).
[a c e] [x] = [x']
[b d f] [y] = [y']
[0 0 1] [1] = [1]

Kind: static method of v2
Returns: v2 - 2D cartesian vector transformed.

Param Type Description
u v2 2D cartesian vector
a number m11
b number m21
c number m12
d number m22
e number x-translation [optional]
f number y-translation [optional]

Example

let u = {x:3,y:4};
v2.trf(u,2,0,0,1,4,5);   // u = {x:10,y:9};

v2.isimtrf(u, a, b) ⇒ v2

Apply inplace similarity transformation to a vector.
u = a*u + b*~u

Kind: static method of v2
Returns: v2 - 2D cartesian vector transformed.

Param Type Description
u v2 2D cartesian vector
a number Scale u by a.
b number Scale ~u by b.

Example

let u = {x:3,y:4};
v2.simtrf(u,2,1);   // u = {x:2,y:11};

v2.str(u, n) ⇒ string

String of vector. Format: (x,y).

Kind: static method of v2
Returns: string - .

Param Type Description
u v2 2D cartesian vector
n v2 decimal places. [optional]

Example

let u1 = {x:3,y:4}, u2 = {x:1.23456,y:78.90123} 
v2.str(u1);     // "(3,4)";
v2.str(u2,3);   // "(1.235,78.901)";
v2.str(u2,0);   // "(1,79)";
v2.str(u2);     // "(1.23456,78.90123)";