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 4a6a784..e675c5b 100644 --- a/samples/pong/Soldier.cs +++ b/samples/pong/Soldier.cs @@ -17,6 +17,7 @@ public override void Start() public override void Update(double deltaTime) { base.Update(deltaTime); + } public override void FrameUpdate(double deltaTime) @@ -25,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(); diff --git a/src/rasdaq/Transformations/Transform.cs b/src/rasdaq/Transformations/Transform.cs index b96ec97..870dd0c 100644 --- a/src/rasdaq/Transformations/Transform.cs +++ b/src/rasdaq/Transformations/Transform.cs @@ -26,6 +26,34 @@ public class Transform(Vector3 spawnPosition) /// public float rotation = 0.0f; + /// + /// 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); + Vector2 radius = (OVector2)entityPos - (OVector2)point; + + // get trig + 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; + 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); + } + internal void CoordUpdate(OVector2 delta) { position.X += delta.X; @@ -65,5 +93,6 @@ internal Matrix4 GetRenderedTransform(float imageWidth, float imageHeight) var scale = ScaleFromNDC(imageWidth, imageHeight); return scale * rotation * translation; + // return scale * rotation * translation; } } 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)); + } }