Search code examples
objective-crotationrectanglespoints

Rotate a rectangle until two points have equal y coordinates


Say I have a rectangle (R) and inside said rectangle, I have two points, A and B. I need to rotate the rectangle around the center point (C) to the point A and B have equal y coordinates. Since the solution to this could produce two separate answers (where Ax is < Bx, and where Ax is > Bx), I would like to constrain this to only allow the solution where Ax < Bx.

My solution is to solve for theta when rotating around M (the midpoint between A and B) and then to rotate around C by theta (below).

Will this work in all cases/is this optimal? Thanks in advance!

CGPoint m = CGPointMake(a.x / 2 + b.x / 2, a.y / 2 + b.y / 2);
float dx = m.x - a.x;
float dy = m.y - a.y;
float radians = -atan2f(dy, dx)

Solution

  • You can perform the rotation around C, but determine the angle of rotation by examining the relationship between points A and B. The angle of rotation will be -atan2(dy, dx), where dy = B.y-A.y and dx = B.x-A.x.

    The range of atan2 is -M_PI to M_PI, so the expression will always provide the smallest rotation to make the line AB parallel to the x axis. To produce a result where A.x < B.x, examine the sign of dx. A negative dx means that A.x > B.x. In that case, your rotation should be adjusted by pi. To sum up:

    CGPoint A = // some point
    CGPoint B = // some point
    
    CGFloat dx = B.x - A.x;
    CGFloat dy = B.y - A.y;
    CGFloat rotation = (dx < 0)? M_PI+atan2(dy,dx) : -atan2(dy,dx);
    

    Apply rotation to any point you wish in the rectangle's coordinate system. The rectangle will be rotated about that point to make the line AB parallel to the x-axis leaving A.x < B.x.