Last active
January 21, 2019 04:26
-
-
Save lcaballero/99e71c5d1c9f532d0d3829674387d461 to your computer and use it in GitHub Desktop.
js/ts 2d Vector lib.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function isNum(x) { | |
return !isNaN(x); | |
} | |
function hasX(v) { | |
return v && isNum(v.x); | |
} | |
function hasY(v) { | |
return v && isNum(v.y); | |
} | |
function hasXY(v) { | |
return !!v && hasX(v) && hasY(v); | |
} | |
function isVec(v) { | |
return v.isVec | |
} | |
class Vector { | |
public x:number; | |
public y:number; | |
constructor() | |
constructor(x2:number=0, y2:number=0, x1:number=0, y1:number=0) { | |
this.x = x2 - x1; | |
this.y = y2 - y1; | |
} | |
sub( x, y ) { | |
return x.isVec ? | |
Vec( this.x, this.y, x.x, x.y ) : | |
Vec( this.x, this.y, x, y ); | |
} | |
add( x:Vector|number, y:Vector|number=0 ) { | |
return isVec(x) ? | |
Vec( this.x, this.y, -x.x, -x.y ) : | |
Vec( this.x, this.y, -x, -y ); | |
} | |
scaleX( xs ) { | |
return this.scale( xs, 1 ); | |
} | |
scaleY( ys ) { | |
return this.scale( 1, ys ); | |
} | |
scale( xs, ys ) { | |
return Vec( (xs || 1) * this.x, (ys || 1) * this.y, 0, 0 ); | |
} | |
translateX( xt ) { | |
return this.translate( xt, 0 ); | |
} | |
translateY( yt ) { | |
return this.translate( 0, yt ); | |
} | |
translate( xt, yt ) { | |
return Vec( this.x, this.y, -xt, -yt ); | |
} | |
get isVec() { | |
return true | |
} | |
get mag() { | |
const d = (this.x * this.x) + (this.y * this.y); | |
return Math.sqrt(d); | |
} | |
get isUpward() { | |
return this.y > 0; | |
} | |
get isDownward() { | |
return this.y < 0; | |
} | |
get isLeftward() { | |
return this.x < 0; | |
} | |
get isRightward() { | |
return this.x > 0; | |
} | |
get isNull() { | |
return this.x == 0 && this.y == 0; | |
} | |
get isVertical() { | |
return this.x == 0 && this.y != 0; | |
} | |
get isHorizontal() { | |
return this.y == 0 && this.x != 0; | |
} | |
} | |
function Vec(x2:number, y2:number, x1:number=0, y1:number=0) { | |
return new Vector(x2, y2, x1, y1); | |
} | |
export { Vec:Vec, Vector:Vector }; | |
/*************************************************** | |
tests | |
***************************************************/ | |
import { Vec, Vector } from '../src/components/Vec'; | |
import * as TestUtils from 'react-dom/test-utils'; | |
it('<3,4> add 1,0', () => { | |
const a = Vec(3,4) | |
const b = Vec(1,0) | |
const c = a.add(b) | |
expect(c.x).toEqual(4) | |
expect(c.y).toEqual(4) | |
}) | |
it('<3,4> add 0,1', () => { | |
const a = Vec(3,4) | |
const b = Vec(0,1) | |
const c = a.add(b) | |
expect(c.x).toEqual(3) | |
expect(c.y).toEqual(5) | |
}) | |
it('<1,4> translate 1,1', () => { | |
const a = Vec(1,4) | |
const c = a.translateY(1) | |
expect(c.x).toEqual(1) | |
expect(c.y).toEqual(5) | |
}) | |
it('<1,4> translate 1,1', () => { | |
const a = Vec(1,4) | |
const c = a.translateX(1) | |
expect(c.x).toEqual(2) | |
expect(c.y).toEqual(4) | |
}) | |
it('<1,4> translate 1,1', () => { | |
const a = Vec(1,4) | |
const c = a.translate(1,1) | |
expect(c.x).toEqual(2) | |
expect(c.y).toEqual(5) | |
}) | |
it('<0,0> all directions', () => { | |
const a = Vec(0,0) | |
expect(a.isRightward).toBeFalsy() | |
expect(a.isLeftward).toBeFalsy() | |
expect(a.isDownward).toBeFalsy() | |
expect(a.isUpward).toBeFalsy() | |
}) | |
it('<2,0> isRightward', () => { | |
const a = Vec(2,0) | |
expect(a.isRightward).toBeTruthy() | |
expect(a.isLeftward).toBeFalsy() | |
expect(a.isUpward).toBeFalsy() | |
expect(a.isDownward).toBeFalsy() | |
}) | |
it('<0,-2> isUpward', () => { | |
const a = Vec(0,2) | |
expect(a.isRightward).toBeFalsy() | |
expect(a.isLeftward).toBeFalsy() | |
expect(a.isDownward).toBeFalsy() | |
expect(a.isUpward).toBeTruthy() | |
}) | |
it('<0,-2> isDownward', () => { | |
const a = Vec(0,-2) | |
expect(a.isRightward).toBeFalsy() | |
expect(a.isLeftward).toBeFalsy() | |
expect(a.isDownward).toBeTruthy() | |
expect(a.isUpward).toBeFalsy() | |
}) | |
it('<2,2> scale .5', () => { | |
const a = Vec(2,2) | |
const c = a.scale(.5, .5) | |
expect(c.x).toEqual(1) | |
expect(c.y).toEqual(1) | |
}) | |
it('<2,2> scaleY .5', () => { | |
const a = Vec(2,2) | |
const c = a.scaleY(.5) | |
expect(c.x).toEqual(2) | |
expect(c.y).toEqual(1) | |
}) | |
it('<2,2> scaleX .5', () => { | |
const a = Vec(2,2) | |
const c = a.scaleX(.5) | |
expect(c.x).toEqual(1) | |
expect(c.y).toEqual(2) | |
}) | |
it('add <3,4> - <1,1>', () => { | |
const a = Vec(3,4) | |
const b = Vec(1,1) | |
const c = a.add(b) | |
expect(c.x).toEqual(4) | |
expect(c.y).toEqual(5) | |
}) | |
it('sub <3,4> - <1,1>', () => { | |
const a = Vec(3,4) | |
const b = Vec(1,1) | |
const c = a.sub(b) | |
expect(c.x).toEqual(2) | |
expect(c.y).toEqual(3) | |
}) | |
it('isVec where false', () => { | |
const v = {} | |
expect(v.isVec).toBeFalsy() | |
}) | |
it('isVec where true', () => { | |
const v = Vec() | |
expect(v.isVec).toBeTruthy() | |
}) | |
it('Vec magnitude <-3,-4>', () => { | |
const v = Vec(-3, -4) | |
expect(v.mag).toEqual(5) | |
}) | |
it('Vec magnitude <0,0>', () => { | |
const v = Vec(0, 0) | |
expect(v.mag).toEqual(0) | |
}) | |
it('Vec magnitude <3,4>', () => { | |
const v = Vec(3, 4) | |
expect(v.mag).toEqual(5) | |
}) | |
it('Vec() produces <0,0>', () => { | |
const v = Vec() | |
expect(v.x).toEqual(0) | |
expect(v.y).toEqual(0) | |
}) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment