-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
use atan2 to calculate angleBetween() #6205
use atan2 to calculate angleBetween() #6205
Conversation
To eliminate the imprecision near 0 and PI, we propose a method of calculating angles using atan2.
If the execution speed of atan2 is an issue, I may change the content so that at least the results are correct when the two vectors are clearly parallel. |
I was mistaken. The performance issue was pointed out to me, so I thought it might be slower, so I looked it up, but it's the opposite. benchmark TestTo conclude, the new angleBetween() seems to be faster than the current angleBetween(). current angleBetween(): 37-38 fps There was the following difference at 1000000 times. current angleBetween(): almost 20 fps There is no unnecessary clamp processing, and the simplicity of the execution may have an effect. Accuracy of values near 0 and PII compared the accuracy when calculating the angle directly from cos and sin with the following code. We examined separately whether there is difference in values, especially near 0 and PI. function setup() {
createCanvas(600, 400);
let v, w;
v = createVector(1,0);
w = createVector();
let isTrue = 0;
let isTrue2 = 0;
let isWrongSmall = 0;
let isWrongSmall2 = 0;
let isWrongBig = 0;
let isWrongBig2 = 0;
for(let i=0; i<500000; i++){
const t = PI*i/500000;
w.set(cos(t), sin(t));
if(v.angleBetween(w) === t){ isTrue++; }
else if(i < 5000){ isWrongSmall++; }
else if(i > 495000){ isWrongBig++; }
if(v.angleBetween2(w) === t){ isTrue2++; }
else if(i < 5000){ isWrongSmall2++; }
else if(i > 495000){ isWrongBig2++; }
}
console.log(isTrue, isTrue2);
console.log(isWrongSmall, isWrongSmall2);
console.log(isWrongBig, isWrongBig2);
} (Note that angleBetween2() is the new angleBetween().) current angleBetween(): 369295 The new angleBetween() is slightly larger, but the difference is small. current angleBetween() wrong at <5000: 4998 times, wrong at >499000: 4701 times Accuracy is improved, especially near PI. This also shows that the new angleBetween() is superior. |
I think this is fine, so please leave a review. |
I'd like to add a unit test for the case shown in #6204. |
Actually, the difference to PI is exactly 0, but that is too strict, so I compromised.
Actually, the difference to PI is exactly 0, but that is too strict, so I compromised. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this is a win across the board by being slightly faster and more accurate, great work!
thanks!! ('ω') |
Currently angleBetween() computes the angle using only the inner product, so values near 0 and PI are inaccurate.
To solve this, I would like to use atan2 to calculate the angle.
Resolves #6204
Changes:
Instead of using only the inner product to produce the value, rewrite it so that it produces the value using the inner product and the outer product.
On the other hand, the method of adding signs and the method of handling exceptions are completely the same as before.
PR Checklist
npm run lint
passes