Skip to content

Commit

Permalink
feat(vec2.ts): Implement more vector2 functionality
Browse files Browse the repository at this point in the history
Add addition, multiplication, subtraction, division, scalar multiplication, and dot products
  • Loading branch information
aszecsei committed Nov 11, 2017
1 parent 287c152 commit af463bb
Show file tree
Hide file tree
Showing 4 changed files with 4,810 additions and 69 deletions.
161 changes: 156 additions & 5 deletions src/vec2.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,120 @@
import { EPSILON } from './common'

export class Vector2 {
public x: number
public y: number
static get zero(): Vector2 {
return new Vector2([0, 0])
}
private _values = new Float32Array(2)
get x(): number {
return this._values[0]
}
get y(): number {
return this._values[1]
}
get xy(): number[] {
return [this.x, this.y]
return [this._values[0], this._values[1]]
}
set x(value: number) {
this._values[0] = value
}
set y(value: number) {
this._values[1] = value
}
set xy(values: number[]) {
this.x = values[0]
this.y = values[1]
this._values[0] = values[0]
this._values[1] = values[1]
}
constructor(values?: number[]) {
if (values) {
this.xy = values
}
}
// TODO: Cross-product
static dot(vector: Vector2, vector2: Vector2): number {
return vector.x * vector2.x + vector.y * vector2.y
}
static distance(vector: Vector2, vector2: Vector2): number {
return Math.sqrt(this.squaredDistance(vector, vector2))
}
static squaredDistance(vector: Vector2, vector2: Vector2) {
let x = vector2.x - vector.x
let y = vector2.y - vector.y
return x * x + y * y
}
static direction(vector: Vector2, vector2: Vector2, dest?: Vector2): Vector2 {
if (!dest) dest = new Vector2()
let x = vector.x - vector2.x
let y = vector.y - vector2.y
let length = Math.sqrt(x * x + y * y)
if (length === 0) {
dest.reset()
return dest
}
length = 1.0 / length
dest.x = x * length
dest.y = y * length
return dest
}
static lerp(a: Vector2, b: Vector2, t: number, dest?: Vector2): Vector2 {
if (!dest) dest = new Vector2()
dest.x = a.x + t * (b.x - a.x)
dest.y = a.y + t * (b.y - a.y)
return dest
}
static sum(vector: Vector2, vector2: Vector2, dest?: Vector2): Vector2 {
if (!dest) dest = new Vector2()
dest.x = vector.x + vector2.x
dest.y = vector.y + vector2.y
return dest
}
static difference(
vector: Vector2,
vector2: Vector2,
dest?: Vector2
): Vector2 {
if (!dest) dest = new Vector2()

dest.x = vector.x - vector2.x
dest.y = vector.y - vector2.y

return dest
}

static product(vector: Vector2, vector2: Vector2, dest?: Vector2): Vector2 {
if (!dest) dest = new Vector2()

dest.x = vector.x * vector2.x
dest.y = vector.y * vector2.y

return dest
}

static quotient(vector: Vector2, vector2: Vector2, dest?: Vector2): Vector2 {
if (!dest) dest = new Vector2()

dest.x = vector.x / vector2.x
dest.y = vector.y / vector2.y

return dest
}
at(index: number): number {
return this._values[index]
}
reset(): void {
this.x = 0
this.y = 0
}
copy(dest?: Vector2): Vector2 {
if (!dest) dest = new Vector2()
dest.xy = this.xy
return dest
}
negate(dest?: Vector2): Vector2 {
if (!dest) dest = this
dest.x = -this.x
dest.y = -this.y
return dest
}
equals(other: Vector2, threshold = EPSILON): boolean {
if (Math.abs(this.x - other.x) > threshold) {
return false
Expand All @@ -29,4 +124,60 @@ export class Vector2 {
}
return true
}
length(): number {
return Math.sqrt(this.squaredLength())
}
squaredLength(): number {
let x = this.x
let y = this.y
return x * x + y * y
}
add(vector: Vector2, dest?: Vector2): Vector2 {
if (!dest) dest = this
dest.x = this.x + vector.x
dest.y = this.y + vector.y
return dest
}
subtract(vector: Vector2, dest?: Vector2): Vector2 {
if (!dest) dest = this
dest.x = this.x - vector.x
dest.y = this.y - vector.y
return dest
}
multiply(vector: Vector2, dest?: Vector2): Vector2 {
if (!dest) dest = this
dest.x = this.x * vector.x
dest.y = this.y * vector.y
return dest
}
divide(vector: Vector2, dest?: Vector2): Vector2 {
if (!dest) dest = this
dest.x = this.x / vector.x
dest.y = this.y / vector.y
return dest
}
scale(value: number, dest?: Vector2): Vector2 {
if (!dest) dest = this
dest.x = this.x * value
dest.y = this.y * value
return dest
}
normalize(dest?: Vector2): Vector2 {
if (!dest) dest = this
dest.xy = this.xy
let length = dest.length()
if (length === 1) {
return dest
}
if (length === 0) {
dest.reset()
return dest
}
length = 1.0 / length
dest.x *= length
dest.y *= length
return dest
}
// TODO: Multiply Matrix2
// TODO: Multiply Matrix3
}
68 changes: 4 additions & 64 deletions test/ts-vector-math.test.ts
Original file line number Diff line number Diff line change
@@ -1,67 +1,7 @@
import { Vector2 } from '../src/ts-vector-math'
import * as math from '../src/ts-vector-math'

/**
* Dummy test
*/
describe('Vector2', () => {
it('is instantiable', () => {
expect(new Vector2()).toBeInstanceOf(Vector2)
})

it('can be set through swizzle', () => {
let v1 = new Vector2()
v1.xy = [1, 2]
let v2 = new Vector2()
v2.x = 1
v2.y = 2
expect(v1).toEqual(v2)
})

it('can be retrieved through swizzle', () => {
let v1 = new Vector2()
v1.xy = [1, 2]
expect(v1.xy).toEqual([1, 2])
})

it('detects non-equality', () => {
expect(new Vector2([1, 2])).not.toEqual(new Vector2([1, 1]))
expect(new Vector2([1, 2])).not.toEqual(new Vector2([2, 2]))
})

it('copies values', () => {
let v1 = new Vector2([1, 1])
let v2 = v1.copy()
v2.xy = [2, 2]
expect(v1).not.toEqual(v2)
})

it('copies values to a provided destination', () => {
let v1 = new Vector2([1, 1])
let v2 = new Vector2([1, 2])
let v3 = v1.copy(v2)
expect(v2).toEqual(v2)
expect(v1).toEqual(v2)
expect(v1).toEqual(v3)
v3.y = 3
expect(v2).toEqual(v3)
expect(v1).not.toEqual(v2)
expect(v1).not.toEqual(v3)
})

it('tests equality correctly', () => {
let v1 = new Vector2([1, 1])
let v2 = new Vector2([1, 2])
expect(v1.equals(v2)).toBeFalsy()
v2.xy = [2, 1]
expect(v1.equals(v2)).toBeFalsy()
v2.xy = [1, 1]
expect(v1.equals(v2)).toBeTruthy()
})

it('tests equality for a given threshold', () => {
let v1 = new Vector2([1, 1])
let v2 = new Vector2([2, 2])
expect(v1.equals(v2)).toBeFalsy()
expect(v1.equals(v2, 2)).toBeTruthy()
describe('Library', () => {
it('contains Vector2', () => {
expect(new math.Vector2()).toBeInstanceOf(math.Vector2)
})
})
Loading

0 comments on commit af463bb

Please sign in to comment.