UNPKG

vector2d-extended

Version:
442 lines (350 loc) 8.54 kB
function toFixed (number: number, fixed: number = 0): number { const fix = Math.pow(10, fixed); return Math.floor(number * fix) / fix; } class Vector2d { constructor (public x: number = 0, public y: number = 0) {} toString () { return '{x:' + this.x + ',y:' + this.y + '}'; } static get ZERO (): Vector2d { return new Vector2d(); } static get ONE (): Vector2d { return new Vector2d(1, 1); } static get UP (): Vector2d { return new Vector2d(0, -1); } static get DOWN (): Vector2d { return new Vector2d(0, 1); } static get RIGHT (): Vector2d { return new Vector2d(1, 0); } static get LEFT (): Vector2d { return new Vector2d(-1, 0); } static clampMagnitude (a: Vector2d, maxLength: number): Vector2d { return a.clone().clampMagnitude(maxLength); } static lerp (a: Vector2d, b: Vector2d, l: number): Vector2d { return a.clone().lerp(b, l); } static scale (a: Vector2d, b: Vector2d): Vector2d { return a.clone().scaleX(b).scaleY(b); } static scaleX (a: Vector2d, b: Vector2d): Vector2d { return new Vector2d(a.x, 0).scaleX(b); } static scaleY (a: Vector2d, b: Vector2d): Vector2d { return new Vector2d(0, a.y).scaleY(b); } static add (a: Vector2d, b: Vector2d): Vector2d { return a.clone().addX(b).addY(b); } static addX (a: Vector2d, b: Vector2d): Vector2d { return new Vector2d(a.x, 0).addX(b); } static addY (a: Vector2d, b: Vector2d) { return new Vector2d(0, a.y).addY(b); } static subtract (a: Vector2d, b: Vector2d): Vector2d { return a.clone().subtractX(b).subtractY(b); } static subtractX (a: Vector2d, b: Vector2d): Vector2d { return new Vector2d(a.x, 0).subtractX(b); } static subtractY (a: Vector2d, b: Vector2d): Vector2d { return new Vector2d(0, a.y).subtractY(b); } static multiply (a: Vector2d, b: number): Vector2d { return a.clone().multiplyX(b).multiplyY(b); } static multiplyX (a: Vector2d, b: number): Vector2d { return a.clone().multiplyX(b); } static multiplyY (a: Vector2d, b: number): Vector2d { return a.clone().multiplyY(b); } static divide (a: Vector2d, b: number): Vector2d { return a.clone().divideX(b).divideY(b); } static divideX (a: Vector2d, b: number): Vector2d { return a.clone().divideX(b); } static divideY (a: Vector2d, b: number): Vector2d { return a.clone().divideY(b); } static normalize (a: Vector2d): Vector2d { return a.clone().normalize(); } static project (a: Vector2d, b: Vector2d): Vector2d { return a.clone().project(b); } static round (a: Vector2d): Vector2d { return a.clone().round(); } static roundX (a: Vector2d): Vector2d { return a.clone().roundX(); } static roundY (a: Vector2d): Vector2d { return a.clone().roundY(); } static invert (a: Vector2d): Vector2d { return a.clone().invert(); } static invertX (a: Vector2d): Vector2d { return a.clone().invertX(); } static invertY (a: Vector2d): Vector2d { return a.clone().invertY(); } // Methods // Returns Vector2d set (x: number, y: number): Vector2d { this.x = x; this.y = y; return this; } add (a: Vector2d): Vector2d { return this.addX(a).addY(a); } addX (a: Vector2d): Vector2d { this.x += a.x; return this; } addY (a: Vector2d): Vector2d { this.y += a.y; return this; } subtract (a: Vector2d): Vector2d { return this.subtractX(a).subtractY(a); } subtractX (a: Vector2d): Vector2d { this.x -= a.x; return this; } subtractY (a: Vector2d): Vector2d { this.y -= a.y; return this; } multiply (a: number): Vector2d { return this.multiplyX(a).multiplyY(a); } multiplyX (a: number): Vector2d { this.x *= a; return this; } multiplyY (a: number): Vector2d { this.y *= a; return this; } divide (a: number): Vector2d { return this.divideX(a).divideY(a); } divideX (a: number): Vector2d { this.x /= a; return this; } divideY (a: number): Vector2d { this.y /= a; return this; } normalize (): Vector2d { this.magnitude = 1; return this; } project (b: Vector2d): Vector2d { const c: number = this.dot(b) / b.magnitudeSquared; return this.equate(b).multiply(c); } round (): Vector2d { return this.roundX().roundY(); } roundX (): Vector2d { this.x = Math.round(this.x); return this; } roundY (): Vector2d { this.y = Math.round(this.y); return this; } zero (): Vector2d { return this.zeroX().zeroY(); } zeroX (): Vector2d { this.x = 0; return this; } zeroY (): Vector2d { this.y = 0; return this; } clone (): Vector2d { return new Vector2d(this.x, this.y); } equate (b: Vector2d): Vector2d { return this.equateX(b).equateY(b); } equateX (b: Vector2d): Vector2d { this.x = b.x; return this; } equateY (b: Vector2d): Vector2d { this.y = b.y; return this; } invert (): Vector2d { return this.invertX().invertY(); } invertX (): Vector2d { this.x = -this.x; return this; } invertY (): Vector2d { this.y = -this.y; return this; } lerp (b: Vector2d, l: number): Vector2d { if (l < 0) { l = 0; } else if (l > 1) { l = 1; } return this.set(this.x + (b.x - this.x) * l, this.y + (b.y - this.y) * l); } scale (a: Vector2d): Vector2d { return this.scaleX(a).scaleY(a); } scaleX (a: Vector2d): Vector2d { this.x *= a.x; return this; } scaleY (a: Vector2d): Vector2d { this.y *= a.y; return this; } clampMagnitude (maxLength: number): Vector2d { if (this.magnitudeSquared > maxLength * maxLength) { this.magnitude = maxLength; } return this; } // Returns number get rotate (): number { return Math.atan2(this.y, this.x); } set rotate (dir: number) { const len: number = this.magnitude; const x: number = Math.cos(dir) * len; const y: number = Math.sin(dir) * len; this.set( toFixed(x, 10), toFixed(y, 10) ); } get magnitudeSquared (): number { return this.dot(this); } set magnitudeSquared (value: number) { this.magnitude = Math.sqrt(value); } get magnitude (): number { return Math.sqrt(this.magnitudeSquared); } set magnitude (value: number) { const magnitude: number = this.magnitude; this.divide(magnitude).multiply(value); } dot (b: Vector2d): number { return this.x * b.x + this.y * b.y; } cross (b: Vector2d): number { return this.x * b.y - this.y * b.x; } distance (b: Vector2d): number { return Math.sqrt(this.distanceSquared(b)); } distanceSquared (b: Vector2d): number { const dx: number = this.x - b.x; const dy: number = this.y - b.y; return dx * dx + dy * dy; } angle (b: Vector2d): number { const aMagnitude: number = this.magnitude; const bMagnitude: number = b.magnitude; let dot = (this.x/aMagnitude) * (b.x/bMagnitude) + (this.y/aMagnitude) * (b.y/bMagnitude); if (dot < -1) { dot = -1; } else if (dot > 1) { dot = 1; } return Math.acos(dot); } areaTriangle (b: Vector2d): number { return this.areaParallelogram(b) / 2; } areaParallelogram (b: Vector2d): number { return Math.abs(this.cross(b)); } // Returns boolean isZero (): boolean { return this.isZeroX() && this.isZeroY(); } isZeroX (): boolean { return this.x === 0; } isZeroY (): boolean { return this.y === 0; } isEqual (b: Vector2d): boolean { return this.isEqualX(b) && this.isEqualY(b); } isEqualX (b: Vector2d): boolean { return this.x === b.x; } isEqualY (b: Vector2d): boolean { return this.y === b.y; } isNaN (): boolean { return this.isNaNX() || this.isNaNY(); } isNaNX (): boolean { return isNaN(this.x); } isNaNY (): boolean { return isNaN(this.y); } isFinite (): boolean { return this.isFiniteX() || this.isFiniteY(); } isFiniteX (): boolean { return isFinite(this.x); } isFiniteY (): boolean { return isFinite(this.y); } isEqualRotate (b: Vector2d): boolean { return toFixed(this.rotate, 2) === toFixed(b.rotate, 2); } isEqualInvertRotate (b: Vector2d): boolean { const ref = Math.abs(toFixed(this.rotate, 6) - toFixed(b.rotate, 6)); return (3.14158 < ref && ref < 3.14160); } isCollinear (b: Vector2d): boolean { if (this.isZeroX() || this.isZeroY() || b.isZeroX() || b.isZeroY()) { const an: number = this.isZeroX() && !this.isZeroY() ? this.y : this.x; const bn: number = b.isZeroX() && !b.isZeroY() ? b.y : b.x; const n: number = bn / an; const nax: number = this.x * n; const nay: number = this.y * n; return b.x === nax && b.y === nay; } return this.x / b.x === this.y / b.y; } isOrthogonal (b: Vector2d): boolean { return this.dot(b) === 0; } }; export default Vector2d;