Rotating an L shape of 3 points so that it always faces a certain way.

geometrytrigonometry

I have 3 points in 2d space that roughly make an L shape. I want the L shape to face a certain way. I'm having trouble coming up with the logic to figure out which angle I should rotate my shape.

Here are the 3 main orientations I encounter and their slight variations;

Orientations

I want my L to always be like 1-A (top left).

I know which point is the corner point. What I do is I get the angle to the two other points.

In the case of 1-B these might be (-2, -94) and in 1-C (3, -88). So, for 1-B I'd need to rotate the whole shape by -2 degrees. For 1-C I'd need to rotate by 3 degrees.

In the case of 2-B, my angles are something like (-87, -177) and for 2-C they are (-91, 178). For 2-B, I'd need to rotate the shape by -87 degrees. For 2-C I'd need to rotate by -91 degrees.

I've tried calculating the smaller angle by magnitude and rotating the shape by that.

var smaller_angle;

if(math.abs(angle1) < math.abs(angle2))
   smaller_angle = angle1;
else
   smaller_angle = angle2;

shape.rotate(smaller_angle);

This works for the majority of the time but it won't work, for example, the shape is similar to 3-A with the angles (0, 88). The above logic rotates by 0 and it fails.

What should my logic be so I can find the angle I'm supposed to rotate this shape, given that I know the corner point and I know the angle between corner and other points?

Best Answer

I see that your angles are between $-180^\circ$ and $+180^\circ$. The difference between your two angles is about $90^\circ$. If you want to rotate such that one side is along the positive $x$ axis, and the other one towards the negative $y$ axis, all you need to do is rotate by the opposite of the larger angle. So $$(-2, -94)\to 2\to(0,-92)\\(3, -88)\to -3\to(0, -91)$$Then $$(0,88)\to -88\to (-88,0)$$

Note that this is valid if the negative $x$ axis is not in the region between the legs.

  • How to check for that? look at the angle difference between the larger and smaller If it is smaller than $180^\circ$ your inner region does not overlap the $-x$ axis, so you are fine. If it is greater that $180^\circ$ you are overlapping.
  • What do you do if you overlap the $-x$ axis? In that case subtract $360^\circ$ from the larger value. The previous smaller value is now larger, and continue as before

Note since the question uses a reference frame upside down (positive x to the right, positive y down), the following is a possible python implementation

def rotate(a1,a2):
    sm, la = a1, a2
    if sm>la:
        sm, la = la, sm
    if la-sm>180:
        sm, la = la, sm+360
    return -sm