Skip to content
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

Merged
merged 2 commits into from
Jun 14, 2023
Merged

use atan2 to calculate angleBetween() #6205

merged 2 commits into from
Jun 14, 2023

Conversation

inaridarkfox4231
Copy link
Contributor

@inaridarkfox4231 inaridarkfox4231 commented Jun 12, 2023

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

To eliminate the imprecision near 0 and PI, we propose a method of calculating angles using atan2.
@inaridarkfox4231
Copy link
Contributor Author

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.

@inaridarkfox4231
Copy link
Contributor Author

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.
Let me explain the advantages of this proposal.

benchmark Test

To conclude, the new angleBetween() seems to be faster than the current angleBetween().
Benchmark Test
Specifically, when executing 500000 times per frame, the average frame rate at 120 frames had the following difference.

current angleBetween(): 37-38 fps
new angleBetween(): 58-59 fps

There was the following difference at 1000000 times.

current angleBetween(): almost 20 fps
new angleBetween(): almost 33 fps

There is no unnecessary clamp processing, and the simplicity of the execution may have an effect.

Accuracy of values ​​near 0 and PI

I 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().)
First, the number of correct results:

current angleBetween(): 369295
new angleBetween(): 439400

The new angleBetween() is slightly larger, but the difference is small.
Note the number of times the values ​​deviate near 0 and PI. I checked with a margin of 5000 each.

current angleBetween() wrong at <5000: 4998 times, wrong at >499000: 4701 times
new angleBetween() wrong at <5000: 1470 times, wrong at >499000: 0 times

Accuracy is improved, especially near PI. This also shows that the new angleBetween() is superior.

@inaridarkfox4231
Copy link
Contributor Author

inaridarkfox4231 commented Jun 14, 2023

I think this is fine, so please leave a review.

@inaridarkfox4231
Copy link
Contributor Author

I'd like to add a unit test for the case shown in #6204.

@Qianqianye Qianqianye requested a review from davepagurek June 14, 2023 00:43
Actually, the difference to PI is exactly 0, but that is too strict, so I compromised.
@inaridarkfox4231
Copy link
Contributor Author

Actually, the difference to PI is exactly 0, but that is too strict, so I compromised.

Copy link
Contributor

@davepagurek davepagurek left a 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!

@davepagurek davepagurek merged commit c6d8a1b into processing:main Jun 14, 2023
@inaridarkfox4231
Copy link
Contributor Author

thanks!! ('ω')

@inaridarkfox4231 inaridarkfox4231 deleted the angleBetween_improve branch June 14, 2023 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make the value obtained by angleBetween() more accurate
2 participants