# How can I map coordinates in an angled square?

I am trying to create a map system for a game. I want to map normal Coordinates for 1200 x 1200 square in an 800x800 square that is rotated 135 degrees. I want to ensure the calculations work when the square is scaled during zoom in and zoom out.

Coordinates I want to map

Final result I am trying to achieve

The requirements are as follows:

1. The square is rotated by 135 degree. So the coordinates are supposed to be rotated to match the rotation of the square.
2. The coordinates must be converted to pixel coordinates so I can use that in my application to draw the coordinates on screen.
3. The marker coordinates must be scaled to fit smaller square to support zooming and zooming out and to enable dynamic marker addition to the square.

Following is what I have done so far to achieve this.

scale the coordinates from 1200x1200 to 800x800 square and then translate to pixel coordinate using the following formula

pixel_x = x * 800 // 1200
pixel_y = 800 - y * 800 // 1200


Rotating the square and the marker coordinates using the following formula

angle_rad = math.radians(angle)
nx = cos_val * (x - center_x) - sin_val * (y - center_y) + center_x
ny = sin_val * (x - center_x) + cos_val * (y - center_y) + center_y


The above formula works when the square is not scaled (result). But when I scale the canvas for zooming in and zooming out. The size of the square varies and the coordinate calculation for the markers does not work anymore

Following is the formula I use to calculate the coordinate for resized square



# Calculate the center of the square
center_x = sum(x_coords) / len(x_coords)
center_y = sum(y_coords) / len(y_coords)

# Get the coordinates of the two points to calculate the width
x1, y1 = x_coords[0], y_coords[0]
x2, y2 = x_coords[1], y_coords[1]

square_width = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)

# Get the coordinates of the two points for calculating the height
x1, y1 = x_coords[1], y_coords[1]
x2, y2 = x_coords[2], y_coords[2]

square_height = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)

scaling_factor_x = canvas_width / square_width
scaling_factor_y = canvas_height / square_height

pixel_x = x * square_width // 1200
pixel_y = canvas_height - (y * square_height) // 1200

scaled_pixel_x = pixel_x * (1 / scaling_factor_x)
scaled_pixel_y = pixel_y * (1 / scaling_factor_y)


I then use the scaled_pixel_x and scaled_pixel_y marker coordinates to rotate around the center of square to create the new coordinates. But the scaled coordinates does not match the correct location on the rotated square. Could anyone point me what I am doing wrong please?

Wanting to try my luck, I propose the following geometric transformation:

$$\begin{cases} x' = x_c + k\,(x-x_c)\cos\theta - k\,(y-y_c)\sin\theta \\ y' = y_c + k\,(x-x_c)\sin\theta + k\,(y-y_c)\cos\theta \end{cases}$$

with $$x_c,y_c \in \mathbb{R}$$, $$0 \le \theta < 2\pi$$ for rototranslation and $$0 \le k \le 1$$ for scaling.

In particular, wanting to put it into practice in Mathematica:

L = {{0, 0}, {1200, 0}, {1200, 1200}, {0, 1200}, {0, 0}};

P = {{114, 385}, {169, 749}, {295, 5}, {600, 600},
{788, 496}, {894, 534}, {957, 776}, {969, 1094}};

{xc, yc} = Mean[L[[1 ;; 4]]];

Manipulate[

Lt = Table[{x, y} = L[[i]];
{xc + k (x - xc) Cos[θ] - k (y - yc) Sin[θ],
yc + k (x - xc) Sin[θ] + k (y - yc) Cos[θ]}, {i, 5}];

Pt = Table[{x, y} = P[[i]];
{xc + k (x - xc) Cos[θ] - k (y - yc) Sin[θ],
yc + k (x - xc) Sin[θ] + k (y - yc) Cos[θ]}, {i, 8}];

Graphics[{Blue, Line[Lt], Red, Point[Pt]},
Axes -> True, AxesLabel -> {"x", "y"},
PlotRange -> {{-500, 1500}, {-500, 1500}}],

{{k, 1}, 0, 1}, {{θ, 0}, 0, 2 π}]


we get:

If it doesn't reflect your expectations, specify what is wrong.

• The formula works perfectly in my python code on initial run but i have a zoom functionality which scales the canvas. Trying to add coordinates dynamically after the scaling is my primary issue. I am unable to workout the offset calcuation between the coordinates of the marker and the square in relation to the canvas to correctly place the marker on the scaled square. Commented May 30, 2023 at 11:41