[AskJS] Good quality geometry, vector, etc library?
vector - Element-wise Operations In Javascript - Stack Overflow
math - javascript formula for computing the vector normal - Stack Overflow
javascript - Maths.js for Vector properties - Stack Overflow
Videos
» npm install vector-math
I'm trying to find a library that has all of these primitive types in it. You know, it has vectors, quaternions, matrix, etc.
Essentially imagine the P5 library minus all of the rendering. P5 has a massive bundle size so just using it for these parts isn't really an option.
What would you recommend?
we can use the map function to add array elements:
function addvector(a,b){
return a.map((e,i) => e + b[i]);
}
addvector([2,3,4],[4,7,90]) # returns [6,10,94]
Check out Sylvester. I think it might be what you are looking for.
But if you wanted to implement the objects yourself, then it might be better to do a more OOP approach. JavaScript is a prototype-based language, so it different a little bit from other OOP languages, but its still pretty easy to implement your own prototypes.
Something like:
Vector = function(items) {
this.items = items
}
Vector.prototype.add = function(other) {
var result = []
for(var i = 0; i < this.items; i++) {
result.push( this.items[i] + other.items[i])
}
return new Vector(result);
}
Vector.prototype.subtract = function(other) { /* code to subtract */ }
Vector.prototype.multiply = function(other) { /* code to multiply */ }
And then use them like this:
var a = new Vector([1,2,3]);
var b = new Vector([5,0,1]);
var result = a.add(b)
result.items // [6,2,4]
Or if you wanted to, you could also extend the Array class with some functions with
Array.prototype.vectorAdd = function(other) { /* code to add another array as a vector */ };
And call that using
[1,2,3].vectorAdd([5,0,1])
Hopefully, that might give you a starting point to make your code a little more readable.
Just another note: Unfortunately in this case, JavaScript doesn't support operation overloading so you can't do neat stuff like a+b. You'll have to do something like a.add(b). but as long you return an appropriate object you can chain methods together. Like:
a.add(b).multiply(c).subtract(d);
ps. the presented code might be a little "off", I just typed it up off the top of my head, so treat it more like pseduocode :)
Every vector is defined by to values eg. x and y. Length of the vector is given by equation length = sqrt(x^2+y^2). Operation of obtaining unit vertor is called normalization. As you wrote, in order to normalize vector, we divide each vector component by length.
Here's an example of implementation in JavaScript. First of all, you need to define a vector somehow. We'll create new object called Vector for that. Then we'll add a function that calculates the length and normalizes the x and y values:
class Vector {
constructor(x, y) {
this.x = x;
this.y = y;
}
get length() {
const { x, y } = this;
return (x**2 + y**2) ** 0.5;
}
normalize() {
const { length } = this;
this.x /= length;
this.y /= length;
return this;
}
}
// create an instance of Vector:
const v = new Vector(2,4);
console.log(v);
// normalize it:
const n = v.normalize();
console.log(n);
Using class syntax, separating the different steps in distinct methods, and treating vectors as immutable, you could do this:
class Vector {
constructor(x, y) {
this.x = x;
this.y = y;
Object.freeze(this);
}
norm() {
return Math.hypot(this.x, this.y);
}
scale(scalar) {
return new Vector(scalar * this.x, scalar * this.y);
}
normalize() {
return this.scale(1 / this.norm());
}
}
const v = new Vector(2, 4);
console.log(v.normalize());
If we go for an array representation, and support higher dimensions, it could become something like this:
class Vector extends Array {
norm() {
return Math.hypot(...this);
}
scale(scalar) {
return this.map(x => scalar * x);
}
normalize() {
return this.scale(1 / this.norm());
}
}
const v = new Vector(2, 4);
console.log(v.normalize());