[p5.js 2.0+ Bug Report]: Vector.slerp() does not work correctly for vectors of more than three dimensions
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 24k
- Forks
- 3.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 25
Description
Most appropriate sub-area of p5.js?
- Accessibility
- Color
- Core/Environment/Rendering
- Data
- DOM
- Events
- Image
- IO
- Math
- Typography
- Utilities
- WebGL
- WebGPU
- p5.strands
- Build process
- Unit testing
- Internationalization
- Friendly errors
- Other (specify if possible)
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);
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the instance and static p5.Vector.slerp() entry points described in the issue, then reproduce the provided 4D example. Compare the current cross()-based behavior with the proposed general slerp formula, while checking that 2D and 3D results remain unchanged. Done means 4D interpolation produces the expected vector and the existing lower-dimensional behavior is preserved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100