diff --git a/README.md b/README.md index 389c9b5..e2dc109 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # vec3 + [![NPM version](https://img.shields.io/npm/v/vec3.svg)](http://npmjs.com/package/vec3) [![Build Status](https://github.com/PrismarineJS/node-vec3/workflows/CI/badge.svg)](https://github.com/PrismarineJS/node-vec3/actions?query=workflow%3A%22CI%22) @@ -7,7 +8,7 @@ ## Usage ```js -var v = require('vec3'); +var v = require("vec3"); var v1 = v(1, 2, 3); console.log(v1); // prints "(1, 2, 3)" @@ -18,7 +19,7 @@ console.log(v2); // prints "(1, 2, 4)" Or: ```js -var Vec3 = require('vec3').Vec3; +var Vec3 = require("vec3").Vec3; var v1 = new Vec3(1, 2, 3); // etc... @@ -55,6 +56,7 @@ More available functions are listed below in Test Coverage. ✔ minus ✔ scaled ✔ abs + ✔ angleTo ✔ distanceTo ✔ distanceSquared ✔ equals diff --git a/index.d.ts b/index.d.ts index b40b99f..d0d0ef9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -126,6 +126,11 @@ export class Vec3 { */ modulus(other: Vec3): Vec3; + /** + * Return the angle in rad between another vector and this one + */ + angleTo(other: Vec3): number; + /** * Return the euclidean distance to another vector */ diff --git a/index.js b/index.js index 9a0f76b..5f2f035 100644 --- a/index.js +++ b/index.js @@ -133,6 +133,10 @@ class Vec3 { euclideanMod(this.z, other.z)) } + angleTo (other) { + return Math.acos(this.dot(other) / (this.norm() * other.norm())) + } + distanceTo (other) { const dx = other.x - this.x const dy = other.y - this.y diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 896d491..8915c15 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -39,6 +39,7 @@ expectType(vec.scaled(2)); expectType(vec.abs()); expectType(vec.volume()); expectType(vec.modulus(vec)); +expectType(vec.angleTo(vec)); expectType(vec.distanceTo(vec)); expectType(vec.distanceSquared(vec)); expectType(vec.equals(vec)); diff --git a/test/test.js b/test/test.js index 1c24eec..72cb437 100644 --- a/test/test.js +++ b/test/test.js @@ -182,6 +182,24 @@ describe('vec3', function () { assert.strictEqual(v2.y, 1.5) assert.strictEqual(v2.z, 1.9) }) + it('angleTo', function () { + const v1 = new Vec3(1, 1, 1) + const v2 = new Vec3(1, 0, 0) + const angle1 = v1.angleTo(v2) + const angle2 = v2.angleTo(v1) + const expected = 0.9553166181 + assert.strictEqual(angle1, angle2) + assert.strictEqual(Math.round(angle1 * 100000), Math.round(expected * 100000)) + }) + it('angleToNullVectors', function () { + const v1 = new Vec3(0, 0, 0) + const v2 = new Vec3(0, 0, 0) + const angle1 = v1.angleTo(v2) + const angle2 = v2.angleTo(v1) + const expected = NaN + assert.strictEqual(angle1, angle2) + assert.strictEqual(Math.round(angle1 * 100000), Math.round(expected * 100000)) + }) it('distanceTo', function () { const v1 = new Vec3(1, 1, 1) const v2 = new Vec3(2, 2, 2)