Search code examples
mathgeometryrotationtransformcoordinate-systems

transforming coordinates to a rotated coordinate system


I am trying to convert the rotation and crop rectangle settings of an old graphics editor to new editor which uses different coordinate system than the old one. The following picture illustrates the problem:

rectangles illustration

All the rectangles have the same aspect ratio (e.g. 3:2), and all the coordinates are normalized across the edges (ie from 0 to 1 in both X and Y direction).

The old program saves the coordinates of corners of the blue rectangle C given in the coordinate system aligned with the green rectangle (with origin at A), and the angle of rotation of yellow rectangle.

The new program needs the coordinates of the corners of the blue rectangle in the coordinate system aligned with the yellow rectangle (with origin at B). How do I do the transformation from old to new?

This seems like a simple math problem, but it has been so many years since the math classes that I could not figure this out with pen-and-paper nor searching this site (many similar questions, but I could not find quite a matching one...)


Solution

  • Let c(0), c(1), c(2), c(3) be the four corners of C and let b(0) be the corner B where B's coordinate system is located. Let q be the angle of rotation of the x-axis of B. All these angles and points must be given in the same coordinate system.

    To find the coordinates of c(i) in B, rotate the vector c(i) - b(0) by the angle q (or -q depending on how things are measured). You can use a rotation matrix for this. Let cq = cos(q), sq = sin(q), and (dx, dy) = c(i) - b(0). The coordinates of c(i) in B are then

    Product of the rotation matrix for q and (dx, dy)


    Let c = (c(0) + c(2)) / 2 be the center of C. Let S(s) be the matrix that scales by s and let R(q) be the matrix that rotates by q. The corners of B are given by

    b(i) = c + S(s) * R(q) * (c(i) - c)
    

    The corners a(0), a(1), a(2), a(3) of the rectangle A are also known. We wish to determine the greatest possible value of the scaling parameter s such that all points b(i) of B are within the rectangle A.

    I think the safest and simplest approach here is to consider relevant pairs of b(i) and a(i) and for such pairs compute the greatest value s(i, j) such that if s = s(i, j) then b(i) is within the corner region of a(j).

    Let a(0) and a(2) be opposite corners of A and let c(0) and c(1) be adjacent corners of C. Let r(j) = a(j) - c and d(i) = R(q) * (c(i) - c).

    Each diagonal i can be scaled by

    s(i, j) = min (|r(j).x| / |d(i).x|, |r(j).y| / |d(i).y|)
    

    before B moves outside the region defined by r(j). Compute s(i, j) for i = 0, 1 and j = 0, 2 and let s be the minimum of those 4 values.


    Depending on how q is measured you may need to apply a transformation q' = atan2(kx * sin(q), ky * cos(q)) to q to account for issues of aspect ratio.