diff --git a/src/2d.js b/src/2d.js new file mode 100644 index 0000000..914e658 --- /dev/null +++ b/src/2d.js @@ -0,0 +1,85 @@ +function sqr(x) { + return x * x; +} + +export class Vec2 { + constructor(x, y) { + this.x = x || 0; + this.y = y || 0; + } + + add(y) { + return new Vec2(this.x + y.x, this.y + y.y); + } + + sub(y) { + return new Vec2(this.x - y.x, this.y - y.y); + } + + mul(k) { + return new Vec2(this.x * k, this.y * k); + } + + conj() { + return new Vec2(this.x, -this.y); + } + + yx() { + return new Vec2(this.y, this.x); + } + + complexMul(y) { + return new Vec2(this.x * y.x - this.y * y.y, this.x * y.y + this.y * y.x); + } + + complexInv() { + return this.conj().mul(1 / this.norm()); + } + + complexDiv(y) { + return this.complexMul(y.complexInv()); + } + + addTo(y) { + this.x += y.x; + this.y += y.y; + } + + subTo(y) { + this.x -= y.x; + this.y -= y.y; + } + + mulTo(k) { + this.x *= k; + this.y *= k; + } + + equal(y) { + return this.x == y.x && this.y == y.y; + } + + arg() { + return Math.atan2(this.y, this.x); + } + + abs() { + return Math.sqrt(this.norm()); + } + + norm() { + return sqr(this.x) + sqr(this.y); + } + + clone() { + return new Vec2(this.x, this.y); + } + + dot(y) { + return this.x * y.x + this.y * y.y; + } + + cross(y) { + return this.x * y.y - this.y * y.x; + } +} \ No newline at end of file diff --git a/tests/2d.test.js b/tests/2d.test.js new file mode 100644 index 0000000..6c603a0 --- /dev/null +++ b/tests/2d.test.js @@ -0,0 +1,52 @@ +import assert from 'node:assert'; +import { Vec2 } from '../src/2d.js'; + +describe('Vec2', function () { + it('construct', function() { + let p = new Vec2(1, 2); + assert.equal(p.x, 1); + assert.equal(p.y, 2); + }); + + it('equal', function() { + assert.ok((new Vec2(1, 2)).equal(new Vec2(1, 2))); + assert.ok(!(new Vec2(1, 2)).equal(new Vec2(1, 12))); + }); + + it('vector calculation', function() { + let p = new Vec2(2, 4), q = new Vec2(3, 1); + assert.ok(p.add(q).equal(new Vec2(5, 5))); + assert.ok(p.sub(q).equal(new Vec2(-1, 3))); + assert.ok(p.mul(1.5).equal(new Vec2(3, 6))); + assert.ok(p.yx().equal(new Vec2(4, 2))); + }); + + it('vector calculation(TO)', function () { + let p = new Vec2(2, 4), q = new Vec2(3, 1); + p.addTo(q); + assert.ok(p.equal(new Vec2(5, 5))); + p.subTo(q); + assert.ok(p.equal(new Vec2(2, 4))); + p.mulTo(1.5); + assert.ok(p.equal(new Vec2(3, 6))); + }); + + it('abs & norm', function() { + let p = new Vec2(3, 4); + assert.equal(p.abs(), 5); + assert.equal(p.norm(), 25); + }); + + it('complex calculation', function() { + let p = new Vec2(1, 4), q = new Vec2(0, 1); + assert.ok(p.complexMul(q).equal(new Vec2(-4, 1))); + assert.ok(p.complexDiv(q).equal(new Vec2(4, -1))); + assert.equal(q.arg(), Math.PI / 2); + }); + + it('dot & cross product', function() { + let p = new Vec2(2, 4), q = new Vec2(3, 1); + assert.equal(p.dot(q), 10); + assert.equal(p.cross(q), -10); + }); +}); \ No newline at end of file