Open MagnuzBinder opened 1 year ago
Thanks for adding your first issue to Stellarium. If you have questions, please do not hesitate to contact us.
Can of worms, yes. We can probably remedy to 0.0001 but not much closer, or do what has to be done also for these movements. Who wants to rewrite StelMovementMgr with quaternions?
Hello @MagnuzBinder!
OK, developers can reproduce the issue. Thanks for the report!
Who wants to rewrite StelMovementMgr with quaternions?
Anyone who's going to do this: don't even think of using QQuaternion
! It's limited to float
precision.
Lowering the difference from 0.01 to 0.0001 reduces the problem area by 99%, which would be welcome. I just wonder, why not 0.000001? This would still mean a vector perpendicular to zenith/nadir that is 0.001414 units long, meaning a relative precision better than 0.0001, if assuming unit vectors and there being some single float calculation somewhere processing it.
As for quaternion libraries, would ferd36's quaternion ( https://github.com/ferd36/quaternions ) do, at least as a starting point? It may be a bit old (2015), but quaternions haven't changed any since 1843 (or 1819 if we give credit to their first real inventor Gauss instead of Hamilton), it seems mathematically correct and sanely written at a first glance, supports both single, double and long double precision, and it's MIT open source, so it can be modified if needed.
As for rewriting StelMovementMgr, I wish I could help, but I'm no C++ programmer, even if I can read the code. I agree the best would be to rewrite StelMovementMgr to proper geometric projection handling, using e.g. quaternions. However, there is a simple and ugly hack that can mitigate the problem, pseudocode: Init: upVectorLastValid = upVectorMountFrame; Main: if (abs(upVectorMountFrame[2]) > 0.000001) upVectorLastValid = upVectorMountFrame; else upVectorMountFrame = upVectorLastValid;
It can also be good knowing what the up vector is used for. I haven't gone through the Stellarium code base, but in two other 3D projects I've worked with, the up vector is only used to calculate the camera transform matrix like: Camera front vector = normalized(front vector) Camera side vector = normalized(front vector X up vector) Camera up vector = Camera side vector X Camera front vector) Used in this way, the up vector doesn't need to be "up" at all, just in the vertical plane the front vector is in and with z/[2] > 0, which makes it easier to form a usable up vector.
Expected Behaviour
When moving to zenith or nadir (±90° altitude) in Search window : Position : Horizontal, azimuth is expected to be unchanged in main view and Search window.
Actual Behaviour
When moving to abs(altitude) > arcsin(0.99) ≈ 81.890386° in Search window : Position : Horizontal, azimuth jumps to some other value in main view but is unchanged and thereby faulty in Search window.
Steps to reproduce
Set FOV to 180°, enter e.g. 0°, 90°, 180° or 270° in Search window : Position : Horizontal, azimuth field and then e.g. 85° in altitude field, and see the view and cardinal points suddenly jump to unexpected directions after the initial correct rotation (cardinal points N S E W should be and stay up down right left).
System
Comment
The cause is most probably stellarium/src/core/StelMovementMgr.cpp line 1151 in Stellarium 23.3: if (fabs((fabs(viewDirectionMountFrame.v[2]) - 1.)) < 0.01 ) Introduced in PR #2659 2022-09-18 Not a problem in Stellarium 0.19.1.
The above causes azimuth to jump if abs(sin(altitude)) > 1 - 0.01, i.e. abs(altitude) > arcsin(1 - 0.01) ≈ 81.890386°
If it is possible to lower the difference below 0.01, it would reduce this problem, but I'm not sure it won't cause instability elsewhere, unless precision is consistently double: 0.01 => 81.890386° 0.001 => 87.437441° 0.0001 => 89.189709° 0.00001 => 89.743765° 0.000001 => 89.918972° 0.0000001 => 89.974377° 0.00000001 => 89.991897°
I read the Zenith scripting issue #754, so I know this is a can of worms you may not want to dig into again, but this bug is a new, non-script-related, manifestation of the same basic problem with sub-optimally written geometric projection handling.
Also, the extra space between "0.01" and ")" could be removed for consistency if you do something about the code.