From 769649386b3f80ef3647a9c35b9275093bd2e92b Mon Sep 17 00:00:00 2001 From: uttam12331 Date: Mon, 3 Aug 2026 10:28:23 +0530 Subject: [PATCH] Fix rotate_around_point to rotate about the source point rotate_around_point computes the source->target vector, rotates it, then adds it back to `target` instead of the center of rotation `source`. This places the result at the wrong location and does not preserve the point's distance from the center. For example, rotating (1, 0) around (0, 0) by 90 degrees returned (1, 1) (distance sqrt(2) from the center) instead of the expected (0, 1). Add the rotated offset to `source` so the point orbits the center, and add regression tests asserting the distance from source is preserved and that a 180 degree rotation reflects the target through the source. --- arcade/math.py | 2 +- tests/unit/test_math.py | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/arcade/math.py b/arcade/math.py index a35237fcad..a32f1c606d 100644 --- a/arcade/math.py +++ b/arcade/math.py @@ -421,7 +421,7 @@ def rotate_around_point(source: Point2, target: Point2, angle: float): dx = diff_x * c - diff_y * s dy = diff_x * s + diff_y * c - return target[0] + dx, target[1] + dy + return source[0] + dx, source[1] + dy def get_angle_degrees(x1: float, y1: float, x2: float, y2: float) -> float: diff --git a/tests/unit/test_math.py b/tests/unit/test_math.py index cd25515506..405c4cc7f3 100644 --- a/tests/unit/test_math.py +++ b/tests/unit/test_math.py @@ -5,6 +5,8 @@ python -m pytest tests/unit/test_utils.py """ +import math + import arcade from pytest import approx from arcade.math import * @@ -87,3 +89,22 @@ def test_rand_vec_spread_deg(): def test_rand_vec_magnitude(): """Smoke test""" rand_vec_magnitude(30.5, 3.3, 4.4) + + +def test_rotate_around_point_preserves_distance_from_source(): + """The rotated point must keep its distance from the center of rotation (source).""" + source = (2.0, 3.0) + target = (5.0, 7.0) # distance 5 from source + for angle in (30.0, 90.0, 170.0, 250.0): + rx, ry = rotate_around_point(source, target, angle) + dist = math.hypot(rx - source[0], ry - source[1]) + assert dist == approx(5.0) + + +def test_rotate_around_point_180_reflects_through_source(): + """A 180 degree rotation reflects the target through the source (direction-independent).""" + source = (2.0, 3.0) + target = (5.0, 3.0) + rx, ry = rotate_around_point(source, target, 180.0) + assert rx == approx(2.0 * source[0] - target[0]) + assert ry == approx(2.0 * source[1] - target[1])