-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug in Vector.lerp() implementation #21
Comments
Is the solution to just to remove Could you also please show an example of correct output for this function? |
p5js' lerp() reference: https://p5js.org/reference/#/p5.Vector/lerp My Processing Pjs-based implementation: |
My solution to this was just to do this, ha! This is technically faster than what @LingDong- had before as well, creating new objects takes longer than just calling the function on the first vector inputted. Vector.add = (v, u) => v.add(u);
Vector.rem = (v, u) => v.rem(u);
Vector.sub = (v, u) => v.sub(u);
Vector.mult = (v, u) => v.mult(u);
Vector.div = (v, u) => v.div(u);
Vector.dist = (v, u) => v.dist(u);
Vector.cross = (v, u) => v.cross(u);
Vector.lerp = (v, u, t) => v.lerp(u, t);
Vector.equals = (v, u, epsilon) => v.equals(u, epsilon); The lerp implementation in the Vector class looks correct to me. |
Static methods aren't supposed to mutate its passed arguments! 🙅 Take for example this implementation of static method PVector.add(): 👓 PVector.add = (v1, v2, t) =>
t? t.set(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z)
: new PVector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); Neither parameters v1 & v2 are ever mutated there. 🔒 Instead, either a BtW, file PVector.js is a close implementation of class PVector from Processing Java, which p5js more or less follows. ☕ Actually, p5js' implementation of its static method p5.Vector.add() also has a 3rd parameter that serves the same purpose as Java Mode's PVector.add(): 😻 |
ahh! okay I understand. I'll have to revert those changes
…On Sun, Feb 12, 2023 at 22:40 GoToLoop ***@***.***> wrote:
, creating new objects takes longer than just calling the function on the
first vector inputted.
Static methods aren't supposed to mutate its passed arguments! 🙅
Take for example this implementation of static method *PVector*.*add()*:
👓
https://Gist.GitHub.com/GoToLoop/acbf106aa784820aff23#file-pvector-js-L56-L58
PVector.add = (v1, v2, t) =>
t? t.set(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z)
: new PVector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
Neither parameters *v1* & *v2* are ever mutated there. 🔒
Instead, either a new *PVector* is created or the method relies on
parameter *t* to store the result.
BtW, file PVector.js
<https://gist.github.com/GoToLoop/acbf106aa784820aff23#file-pvector-js>
is a close implementation of class *PVector* from Processing Java, which
p5js more or less follows. ☕
Actually, p5js' implementation of its *p5.Vector*.*add()* also has a 3rd
parameter that serves the same purpose as Java Mode's *PVector*.*add()*.
😻
—
Reply to this email directly, view it on GitHub
<https://github.com/LingDong-/q5xjs/issues/21#issuecomment-1427290787>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEY2RQ3AGN2CWWUZ5GZRVV3WXGUJPANCNFSM6AAAAAAUUZKB5M>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Done, thank you! I still need to fix lerp though. |
Have you looked at my PVector.lerp() implementation?
|
Not yet and clearly this is an area of the project I know very little about 😅 Do you think you'd be able to make the fix and do a pull request to my repo? |
const
lerp = (start, stop, amt = 0) => +start + amt*(stop - start),
argsErr = (mtd, len, min) => {
throw `Too few args passed to ${mtd}() [${len} < ${min}].`;
};
function PVector(x, y, z) {
this.x = x || 0, this.y = y || 0, this.z = z || 0;
}
PVector.lerp = (v1, v2, amt, t) => (t && t.set(v1) || v1.copy()).lerp(v2, amt);
PVector.prototype.lerp = function (a, b, c, d) {
let x, y, z, amt;
const len = arguments.length;
if (len < 2) argsErr('lerp', len, 2);
if (len === 2) { // given vector and amt
({x, y, z} = a), amt = b;
} else if (len === 3) { // given vector 1, vector 2 and amt
return PVector.lerp(a, b, c);
} else { // given x, y, z and amt
[x, y, z, amt] = arguments;
}
return this.set(lerp(this.x, x, amt),
lerp(this.y, y, amt),
lerp(this.z, z, amt));
};
PVector.prototype.copy = function () {
return new PVector(this.x, this.y, this.z);
};
PVector.prototype.set = function (v, y, z) {
if (y != void 0) this.x = +v, this.y = +y, z != void 0 && (this.z = +z);
else this.set(v[0] || v.x || 0, v[1] || v.y || 0, v[2] || v.z);
return this;
}; |
That's true, I will change it to use an ES6 class! |
Actually I'm doing it right now. 😆 Just starting though: 👲 "use strict";
function Q5(scope, parent) {
const $ = this;
$.createVector = (x, y, z) => new $.Vector(x, y, z);
Q5.Vector = $.Vector = class Vector {
constructor(x, y, z) {
this.x = x || 0, this.y = y || 0, this.z = z || 0;
this._deleteMagCache();
}
_deleteMagCache() {
this._magSq = this._mag = null;
}
_calcMagCache() {
if (this._magSq == null)
this._magSq = (this._mag = Math.hypot(this.x, this.y, this.z)) ** 2;
}
};
} |
Just finished and I tested it this time! I moved the Vector class to the bottom of the file and now it is only created once and uses ES6 classes. https://github.com/quinton-ashley/q5.js/blob/main/q5.js |
It doesn't seem correct to me! How is such an independent class now able to use Q5 instance functions like $.cos(), $.sin(), $.tan(), $.atan2()? |
ah! good catch |
Okay I think it's good now: |
There seems to be a bug with the implementation of Vector.lerp() function
The function change the value of y and z coordinate of the first param vector, which don't seems to be intended (it should not modify any value of the first param vector)
The text was updated successfully, but these errors were encountered: