0

私がやろうとしているのは、3 つの連続する点によって形成される線の間の回転角度を見つけることです。これらは連続した点なので、回転の方向が重要です。私の入力は、座標のペアのシーケンスです。

私の望む出力は、ポイントが角度の頂点として機能する各ポイントの回転角度です。この角度は 1 から 360 の間で、負の数は左への回転を示し、正の数は右への回転を示します。

私はこれに何週間も苦労してきましたが、ついにこれまで以上に解決策に近づいています. 次のスクリプトを作成し、プログラム Geospatial Modeling Tool (GME) の「pathmetrics」関数の出力と比較しました。

coords=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))

多くの結果は一致しますが、一致しないものもあります。

                            My results                                                                      GME results     
        A                   B                   C       orientation     angle       bearing AB  bearing BC  GMEangle    GMEbearing AB   GMEbearing BC
[283907, 971700]    [284185, 971634]    [284287, 971507]    right       37.8750     103.3553    141.2300    37.8750     103.3553        141.2303
[284185, 971634]    [284287, 971507]    [284275, 971608]    left        -148.0060   141.2303    353.2200    -148.0060   141.2303        353.2243
[284287, 971507]    [284275, 971608]    [283919, 971761]    left        -59.9675    353.2243    293.2600    -68.9673    353.2243        284.2570
[284275, 971608]    [283919, 971761]    [284311, 971648]    right       172.8236    293.2600    106.0800    96.6181     284.2570        106.0804
[283919, 971761]    [284311, 971648]    [284277, 971637]    right       145.9916    106.0804    252.0700    145.9916    106.0804        252.0721
[284311, 971648]    [284277, 971637]    [284280, 971651]    right       120.0227    252.0700    12.0900     120.0227    252.0721        12.0948
[284277, 971637]    [284280, 971651]    [284174, 971649]    left        -103.1757   12.0948     268.9200    -103.1757   12.0948         268.9191
[284280, 971651]    [284174, 971649]    [283909, 971701]    right       12.1828     268.9191    281.1000    -131.4097   268.9191        137.5094
[284174, 971649]    [283909, 971701]    [283941, 971700]    right       170.6880    281.1000    91.7900     85.2053     137.5094        9.4623
[283909, 971701]    [283941, 971700]    [284294, 971518]    right       25.4848     91.7899     117.2700    146.4722    9.4623          85.0429
[283941, 971700]    [284294, 971518]    [284288, 971517]    right       143.2629    117.2748    260.5400    123.0283    85.0429         260.5377
[284294, 971518]    [284288, 971517]    [284315, 971539]    right       150.2887    260.5400    50.8300     150.2887    260.5377        50.8263
[284288, 971517]    [284315, 971539]    [284250, 971505]    left        -168.4394   50.8263     242.3900    -147.5925   50.8263         263.2338

(表がごちゃごちゃしててすみません;思い通りに画像がアップできませんでした)

エラーが発生したポイントを特定できましたが、制御できない事前設定された式に厳密に依存しているため、なぜエラーが発生したのかわかりません。したがって、違いは、(時々) ベクトルのベアリングの私の計算が GME によって計算されたものと異なることです。奇妙な部分は、それが時々しか起こらないということであり、何がそれを引き起こすのか私にはわかりません.

何が起こっているのかについてのアイデアはありますか?

動きの方向を組み込んだ線間の角度を計算する他の方法を知っている場合は、お知らせください. うまくいくものは何でも大丈夫です。

ありがとう!!!!

4

1 に答える 1

1

ポイントA、B、Cがあります。あなたの説明から、Bが回転ポイントであると想定しています。つまり、ベクトル BA は BC に変換されます。

  • ベクトル BA (AB) と BC (CB) を作成します。
  • ベクトルの角度を計算 (それらを正にする) とそれらの差
  • ベクトル間の角度の差が回転角度です。

numpy を使用すると、これが簡単になります。このような:

In [1]: import numpy as np

In [2]: A = np.array([283907, 971700])

In [3]: B = np.array([284185, 971634])

In [4]: C = np.array([284287, 971507])

In [5]: BA = A - B

In [6]: BC = C - B

In [7]: BA
Out[7]: array([-278,   66])

In [8]: BC
Out[8]: array([ 102, -127])

In [9]: s = np.arctan2(*BA)

In [10]: if s < 0:
   ....:     s += 2*np.pi
   ....:     

In [11]: s
Out[11]: 4.9454836529138948

In [12]: e = np.arctan2(*BC)

In [13]: if e < 0:
    e += 2*np.pi
   ....:     

In [14]: e
Out[14]: 2.4649341681747883

In [15]: delta = e - s

In [16]: np.degrees(delta)
Out[16]: -142.12501634890182

In [17]: delta
Out[17]: -2.4805494847391065

正の角度は反時計回りです。

于 2013-03-15T21:40:19.570 に答える