From 2ccd3edafc01d102a24de0cf59903d5346a48e2e Mon Sep 17 00:00:00 2001 From: Svjatoslav Agejenko Date: Fri, 20 Mar 2026 22:51:50 +0200 Subject: [PATCH] refactor(math): simplify Rotation API to use quaternions exclusively --- TODO.org | 2 + doc/example.png | Bin 67796 -> 0 bytes .../eu/svjatoslav/sixth/e3d/gui/Camera.java | 6 +- .../svjatoslav/sixth/e3d/math/Rotation.java | 79 +----------------- .../svjatoslav/sixth/e3d/math/Transform.java | 26 ++---- .../renderer/octree/raytracer/CameraView.java | 23 +++-- .../octree/raytracer/RaytracingCamera.java | 29 +++++-- .../e3d/renderer/raster/ShapeCollection.java | 3 +- .../sixth/e3d/math/QuaternionTest.java | 3 +- .../sixth/e3d/math/RotationMatrixTest.java | 3 +- 10 files changed, 60 insertions(+), 114 deletions(-) delete mode 100644 doc/example.png diff --git a/TODO.org b/TODO.org index 25051af..d54e650 100644 --- a/TODO.org +++ b/TODO.org @@ -93,3 +93,5 @@ Occurs when text is forward-oriented. http://blog.rogach.org/2015/08/how-to-create-your-own-simple-3d-render.html + Improve triangulation. Read: https://ianthehenry.com/posts/delaunay/ + +** Fix camera rotation for voxel raytracer \ No newline at end of file diff --git a/doc/example.png b/doc/example.png deleted file mode 100644 index 709424030b06354af0c4ac691eb441f119d853b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67796 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 KMNUMnLSTZv%wjVD diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/Camera.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/Camera.java index f5542e6..bafdb83 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/Camera.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/Camera.java @@ -13,7 +13,7 @@ import eu.svjatoslav.sixth.e3d.math.Transform; * Represents the viewer's camera in the 3D world, with position, orientation, and movement. * *

The camera is the user's "eyes" in the 3D scene. It has a position (location), - * a looking direction (defined by XZ and YZ angles), and a movement system with + * a looking direction (defined by a quaternion), and a movement system with * velocity, acceleration, and friction for smooth camera navigation.

* *

