int y = e.getY();
// rotate
if (this.InteractionMode == 1) {
- cam.Azimuth(lastX - x);
- cam.Elevation(y - lastY);
+ cam.Elevation(clampElevationDelta(y - lastY));
if (doNotRotate)
cam.SetViewUp(upDirection);
+ cam.Azimuth(lastX - x);
cam.OrthogonalizeViewUp();
resetCameraClippingRange();
// panel.UpdateLight();
return true;
}
+ private static double dot(double[] a, double[] b) {
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+ }
+
+ /** Calculate change in elevation, clamped to vertical directions. */
+ private double clampElevationDelta(double elevationDelta) {
+ if (!doNotRotate)
+ return elevationDelta;
+
+ double[] direction = cam.GetDirectionOfProjection();
+ double d = Math.min(1.0, Math.max(-1.0, dot(direction, upDirection)));
+ double elevation = Math.toDegrees(Math.acos(d)) + elevationDelta;
+ if (elevation < 0)
+ elevationDelta -= elevation - 1e-5;
+ else if (elevation > 180)
+ elevationDelta -= elevation - 180 + 1e-5;
+ return elevationDelta;
+ }
+
@Override
public boolean mouseWheelMoved(MouseWheelEvent e) {
double zoomFactor;