I’m implementing a compass overlay that rotates based on the camera heading. When users drag from the top of the viewport to tilt the camera, the compass suddenly flips between two headings (approximately 0° and 180°). This happens during the drag motion itself, not at any specific pitch angle, and only occurs when dragging from the top of the screen.
Here’s an example sandcastle of my implementation: Sandcastle
Has anyone encountered this behavior before or know what might be causing these sudden heading flips during top-down drag interactions? Is there a way to prevent that from happening?
Please let us know if you have further questions and if one of these resources is able to help you arrive at a solution. And it would be great to share your findings on the current best approach to this problem for the benefit of other community users.
I’m not looking for an implementation of a compass. Instead, I’m trying to understand the reason behind the odd behavior where the heading value flips when you drag from a specific point on the screen. If you open the Sandcastle example I posted, you’ll see exactly what I mean.
The compass n the sandcastle is included for convenience, but you could just as easily use console.log to observe the camera’s heading and still notice the issue.
If you mean the sudden flip that happens when your camera is looking from above to the surface, it is related to Euler angle singularity/gimbal lock. This is a well-known phenomena when using Euler angles. It also happens in this widget, try tilting and moving around, the N in the compass makes sudden flips (can’t say when because there is no earth as reference).: Cesium-Navigation Example (standalone)
What I observe is, when you start dragging from bottom of the view, the camera tilt angles goes up to the 89.999 (but not 90), there is a limit that stops you going beyond 90 degree of pitch angle.
However, when you start dragging from top of the view, it goes beyond 90+epsilon (small value)
When you go beyond 90 degrees, the problem arises, the “view camera” flips. This flip of the camera makes your front back, as your camera starts looking to the other side. The arrow shows the correct way, but you (the camera) is flipped.
You can confirm the problem visually, try dragging from bottom of the view and you will be limited to a certain angle, say 89.9999. At that moment, try dragging from top part of the view, you will see some additional rotation.
The reason why it happens on the top point but not on the bottom point may be implementation specific or a bug.
One possible solution may be to limit the maximum tilt/pitch angle of the camera programmatically.
That’s what I was thinking, but I wanted confirmation from someone in Cesium and suggestions for possible solutions.
I tried to implement this before posting, but couldn’t get it to work.
From what I could tell there’s no built-in way to limit maximum tilt in Cesium (There is maximumTiltAngle, but it limits the other direction of tilting).
Also, when I tried to do it myself with listening to camera.changed and calling camera.setView it didn’t work well and I was having difficulty detecting when the tilt is bad, since in both directions it’s 89.999° (there’s no 90.001°).
I’m open to suggestions on how to implement such a thing, maybe I missed something.