By default, the user can navigate using arrow keys (handled by @@ -28,8 +28,8 @@ import eu.svjatoslav.sixth.e3d.math.Transform; * // Set camera position * camera.getTransform().setTranslation(new Point3D(0, -50, -200)); * - * // Set camera orientation (radians) - * camera.getTransform().setRotation(0, 0); // angleXZ, angleYZ + * // Set camera orientation using a quaternion + * camera.getTransform().getRotation().setQuaternion(Quaternion.fromAngles(0.5, -0.3)); * * // Copy camera state from another camera * Camera snapshot = new Camera(camera); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/math/Rotation.java b/src/main/java/eu/svjatoslav/sixth/e3d/math/Rotation.java index 236be0d..8e529d0 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/math/Rotation.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/math/Rotation.java @@ -6,13 +6,11 @@ package eu.svjatoslav.sixth.e3d.math; import eu.svjatoslav.sixth.e3d.geometry.Point3D; -import static java.lang.Math.atan2; - /** - * Represents a rotation in 3D space using a quaternion internally. + * Represents a rotation in 3D space using a quaternion. * - *

Historically used two Euler angles (XZ and YZ). Now stores a quaternion - * for better numerical stability and to avoid gimbal lock.

+ *

Quaternions provide smooth interpolation and avoid gimbal lock + * compared to Euler angles.

* * @see Transform * @see Quaternion @@ -28,16 +26,6 @@ public class Rotation implements Cloneable { quaternion = Quaternion.identity(); } - /** - * Creates a rotation with the specified Euler angles. - * - * @param angleXZ the angle around the XZ axis (yaw) in radians - * @param angleYZ the angle around the YZ axis (pitch) in radians - */ - public Rotation(final double angleXZ, final double angleYZ) { - quaternion = Quaternion.fromAngles(angleXZ, angleYZ); - } - /** * Creates a copy of this rotation with the same orientation. * @@ -59,41 +47,6 @@ public class Rotation implements Cloneable { toMatrix().transform(point3d, point3d); } - /** - * Adds the specified angles to this rotation. - * - * @param angleXZ the angle to add around the XZ axis in radians - * @param angleYZ the angle to add around the YZ axis in radians - */ - public void rotate(final double angleXZ, final double angleYZ) { - final Quaternion delta = Quaternion.fromAngles(angleXZ, angleYZ); - quaternion = delta.multiply(quaternion); - } - - /** - * Sets the rotation angles. - * - * @param angleXZ the angle around the XZ axis (yaw) in radians - * @param angleYZ the angle around the YZ axis (pitch) in radians - */ - public void setAngles(final double angleXZ, final double angleYZ) { - quaternion = Quaternion.fromAngles(angleXZ, angleYZ); - } - - /** - * Copies the rotation from another rotation. - * - * @param rotation the rotation to copy from - */ - public void setAngles(final Rotation rotation) { - quaternion = new Quaternion( - rotation.quaternion.w, - rotation.quaternion.x, - rotation.quaternion.y, - rotation.quaternion.z - ); - } - /** * Sets the rotation from a quaternion. * @@ -112,32 +65,6 @@ public class Rotation implements Cloneable { return quaternion; } - /** - * Returns the angle around the XZ axis (yaw) in radians. - * - *

This is a compatibility shim that extracts the angle from the quaternion. - * May not be accurate for extreme pitch angles.

- * - * @return the XZ angle - */ - public double getAngleXZ() { - final Matrix3x3 m = toMatrix(); - return atan2(m.m02, m.m00); - } - - /** - * Returns the angle around the YZ axis (pitch) in radians. - * - *

This is a compatibility shim that extracts the angle from the quaternion. - * May not be accurate for extreme yaw angles.

- * - * @return the YZ angle - */ - public double getAngleYZ() { - final Matrix3x3 m = toMatrix(); - return atan2(-m.m21, m.m11); - } - /** * Converts this rotation to a 3x3 transformation matrix. * diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/math/Transform.java b/src/main/java/eu/svjatoslav/sixth/e3d/math/Transform.java index 021fe1a..047308a 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/math/Transform.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/math/Transform.java @@ -44,17 +44,17 @@ public class Transform implements Cloneable { } /** - * Creates a transform with the specified translation and rotation angles. + * Creates a transform with the specified translation and rotation from Euler angles. * * @param translation the translation * @param angleXZ the angle around the XZ axis (yaw) in radians * @param angleYZ the angle around the YZ axis (pitch) in radians + * @return a new transform with the specified translation and rotation */ - public Transform(final Point3D translation, final double angleXZ, - final double angleYZ) { - - this.translation = translation; - rotation = new Rotation(angleXZ, angleYZ); + public static Transform fromAngles(final Point3D translation, final double angleXZ, final double angleYZ) { + final Transform t = new Transform(translation); + t.rotation.setQuaternion(Quaternion.fromAngles(angleXZ, angleYZ)); + return t; } /** @@ -96,7 +96,7 @@ public class Transform implements Cloneable { return translation; } - /** + /** * Applies this transform to a point: rotation followed by translation. * * @param point the point to transform (modified in place) @@ -106,16 +106,6 @@ public class Transform implements Cloneable { point.add(translation); } - /** - * Sets the rotation angles for this transform. - * - * @param angleXZ the angle around the XZ axis (yaw) in radians - * @param angleYZ the angle around the YZ axis (pitch) in radians - */ - public void setRotation(final double angleXZ, final double angleYZ) { - rotation.setAngles(angleXZ, angleYZ); - } - /** * Sets the translation for this transform by copying the values from the given point. * @@ -127,4 +117,4 @@ public class Transform implements Cloneable { this.translation.z = translation.z; } -} +} \ No newline at end of file diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/octree/raytracer/CameraView.java b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/octree/raytracer/CameraView.java index 12d149e..d585576 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/octree/raytracer/CameraView.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/octree/raytracer/CameraView.java @@ -6,7 +6,7 @@ package eu.svjatoslav.sixth.e3d.renderer.octree.raytracer; import eu.svjatoslav.sixth.e3d.geometry.Point3D; import eu.svjatoslav.sixth.e3d.gui.Camera; -import eu.svjatoslav.sixth.e3d.math.Rotation; +import eu.svjatoslav.sixth.e3d.math.Matrix3x3; import static eu.svjatoslav.sixth.e3d.renderer.octree.raytracer.RaytracingCamera.SIZE; @@ -27,7 +27,6 @@ public class CameraView { * @param zoom the zoom level (scales the view frustum) */ public CameraView(final Camera camera, final double zoom) { - // compute camera view coordinates as if camera is at (0,0,0) and look at (0,0,1) final float viewAngle = (float) .6; cameraCenter = new Point3D(); topLeft = new Point3D(0, 0, SIZE).rotate(-viewAngle, -viewAngle); @@ -35,13 +34,21 @@ public class CameraView { bottomLeft = new Point3D(0, 0, SIZE).rotate(-viewAngle, viewAngle); bottomRight = new Point3D(0, 0, SIZE).rotate(viewAngle, viewAngle); - Rotation rotation = camera.getTransform().getRotation(); - topLeft.rotate(-rotation.getAngleXZ(), -rotation.getAngleYZ()); - topRight.rotate(-rotation.getAngleXZ(), -rotation.getAngleYZ()); - bottomLeft.rotate(-rotation.getAngleXZ(), -rotation.getAngleYZ()); - bottomRight.rotate(-rotation.getAngleXZ(), -rotation.getAngleYZ()); + final Matrix3x3 m = camera.getTransform().getRotation().toMatrix(); + final Point3D temp = new Point3D(); + + temp.clone(topLeft); + m.transform(temp, topLeft); + + temp.clone(topRight); + m.transform(temp, topRight); + + temp.clone(bottomLeft); + m.transform(temp, bottomLeft); + + temp.clone(bottomRight); + m.transform(temp, bottomRight); - // place camera view at camera location camera.getTransform().getTranslation().clone().scaleDown(zoom).addTo(cameraCenter, topLeft, topRight, bottomLeft, bottomRight); } diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/octree/raytracer/RaytracingCamera.java b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/octree/raytracer/RaytracingCamera.java index f0f5184..d751a84 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/octree/raytracer/RaytracingCamera.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/octree/raytracer/RaytracingCamera.java @@ -6,7 +6,7 @@ package eu.svjatoslav.sixth.e3d.renderer.octree.raytracer; import eu.svjatoslav.sixth.e3d.geometry.Point3D; import eu.svjatoslav.sixth.e3d.gui.Camera; -import eu.svjatoslav.sixth.e3d.math.Rotation; +import eu.svjatoslav.sixth.e3d.math.Matrix3x3; import eu.svjatoslav.sixth.e3d.math.Transform; import eu.svjatoslav.sixth.e3d.renderer.raster.Color; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance; @@ -79,11 +79,28 @@ public class RaytracingCamera extends TexturedRectangle { bottomLeft.rotate(cameraCenter, -viewAngle, viewAngle); bottomRight.rotate(cameraCenter, viewAngle, viewAngle); - Rotation rotation = camera.getTransform().getRotation(); - topLeft.rotate(cameraCenter, -rotation.getAngleXZ(), -rotation.getAngleYZ()); - topRight.rotate(cameraCenter, -rotation.getAngleXZ(), -rotation.getAngleYZ()); - bottomLeft.rotate(cameraCenter, -rotation.getAngleXZ(), -rotation.getAngleYZ()); - bottomRight.rotate(cameraCenter, -rotation.getAngleXZ(), -rotation.getAngleYZ()); + final Matrix3x3 m = camera.getTransform().getRotation().toMatrix(); + final Point3D temp = new Point3D(); + + temp.clone(topLeft); + temp.subtract(cameraCenter); + m.transform(temp, topLeft); + topLeft.add(cameraCenter); + + temp.clone(topRight); + temp.subtract(cameraCenter); + m.transform(temp, topRight); + topRight.add(cameraCenter); + + temp.clone(bottomLeft); + temp.subtract(cameraCenter); + m.transform(temp, bottomLeft); + bottomLeft.add(cameraCenter); + + temp.clone(bottomRight); + temp.subtract(cameraCenter); + m.transform(temp, bottomRight); + bottomRight.add(cameraCenter); final Color cameraColor = new Color(255, 255, 0, 255); final LineAppearance appearance = new LineAppearance(2, cameraColor); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/ShapeCollection.java b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/ShapeCollection.java index 07be4a3..c075580 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/ShapeCollection.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/ShapeCollection.java @@ -106,7 +106,8 @@ public class ShapeCollection { final Camera camera = viewPanel.getCamera(); - cameraRotationTransform.getRotation().setAngles(camera.getTransform().getRotation()); + cameraRotationTransform.getRotation().setQuaternion( + camera.getTransform().getRotation().getQuaternion()); transformStack.addTransform(cameraRotationTransform); final Point3D cameraLocation = camera.getTransform().getTranslation(); diff --git a/src/test/java/eu/svjatoslav/sixth/e3d/math/QuaternionTest.java b/src/test/java/eu/svjatoslav/sixth/e3d/math/QuaternionTest.java index 70d0488..831ba29 100644 --- a/src/test/java/eu/svjatoslav/sixth/e3d/math/QuaternionTest.java +++ b/src/test/java/eu/svjatoslav/sixth/e3d/math/QuaternionTest.java @@ -12,7 +12,8 @@ public class QuaternionTest { @Test public void testFromAnglesMatchesRotation() { - final Rotation rotation = new Rotation(0.5, 0.3); + final Rotation rotation = new Rotation(); + rotation.setQuaternion(Quaternion.fromAngles(0.5, 0.3)); final Matrix3x3 rotationMatrix = rotation.toMatrix(); final Quaternion quaternion = Quaternion.fromAngles(0.5, 0.3); diff --git a/src/test/java/eu/svjatoslav/sixth/e3d/math/RotationMatrixTest.java b/src/test/java/eu/svjatoslav/sixth/e3d/math/RotationMatrixTest.java index d0d14e6..79cb7c4 100644 --- a/src/test/java/eu/svjatoslav/sixth/e3d/math/RotationMatrixTest.java +++ b/src/test/java/eu/svjatoslav/sixth/e3d/math/RotationMatrixTest.java @@ -13,7 +13,8 @@ public class RotationMatrixTest { @Test public void testToMatrixMatchesRotate() { - final Rotation rotation = new Rotation(0.5, 0.3); + final Rotation rotation = new Rotation(); + rotation.setQuaternion(Quaternion.fromAngles(0.5, 0.3)); final Point3D original = new Point3D(1, 2, 3); final Point3D viaRotate = new Point3D(original); -- 2.20.1