From f2978c0f3db559134338c26644eb3a28c0574566 Mon Sep 17 00:00:00 2001 From: Rinceri Date: Fri, 22 May 2026 00:25:57 +0100 Subject: [PATCH 1/6] add rotation around point --- samples/pong/Soldier.cs | 3 +++ src/rasdaq/Transformations/Transform.cs | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/samples/pong/Soldier.cs b/samples/pong/Soldier.cs index a9d115c..5c46122 100644 --- a/samples/pong/Soldier.cs +++ b/samples/pong/Soldier.cs @@ -17,6 +17,9 @@ public override void Start() public override void Update(double deltaTime) { base.Update(deltaTime); + + Entity.Transform.rotation += 1f; + Entity.Transform.rotationRadius = 400f; } public override void FrameUpdate(double deltaTime) diff --git a/src/rasdaq/Transformations/Transform.cs b/src/rasdaq/Transformations/Transform.cs index 5e3e7b6..2064af5 100644 --- a/src/rasdaq/Transformations/Transform.cs +++ b/src/rasdaq/Transformations/Transform.cs @@ -25,6 +25,10 @@ public class Transform(Vector3 spawnPosition) /// Rotation in degrees. Used for 2D rotation around Z axis. /// public float rotation = 0.0f; + /// + /// distance from the centre of the entity, to rotate around + /// + public double rotationRadius = 0.0; internal void CoordUpdate(OVector2 delta) { @@ -61,9 +65,11 @@ internal Matrix4 Translate() internal Matrix4 GetRenderedTransform(float imageWidth, float imageHeight) { var translation = Translate(); + var rotationTranslation = Matrix4.CreateTranslation((float)rotationRadius, 0, 0); var rotation = Get2DRotation(); var scale = ScaleFromNDC(imageWidth, imageHeight); - return scale * rotation * translation; + return scale * rotationTranslation * rotation * translation; + // return scale * rotation * translation; } } From 96eb46948349f58514e937dd3c01829d4fc1427d Mon Sep 17 00:00:00 2001 From: Rinceri Date: Tue, 14 Jul 2026 20:07:09 +0100 Subject: [PATCH 2/6] add rotation around point as function --- src/rasdaq/Transformations/Transform.cs | 30 ++++++++++++++++++++----- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/rasdaq/Transformations/Transform.cs b/src/rasdaq/Transformations/Transform.cs index 86f7ca2..45d3f28 100644 --- a/src/rasdaq/Transformations/Transform.cs +++ b/src/rasdaq/Transformations/Transform.cs @@ -25,10 +25,29 @@ public class Transform(Vector3 spawnPosition) /// Rotation in degrees. Used for 2D rotation around Z axis. /// public float rotation = 0.0f; - /// - /// distance from the centre of the entity, to rotate around - /// - public double rotationRadius = 0.0; + + public void RotateFromPoint(Vector2 point, float degrees) + { + // get radius + Vector2 entityPos = new(position.X, position.Y); + Vector2 radius = (OVector2)entityPos - (OVector2)point; + + Console.WriteLine("radius: " + radius); + + // get trig + var sin = Math.Sin(MathHelper.DegreesToRadians(degrees)); + var cos = Math.Cos(MathHelper.DegreesToRadians(degrees)); + + // get x,y from origin + var xFromOrigin = radius.X * cos - radius.Y * sin; + var yFromOrigin = radius.X * sin + radius.Y * cos; + + // set position and round to 4 dp + position.X = Math.Round(point.X + xFromOrigin, 4); + position.Y = Math.Round(point.Y + yFromOrigin, 4); + + Console.WriteLine("position: " + position); + } internal void CoordUpdate(OVector2 delta) { @@ -65,11 +84,10 @@ internal Matrix4 Translate() internal Matrix4 GetRenderedTransform(float imageWidth, float imageHeight) { var translation = Translate(); - var rotationTranslation = Matrix4.CreateTranslation((float)rotationRadius, 0, 0); var rotation = Get2DRotation(); var scale = ScaleFromNDC(imageWidth, imageHeight); - return scale * rotationTranslation * rotation * translation; + return scale * rotation * translation; // return scale * rotation * translation; } } From 28e048f73f4180c9e6fd6ea9091b97e2e67a0a4d Mon Sep 17 00:00:00 2001 From: Rinceri Date: Tue, 14 Jul 2026 20:15:27 +0100 Subject: [PATCH 3/6] add rotation around point docs --- src/rasdaq/Transformations/Transform.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/rasdaq/Transformations/Transform.cs b/src/rasdaq/Transformations/Transform.cs index 45d3f28..8bca102 100644 --- a/src/rasdaq/Transformations/Transform.cs +++ b/src/rasdaq/Transformations/Transform.cs @@ -26,7 +26,16 @@ public class Transform(Vector3 spawnPosition) /// public float rotation = 0.0f; - public void RotateFromPoint(Vector2 point, float degrees) + /// + /// Rotate the entity from a point in the world space. + /// + /// Note that this does not rotate the entity itself. + /// Instead, it moves the entity in a circular arc, with `point` being the centre of the arc. + /// + /// + /// centre of rotation + /// rotation in degrees + public void RotateFromPoint(Vector2 point, float rotation) { // get radius Vector2 entityPos = new(position.X, position.Y); @@ -35,8 +44,8 @@ public void RotateFromPoint(Vector2 point, float degrees) Console.WriteLine("radius: " + radius); // get trig - var sin = Math.Sin(MathHelper.DegreesToRadians(degrees)); - var cos = Math.Cos(MathHelper.DegreesToRadians(degrees)); + var sin = Math.Sin(MathHelper.DegreesToRadians(rotation)); + var cos = Math.Cos(MathHelper.DegreesToRadians(rotation)); // get x,y from origin var xFromOrigin = radius.X * cos - radius.Y * sin; From 43c82035a2473a211befc9c87d579c499dd7eded Mon Sep 17 00:00:00 2001 From: Rinceri Date: Tue, 14 Jul 2026 20:15:50 +0100 Subject: [PATCH 4/6] add example to test rotation around point --- samples/pong/Game.cs | 2 +- samples/pong/Soldier.cs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/samples/pong/Game.cs b/samples/pong/Game.cs index 571b2cb..4fc1f7e 100644 --- a/samples/pong/Game.cs +++ b/samples/pong/Game.cs @@ -20,7 +20,7 @@ public override void Init() public override void Start() { World world = new(); - Entity player = new(new Vector3(456, 228, 1)); + Entity player = new(new Vector3(400, 200, 1)); Entity enemy = new(); Sprite spr = new(456, 456, andrei); diff --git a/samples/pong/Soldier.cs b/samples/pong/Soldier.cs index 1cc3f53..e675c5b 100644 --- a/samples/pong/Soldier.cs +++ b/samples/pong/Soldier.cs @@ -18,8 +18,6 @@ public override void Update(double deltaTime) { base.Update(deltaTime); - Entity.Transform.rotation += 1f; - Entity.Transform.rotationRadius = 400f; } public override void FrameUpdate(double deltaTime) @@ -28,7 +26,7 @@ public override void FrameUpdate(double deltaTime) if (Input.IsKeyPressed(Keys.V)) { - Log.Info("V pressed"); + Entity.Transform.RotateFromPoint(new Vector2(800, 200), 90); } PhysicsBody? body = Entity?.GetComponent(); From 2d7b8c780c9e4f46fd3b8ede691f2b49594dfef2 Mon Sep 17 00:00:00 2001 From: Rinceri Date: Sun, 19 Jul 2026 20:59:40 +0100 Subject: [PATCH 5/6] remove debug prints --- src/rasdaq/Transformations/Transform.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/rasdaq/Transformations/Transform.cs b/src/rasdaq/Transformations/Transform.cs index 8bca102..870dd0c 100644 --- a/src/rasdaq/Transformations/Transform.cs +++ b/src/rasdaq/Transformations/Transform.cs @@ -41,8 +41,6 @@ public void RotateFromPoint(Vector2 point, float rotation) Vector2 entityPos = new(position.X, position.Y); Vector2 radius = (OVector2)entityPos - (OVector2)point; - Console.WriteLine("radius: " + radius); - // get trig var sin = Math.Sin(MathHelper.DegreesToRadians(rotation)); var cos = Math.Cos(MathHelper.DegreesToRadians(rotation)); @@ -54,8 +52,6 @@ public void RotateFromPoint(Vector2 point, float rotation) // set position and round to 4 dp position.X = Math.Round(point.X + xFromOrigin, 4); position.Y = Math.Round(point.Y + yFromOrigin, 4); - - Console.WriteLine("position: " + position); } internal void CoordUpdate(OVector2 delta) From 1a7efc6dd4175120cc103a585509e96752f42826 Mon Sep 17 00:00:00 2001 From: Rinceri Date: Sun, 19 Jul 2026 21:00:51 +0100 Subject: [PATCH 6/6] add rotation around point tests --- tests/TransformTests.cs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/TransformTests.cs b/tests/TransformTests.cs index 93ed0b7..e1af831 100644 --- a/tests/TransformTests.cs +++ b/tests/TransformTests.cs @@ -140,4 +140,30 @@ public void GetRenderedTransform_SetPositionScale_ScaleThenTranslate() // need to transpose back since openTK uses row major AssertMatrixEqual(transform.GetRenderedTransform(1, 1), correctMatrix.Transposed()); } + + [Test] + public void RotateFromPoint_At90CCW_Rotate90CCW() + { + // (x: 2, y: 0) + transform.position = new Vector3(2, 0, 0); + + Vector2 center = new(0, 0); + transform.RotateFromPoint(center, 90); + var actual = new Vector3(0, 2, 0); + + Assert.That(transform.position, Is.EqualTo(actual)); + } + + [Test] + public void RotateFromPoint_AtMinus90WithCenterOnRight_Rotate90CW() + { + // (x: 2, y: 0) + transform.position = new Vector3(-2, 0, 0); + + Vector2 center = new(0, 0); + transform.RotateFromPoint(center, -90); + var actual = new Vector3(0, 2, 0); + + Assert.That(transform.position, Is.EqualTo(actual)); + } }