1
votes

The problem seems to be straight forward, however my math isn't great, thus proving challenging. At this point I've almost come to the conclusion that there may not be a solution, however the little I do know of math there almost always seems to be a solution for those of you better informed.

I have three (x,y) verities in 2D plane, they form an (almost) right angle triangle (i.e. 94 or 87 degrees this does vary, however always with in a few degrees). Vertices are always in the positive axis "Q1", (I'm working with pixel data).

What I need is to find orientation of the triangle in 360 degrees:

  • legs (opp & adj) are always against the (imaginary) x,y axis for all four quadrants, so hypotenuse is always facing outwards
  • Triangle in:
    • q i - 90 degrees
    • q ii - 180 degrees
    • q iii - 270 degrees
    • q iv - 0 degrees

I have tried a number of solutions from various suggestions on this forum and else where, at the moment I'm working with this solution, however its not entirely working for me.
https://stackoverflow.com/a/15442539/14398314

Any advice would much be appreciated, language used is python.

Edit: The following image represents input data and required solution. Image of input and output data

Cheers

1
Please explain what you mean by "legs (opp & adj) are always against the (imaginary) x,y axis for all four quadrants". Doesn't that mean one of the vertices is the origin? And how can the triangle be in Q2 or Q3 when all its vertices are in Q1? Can you give an example of three vertices and the expected output?trent ᶠᵒʳᵐᵉʳˡʸ ᶜˡ
@trentcl Thanks for your reply and patience, I've added an image trying to address your questions. The right angle dose represent the origin, the triangle will not be in Q2, Q3 or Q4, it's orientation needs to represent the ~ 0, 90, 180, 270 angle.Thin Lizzy

1 Answers

2
votes

Step 1: identify the corner of the triangle which is near the (almost) right angle

If the 3 corners are A,B,C then build the dot-product AB*BC, AC*CB, AB*AC. The lowest dot product is the one with sides that are near a right angle, and the corner that appears twice in the dot product is the corner of the near right angle.

Step 2: now that you know the corner that is almost right angle (let's say it was A), compute for sides AB and AC the displacement in x and y (AB_DeltaX, AB_DeltaY, AC_DeltaX, AC_DeltaY) and keep, for each side, only the one with the largest absolute value. The quadrants can be found by this table:

90 : deltaX and deltaY are both positive
180: deltaX < 0 and deltaY > 0
270: both negative
0  : deltaY <0, deltaX > 0

Here a simple implementation:

a = (4.2,0.1)
b = (3.1,4.2)
c = (0.1,3.2)


def get_q(a,b,c):

    #step 1
    ab = (b[0] - a[0], b[1] - a[1])
    ac = (c[0] - a[0], c[1] - a[1])
    ba = (a[0] - b[0], a[1] - b[1])
    bc = (c[0] - b[0], c[1] - b[1])
    ca = (a[0] - c[0], a[1] - c[1])
    cb = (b[0] - c[0], b[1] - c[1])

    dp1 = abs(ab[0] * bc[0] + ab[1] * bc[1])
    dp2 = abs(ac[0] * cb[0] + ac[1] * cb[1])
    dp3 = abs(ab[0] * ac[0] + ab[1] * ac[1])

    # find minimum
    if dp1 < dp2 and dp1 < dp3:
        corner = 'B'
        delta1 = ba
        delta2 = bc
    elif dp2 < dp1 and dp2 < dp3:
        corner = 'C'
        delta1 = ca
        delta2 = cb
    elif dp3 < dp1 and dp3 < dp2:
        corner = 'A'
        delta1 = ab
        delta2 = ac
    else:
        corner = 'unknown'
        delta1 = (0.0, 0.0)
        delta2 = (0.0, 0.0)

    # Step 2
    if abs(delta1[0]) > abs(delta2[0]):
        deltaX = delta1[0]
    else:
        deltaX = delta2[0]

    if abs(delta1[1]) > abs(delta2[1]):
        deltaY = delta1[1]
    else:
        deltaY = delta2[1]

    if deltaX > 0 and deltaY > 0:
        quadrant = 'Q1'
    elif deltaX < 0 and deltaY < 0:
        quadrant = 'Q3'
    elif deltaX < 0 and deltaY > 0:
        quadrant = 'Q2'
    elif deltaX > 0 and deltaY < 0:
        quadrant = 'Q4'
    else:
        quadrant = 'unknown'

    return quadrant