README
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
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
andiscl
function: default value [=1] of second parameterfactor
removed. Value0
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. Usepolar
instead.fromPolar
previous converting function marked as obsolete. Usecartesian
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()
- .zero
- .EPS
- .isZero(u) ⇒
boolean
- .isEq(u, v) ⇒
boolan
- .isEps(u, v) ⇒
boolean
- .isUnit(u) ⇒
boolean
- .isCartesian(u) ⇒
boolean
- .isPolar(u) ⇒
boolean
- .len(u) ⇒
number
- .sqr(u) ⇒
number
- .angle(u, v) ⇒
number
- .copy(u, v) ⇒
v2
- .neg(u) ⇒
v2
- .tilde(u) ⇒
v2
- .unit(u) ⇒
v2
- .cartesian(u) ⇒
object
- .polar(u) ⇒
object
- .toPolar(u) ⇒
object
- .fromPolar(2D) ⇒
v2
- .sum(u, v) ⇒
v2
- .dif(u, v) ⇒
v2
- .dot(u, v) ⇒
number
- .perp(u, v) ⇒
number
- .scl(u, [s]) ⇒
v2
- .rot(u, w) ⇒
v2
- .trf(u, a, b, c, d, [e], [f]) ⇒
v2
- .simtrf(u, a, b) ⇒
v2
- .icartesian(u) ⇒
object
- .ipolar(u) ⇒
object
- .ineg(u) ⇒
v2
- .itilde(u) ⇒
v2
- .iunit(u) ⇒
v2
- .isum(u, v) ⇒
v2
- .idif(u, v) ⇒
v2
- .iscl(u, s) ⇒
v2
- .irot(w, u) ⇒
v2
- .itrf(u, a, b, c, d, e, f) ⇒
v2
- .isimtrf(u, a, b) ⇒
v2
- .str(u, n) ⇒
string
object
v2(x,y) ⇒ 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
boolean
v2.isZero(u) ⇒ 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
boolan
v2.isEq(u, v) ⇒ 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
boolean
v2.isEps(u, v) ⇒ 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}
boolean
v2.isUnit(u) ⇒ 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
boolean
v2.isCartesian(u) ⇒ 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
boolean
v2.isPolar(u) ⇒ 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
number
v2.len(u) ⇒ 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
number
v2.sqr(u) ⇒ 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
number
v2.angle(u, [v]) ⇒ 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
v2.copy(u, v) ⇒ 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
v2.neg(u) ⇒ 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
v2.tilde(u) ⇒ 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
v2.unit(u) ⇒ 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}
object
v2.cartesian(u) ⇒ 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};
object
v2.polar(u) ⇒ 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};
object
v2.toPolar(u) ⇒ 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
v2.fromPolar(u) ⇒ 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
v2.sum(u, v) ⇒ 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
v2.dif(u, v) ⇒ 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};
number
v2.dot(u, v) ⇒ 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;
number
v2.perp(u, v) ⇒ 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
v2.scl(u, [s]) ⇒ 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
v2.rot(u, [w]) ⇒ 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
v2.trf(u, a, b, c, d, [e], [f]) ⇒ 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
v2.simtrf(u, [a], [b]) ⇒ 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};
object
v2.icartesian(u) ⇒ 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};
object
v2.ipolar(u) ⇒ 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
v2.ineg(u) ⇒ 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
v2.itilde(u) ⇒ 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
v2.iunit(u) ⇒ 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
v2.isum(u, v) ⇒ 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
v2.idif(u, v) ⇒ 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
v2.iscl(u, [s]) ⇒ 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
v2.irot(u, [w]) ⇒ 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
v2.itrf(u, a, b, c, d, e, f) ⇒ 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
v2.isimtrf(u, a, b) ⇒ 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};
string
v2.str(u, n) ⇒ 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)";