## Rotation angle using 3 points

This is the place for queries that don't fit in any of the other categories.

### Rotation angle using 3 points

Hi!
What I'm trying to do is find the angle of rotation between lines formed by three consecutive points. These are sequential points, so the direction of rotation matter.
My input is a sequence of pair of coordinates.

My desired output is the rotation angle of each point, where the point would be acting as the vertex of the angle. This angle would be between 1 and 360, where a negative number indicates a rotation to the left, and a positive number a rotation to the right.

I've been struggling with this for weeks, but I'm finally closer to the solution than ever before. I wrote the following script and compared it to the output of the "pathmetrics" function of the program Geospatial Modelling Tool(GME).

Code: Select all
`coords=[[283907,971700],[284185,971634],[284287,971507],[284275,971608],[283919,971761],[284311,971648],[284277,971637],[284280,971651],[284174,971649],[283909,971701],[283941,971700],[284294,971518],[284288,971517],[284315,971539],[284250,971505]    print "A"+"\t"+"B"+"\t"+"C"+"\t"+"orientation"+"\t"+"angle"+"\t"+"bearing AB"+"\t"+"bearing BC"    for a in coords:      A=a      indexA=coords.index(a)      B=coords[indexA+1]      C=coords[indexA+2]      ##Find the bearings of AB and BC      AB=[B[0]-A[0],B[1]-A[1]]          #find the extreme of vector AB      BearAB=math.atan2(AB[0],AB[1])    #use arctan2 to find the angle      ABBearDeg=math.degrees(BearAB)    #in degrees      if ABBearDeg<0:                   #if negative, add 360 in order to obtain the angle in a clockwise direction       ABBearDeg=360+ABBearDeg          #Bearing AB      BC=[C[0]-B[0],C[1]-B[1]]          #Do the same for points BC      BearBC=math.atan2(BC[0],BC[1])      BCBearDeg=math.degrees(BearBC)      if BCBearDeg<0:       BCBearDeg=360+BCBearDeg          #Bearing BC     ##Find the angle between the lines      alfa=BCBearDeg-ABBearDeg          #Obtain the difference between the bearing angles      if abs(alfa)>180:                 #If greater than 180       if alfa<0:                        #and negative        angle=(360+alfa)                   #Direction of rotation is right and angle is obtained by adding 360        print format(A)+"\t"+format(B)+"\t"+format(C)+"\t"+"right"+"\t"+format(angle)+"\t"+format(round(ABBearDeg,2))+"\t"+format(round(BCBearDeg,2))       else:                             #If positive        angle=alfa-360                      #Direction of rotation is left and angle is obtained by substracting 360        print format(A)+"\t"+format(B)+"\t"+format(C)+"\t"+"left"+"\t"+format(angle)+"\t"+format(ABBearDeg)+"\t"+format(round(BCBearDeg,2))      else:                            #If the difference was less than 180, then the rotation angle is equal to it       angle=alfa       if angle<0:                     #If negative, left rotation           print format(A)+"\t"+format(B)+"\t"+format(C)+"\t"+"left"+"\t"+format(angle)+"\t"+format(ABBearDeg)+"\t"+format(round(BCBearDeg,2))       else:                            #If positive, right rotation        print format(A)+"\t"+format(B)+"\t"+format(C)+"\t"+"right"+"\t"+format(angle)+"\t"+format(ABBearDeg)+"\t"+format(round(BCBearDeg,2))`

While many of the results coincide, others don't.

I've been able to pin-point at with point the error occurs, but I can't figure out why it happens because it depends strictly on pre-set formulas I have no control of.
So, the difference is that (SOMETIMES) my calculations of the bearing of the vectors differs from the one calculated by GME.
The weird part is that it happens only sometimes, and I have no idea what triggers it.

Any ideas of what might be going on?

If you know any other way of calculating angles between lines that incorporate the direction of the movement, do let me know.

Thanks!!!
noebyus

Posts: 1
Joined: Fri Mar 15, 2013 8:58 pm

### Re: Rotation angle using 3 points

This code is hard to read. Consequently I didn't try to find the bug. I would suggest you read this: http://www.python.org/dev/peps/pep-0008/ because if you use those guide lines you will get more feed back.

The way I would calculate angles would be something like this
Code: Select all
`import mathline_1 = [[0., 0.], [1., 1.]]line_2 = [[1., 1.], [2., 3.]]def find_angle(line_1, line_2):    dx_line_1 = line_1[1][0] - line_1[0][0]    dy_line_1 = line_1[1][1] - line_1[0][1]    dx_line_2 = line_2[1][0] - line_2[0][0]    dy_line_2 = line_2[1][1] - line_2[0][1]    a_line_1 = math.atan2(dx_line_1, dy_line_1)    a_line_2 = math.atan2(dx_line_2, dy_line_2)        return (a_line_1 - a_line_2) * 180 / math.piprint '{:.2f}'.format(find_angle(line_1, line_2))`

though it appears you try to do something similar but it's hard to tell, which is the real problem imho.
hrs

Posts: 86
Joined: Thu Feb 07, 2013 9:26 pm