我遇到了一个令人困惑的问题。这是一个小背景:
我正在使用Lambert93中的坐标点处理qgis / python:一个中心点(我的dict键)和其他几个点都在它周围。为了简化,我只提出了一个例子:
import numpy as np
import math
dict = {(355385,6.68906e+06): [(355277,6.68901e+06), (355501,6.68912e+06), (355364,6.6891e+06), (355277,6.68901e+06)]}
for key, values in dict.iteritems():
anglist =[]
print key
i=0
j=1
for sides in values[:-1]:
A = np.array(dict[key][i])
B = np.array(key)
C = np.array(dict[key][j])
BA = A - B
BC = C - B
cosine_angle = np.vdot(BA, BC) / (np.linalg.norm(BA) * np.linalg.norm(BC))
angle = (np.degrees(np.arccos(cosine_angle)))
i+=1
j+=1
anglist.append(angle)
s = sum(anglist)
dict[key]= [values, anglist, s]
print dict
结果是:
{(355385, 6689060.0): [[(355277, 6689010.0), (355501, 6689120.0), (355364, 6689100.0), (355277, 6689010.0)], [177.4925133253854, 90.349597027985112, 87.142916297400205], 354.98502665077069]}
正如你所看到的,sum = 354.我有一大堆数据,有时我会得到正确的360,但在大多数情况下我没有。然而,在所有逻辑中,通过转换单个点并结束计算开始,我应该得到的唯一结果是360.
我尝试了另一种方法,看看cosine-angle
和angle
是不是问题:
from math import sqrt
from math import acos
import numpy
def angle(a, b, c):
# Create vectors from points
ba = [ aa-bb for aa,bb in zip(a,b) ]
bc = [ cc-bb for cc,bb in zip(c,b) ]
# Normalize vector
nba = sqrt ( sum ( (x**2.0 for x in ba) ) )
ba = [ x/nba for x in ba ]
nbc = sqrt ( sum ( (x**2.0 for x in bc) ) )
bc = [ x/nbc for x in bc ]
# Calculate scalar from normalized vectors
scale = sum ( (aa*bb for aa,bb in zip(ba,bc)) )
# calculate the angle in radian
angle = numpy.degrees(acos(scale))
return angle
print angle((355277,6.68901e+06),(355385,6.68906e+06), (355501,6.68912e+06))
print angle((355501,6.68912e+06),(355385,6.68906e+06), (355364,6.6891e+06))
print angle((355364,6.6891e+06),(355385,6.68906e+06), (355277,6.68901e+06))
但结果仍然是:
177.492513325
90.349597028
87.1429162974
所以我认为我们可以跨越问题的数学......所以一种可能性是qgis(或python?)如何管理坐标的问题。我怎么能绕过这个?
大致相同答案 0 :(得分:0)
感谢Hellmar的指示,这里是工作代码。我做了两件事:在我的飞机上给出了所有的中心点(0,0),减去了中心点和(0,0)之间距离所有其他相关点的距离。 然后我能够使用atan2,因为我需要计算的所有角度都是(0,0)。在这种情况下,Atan2非常实用,因为它只需要两个点来计算角度:测量的角度始终是0,0的角度。 这可能意味着我不必将我的中心点设置为0,0,因为它只是被踢出了等式。 这是我的代码。任何进一步的建议都非常受欢迎。
import numpy as np
dictionary = {(355385,6.68906e+06): [(355277,6.68901e+06), (355501,6.68912e+06), (355364,6.6891e+06), (355277,6.68901e+06)], (355364,6.6891e+06): [(355261,6.68905e+06), (355385,6.68906e+06), (355481,6.68916e+06), (355340,6.68915e+06), (355261,6.68905e+06)], (355340,6.68915e+06): [(355238,6.68909e+06), (355364,6.6891e+06), (355452,6.68921e+06), (355238,6.68909e+06)]}
def angle_between(p1, p2):
ang1 = np.arctan2(*p1[::-1])
ang2 = np.arctan2(*p2[::-1])
return np.rad2deg((ang1 - ang2) % (2 * np.pi))
zlist=[]
newdict={}
for key, values in dictionary.iteritems():
xlist =[]
ylist = []
i=0
#print key
#print key[0]
for sides in values:
A = dictionary[key][i][0]
B = key[0]
C = dictionary[key][i][1]
D= key[1]
E = (0.0, 0.0)
o1 = A-B
o2 = C-D
xlist.append(o1)
ylist.append(o2)
ziplist = zip(xlist, ylist)
i+=1
zlist.append(ziplist)
#print dict[key][i][0]
newdict=zlist
print newdict
angledict = []
for p in newdict:
i=0
j=1
print p
for q in p[:-1]:
A=p[i]
B=p[j]
print "A=",A
print "B=", B
angledict.append(angle_between(A,B))
i+=1
j+=1
print angledict
我从here
获取了angle_between函数