1
0
Fork 0

feat: add vector library

Signed-off-by: André Jaenisch <andre.jaenisch@posteo.de>
combat-scorched-earth-from-outer-space
André Jaenisch 1 year ago
parent 1b18586497
commit 711cdbe41b
Signed by: ryuno-ki
GPG Key ID: 5A668E771F1ED854
  1. 102
      src/js/vector.js
  2. 143
      test/js/vector.test.js
  3. 79
      types/vector.d.ts

@ -0,0 +1,102 @@
/**
* @typedef {Object} Vector2D
* @property {number} x
* @property {number} y
*/
/**
* Turns two digits into a 2D Vector.
*
* @param {number} x
* @param {number} y
* @returns {Vector2D}
*/
export function Vec2 (x, y) {
return { x, y }
}
/**
* Computes the dot product of two vectors.
*
* @param {Vector2D} v
* @param {Vector2D} w
* @returns {number}
*/
export function dot (v, w) {
return v.x * w.x + v.y * w.y
}
/**
* Computes the sum of two vectors.
*
* @param {Vector2D} v
* @param {Vector2D} w
* @returns {Vector2D}
*/
export function add (v, w) {
return Vec2(v.x + w.x, v.y + w.y)
}
/**
* Computes the scalar product of a vector with a number.
*
* @param {Vector2D} v
* @param {number} n
* @returns {Vector2D}
*/
export function scale (v, n) {
return Vec2(v.x * n, v.y * n)
}
/**
* Computes the difference between two vectors.
*
* @param {Vector2D} v
* @param {Vector2D} w
* @returns {Vector2D}
*/
export function subtract (v, w) {
return add(v, scale(w, -1))
}
/**
* Computes the determinant of two vectors interpreted as 2x2 matrix.
*
* @param {Vector2D} v
* @param {Vector2D} w
* @returns {number}
*/
export function determinant (v, w) {
return v.x * w.y - v.y * w.x
}
/**
* Computes the length of a vector.
*
* @param {Vector2D} v
* @returns {number}
*/
export function length (v) {
return dot(v, v) ** 0.5
}
/**
* Computes the distance of two vectors.
*
* @param {Vector2D} v
* @param {Vector2D} w
* @returns {number}
*/
export function distance (v, w) {
return length(subtract(v, w))
}
/**
* Scale a vector so it has length 1.
*
* @param {Vector2D} v
* @returns {Vector2D}
*/
export function normalize (v) {
return scale(v, 1 / (length(v) || 1))
}

@ -0,0 +1,143 @@
import { expect } from 'chai'
import {
add,
determinant,
distance,
dot,
length,
normalize,
scale,
subtract,
Vec2,
} from '../../src/js/vector.js'
describe('Vector library', function () {
describe('Vec2', function () {
it('should turn two numbers into a vector', function () {
// Arrange
const x = 2
const y = 5
// Act
const vector = Vec2(x, y)
// Assert
expect(vector).to.have.property('x')
expect(vector).to.have.property('y')
expect(vector.x).to.equal(x)
expect(vector.y).to.equal(y)
})
})
describe('dot', function () {
it('should compute the dot product of two vectors', function () {
// Arrange
const v = Vec2(2, 5)
const w = Vec2(7, 6)
// Act
const product = dot(v, w)
// Assert
expect(product).to.equal(2 * 7 + 5 * 6)
})
})
describe('add', function () {
it('should add two vectors', function () {
// Arrange
const v = Vec2(2, 5)
const w = Vec2(7, 6)
// Act
const sum = add(v, w)
// Assert
expect(sum).to.deep.equal(Vec2(9, 11))
})
})
describe('scale', function () {
it('should compute the scalar product of a number with a vector', function () {
// Arrange
const v = Vec2(2, 5)
const n = -1
// Act
const product = scale(v, n)
// Assert
expect(product).to.deep.equal(Vec2(-2, -5))
})
})
describe('subtract', function () {
it('should subtract one vector from another', function () {
// Arrange
const v = Vec2(2, 5)
const w = Vec2(7, 6)
// Act
const difference = subtract(v, w)
// Assert
expect(difference).to.deep.equal(Vec2(2 - 7, 5 - 6))
})
})
describe('determinant', function () {
it('should compute the determinant of two vectors', function () {
// Arrange
const v = Vec2(2, 5)
const w = Vec2(7, 6)
// Act
const result = determinant(v, w)
// Assert
expect(result).to.equal(2 * 6 - 7 * 5)
})
})
describe('length', function () {
it('should compute the length of a vector', function () {
// Arrange
const v = Vec2(3, 4)
// Act
const result = length(v)
// Assert
expect(result).to.equal(5)
})
})
describe('distance', function () {
it('should compute the distance of two vectors', function () {
// Arrange
const v = Vec2(7, 9)
const w = Vec2(4, 5)
// Act
const result = distance(v, w)
// Assert
expect(result).to.equal(5)
})
})
describe('normalize', function () {
it('should normalize a vector (scale to length 1)', function () {
// Arrange
const v = Vec2(3, 4)
// Act
const normalized = normalize(v)
// Assert
expect(normalized.x).to.be.approximately(0.6, 0.001)
expect(normalized.y).to.be.approximately(0.8, 0.001)
})
})
})

79
types/vector.d.ts vendored

@ -0,0 +1,79 @@
/**
* @typedef {Object} Vector2D
* @property {number} x
* @property {number} y
*/
/**
* Turns two digits into a 2D Vector.
*
* @param {number} x
* @param {number} y
* @returns {Vector2D}
*/
export function Vec2(x: number, y: number): Vector2D;
/**
* Computes the dot product of two vectors.
*
* @param {Vector2D} v
* @param {Vector2D} w
* @returns {number}
*/
export function dot(v: Vector2D, w: Vector2D): number;
/**
* Computes the sum of two vectors.
*
* @param {Vector2D} v
* @param {Vector2D} w
* @returns {Vector2D}
*/
export function add(v: Vector2D, w: Vector2D): Vector2D;
/**
* Computes the scalar product of a vector with a number.
*
* @param {Vector2D} v
* @param {number} n
* @returns {Vector2D}
*/
export function scale(v: Vector2D, n: number): Vector2D;
/**
* Computes the difference between two vectors.
*
* @param {Vector2D} v
* @param {Vector2D} w
* @returns {Vector2D}
*/
export function subtract(v: Vector2D, w: Vector2D): Vector2D;
/**
* Computes the determinant of two vectors interpreted as 2x2 matrix.
*
* @param {Vector2D} v
* @param {Vector2D} w
* @returns {number}
*/
export function determinant(v: Vector2D, w: Vector2D): number;
/**
* Computes the length of a vector.
*
* @param {Vector2D} v
* @returns {number}
*/
export function length(v: Vector2D): number;
/**
* Computes the distance of two vectors.
*
* @param {Vector2D} v
* @param {Vector2D} w
* @returns {number}
*/
export function distance(v: Vector2D, w: Vector2D): number;
/**
* Scale a vector so it has length 1.
*
* @param {Vector2D} v
* @returns {Vector2D}
*/
export function normalize(v: Vector2D): Vector2D;
export type Vector2D = {
x: number;
y: number;
};
Loading…
Cancel
Save