Most appropriate sub-area of p5.js?
p5.js version
2.3.0
Web browser and version
Brave 1.90.122
Operating system
Linux Mint 22.1
Steps to reproduce this
Steps:
- Create two 4D vectors
- Use slerp() to interpolate between the two
- Note the result is incorrect
Snippet:
function setup() {
let c = 0.5;
let v1 = createVector(0, 1, 0, 1);
let v2 = createVector(1, 0, 1, 0);
v1.slerp(v2, 0.5);
// v1 should be vector[0.707, 0.707, 0.707, 0.707] but is actually vector[0.5, 0.707, 0.5, 1]
print(v1.toString());
}
Discussion
slerp() currently uses cross() for its computation, which is only defined for 3D vectors. It needs to use a more general formula, which is readily available on the web; search for "slerp formula".
Feel free to adapt the following (to both the instance and static methods). In my brief testing, it gives the same result as the current slerp() for 2D and 3D vectors, and also seems to work correctly for 4D vectors. It can certainly be optimized.
function slerp(v0, v1, t) {
let m = v0.mag() + (v1.mag() - v0.mag()) * t;
let r0 = p5.Vector.normalize(v0);
let r1 = p5.Vector.normalize(v1);
let a = acos(r0.dot(r1));
if (a === 0) {
return p5.Vector.add(v0, p5.Vector.sub(v1, v0).mult(t));
} else {
r0.mult(sin((1 - t) * a) / sin(a));
r1.mult(sin(t * a) / sin(a));
return r0.add(r1).mult(m);
}
}
Most appropriate sub-area of p5.js?
p5.js version
2.3.0
Web browser and version
Brave 1.90.122
Operating system
Linux Mint 22.1
Steps to reproduce this
Steps:
Snippet:
Discussion
slerp()currently usescross()for its computation, which is only defined for 3D vectors. It needs to use a more general formula, which is readily available on the web; search for "slerp formula".Feel free to adapt the following (to both the instance and static methods). In my brief testing, it gives the same result as the current
slerp()for 2D and 3D vectors, and also seems to work correctly for 4D vectors. It can certainly be optimized.