Yellow-Dog-Man / Resonite-Issues

Issue repository for Resonite.
https://resonite.com
141 stars 2 forks source link

Slerp inaccuracies when close to 180° #3008

Closed mpmxyz closed 2 months ago

mpmxyz commented 2 months ago

Describe the bug?

The computation of Slerp is inaccurate when the angle between the input vectors approaches 180°. This can lead to unexpected animation paths. Reverse engineering found that the difference between one input vector and the projection of the other on it approaches 0 which will make the direction almost random. The difference is then normalized which will cause the unexpected results.

To Reproduce

You can use a premade item that draws the result vectors: resrec:///U-TheAutopilot/R-e19ee6b8-38c1-408f-96ab-22995f8cdaaa Clicking Call draws debug vectors.

Expected behavior

The arrows should be drawn in a circle. ~or a straight line and only between the points. (straight line only when angle is too small to reliably determine the circle direction OR never if a random direction should be chosen)~

Screenshots

The following images allow a comparison between different precisions. Float: grafik Double: grafik

Resonite Version Number

2024.9.16.1105

What Platforms does this occur on?

Windows

What headset if any do you use?

No response

Log Files

Anonymous - 2024.9.16.1105 - 2024-09-26 21_30_24.log (not really relevant)

Additional Context

No response

Reporters

No response

Frooxius commented 2 months ago

I don't think this is really a bug.

Slerp will take the shortest possible path between two vectors, to ensure that the distance traveled is minimal and equal to the angle between the vectors. In most cases, this leaves only one possible path.

However consider when the vectors are exactly opposite - they're at 180° degrees. At that point all possible paths are valid paths - because they will all take the same amount of travel distance - they're all valid paths. This means that the path you get will be effectively random - whichever way the floating point wind blows - any small difference will tip it over to that particular direction.

If you need them to take particular path and you're working with angles like this, you'll have to do some extra work to nudge it towards particular direction you want it to take.

What you're asking for in the expected behavior is also contrary to what Slerp is - it stands to spherical linear interpolation, which means the interpolated points will follow a surface of a sphere.

Going along a line is contrary to that as that would require it to go through the sphere. If you want the points to go along a line, you'll have to use Lerp instead, which is just regular linear interpolation.

mpmxyz commented 2 months ago

I reread my infos about Slerp and noticed I misunderstood the linear interpolation part. (The document only mentioned angles close to 0 and not their sine close to 0.) I also didn't notice how close to 180° you need to be to oberserve the behavior. I probably messed up my numbers when I was helping a user out with the original problem but the difference needs to be less than 0.1°. Sorry for bothering you with non-issues!