MCPcopy Index your code
hub / github.com/processing/p5.js / slerp

Method slerp

src/math/p5.Vector.js:2560–2628  ·  view source on GitHub ↗

* Calculates a new heading and magnitude that are between two vectors. * * The `amt` parameter is the amount to interpolate between the old vector and * the new vector. 0.0 keeps the heading and magnitude equal to the old * vector's, 0.5 sets them halfway between, and 1.0 sets the headin

(v, amt)

Source from the content-addressed store, hash-verified

2558 * }
2559 */
2560 slerp(v, amt) {
2561 // edge cases.
2562 if (amt === 0) {
2563 return this;
2564 }
2565 if (amt === 1) {
2566 return this.set(v);
2567 }
2568
2569 // calculate magnitudes
2570 const selfMag = this.mag();
2571 const vMag = v.mag();
2572 const magmag = selfMag * vMag;
2573 // if either is a zero vector, linearly interpolate by these vectors
2574 if (magmag === 0) {
2575 this.mult(1 - amt).add(v.x * amt, v.y * amt, v.z * amt);
2576 return this;
2577 }
2578 // the cross product of 'this' and 'v' is the axis of rotation
2579 const axis = this.cross(v);
2580 const axisMag = axis.mag();
2581 // Calculates the angle between 'this' and 'v'
2582 const theta = Math.atan2(axisMag, this.dot(v));
2583
2584 // However, if the norm of axis is 0, normalization cannot be performed,
2585 // so we will divide the cases
2586 if (axisMag > 0) {
2587 axis.x /= axisMag;
2588 axis.y /= axisMag;
2589 axis.z /= axisMag;
2590 } else if (theta < Math.PI * 0.5) {
2591 // if the norm is 0 and the angle is less than PI/2,
2592 // the angle is very close to 0, so do linear interpolation.
2593 this.mult(1 - amt).add(v.x * amt, v.y * amt, v.z * amt);
2594 return this;
2595 } else {
2596 // If the norm is 0 and the angle is more than PI/2, the angle is
2597 // very close to PI.
2598 // In this case v can be regarded as '-this', so take any vector
2599 // that is orthogonal to 'this' and use that as the axis.
2600 if (this.z === 0 && v.z === 0) {
2601 // if both this and v are 2D vectors, use (0,0,1)
2602 // this makes the result also a 2D vector.
2603 axis.set(0, 0, 1);
2604 } else if (this.x !== 0) {
2605 // if the x components is not 0, use (y, -x, 0)
2606 axis.set(this.y, -this.x, 0).normalize();
2607 } else {
2608 // if the x components is 0, use (1,0,0)
2609 axis.set(1, 0, 0);
2610 }
2611 }
2612
2613 // Since 'axis' is a unit vector, ey is a vector of the same length as 'this'.
2614 const ey = axis.cross(this);
2615 // interpolate the length with 'this' and 'v'.
2616 const lerpedMagFactor = 1 - amt + (amt * vMag) / selfMag;
2617 // imagine a situation where 'axis', 'this', and 'ey' are pointing

Callers 2

p5.Camera.jsFile · 0.45
p5.Vector.jsFile · 0.45

Calls 9

setMethod · 0.95
magMethod · 0.95
multMethod · 0.95
crossMethod · 0.95
dotMethod · 0.95
_friendlyErrorMethod · 0.95
addMethod · 0.45
normalizeMethod · 0.45
copyMethod · 0.45

Tested by

no test coverage detected