2016-05-31 26 views
1

Ich stecke mit einem verwirrenden Problem fest. Hier ist ein kleiner Hintergrund:Wie kommt es, dass mein voller Kreis nicht 360 Grad ist?

Ich arbeite an Qgis/Python mit Koordinatenpunkten in Lambert93: ein zentraler Punkt (mein Diktatschlüssel) und mehrere andere Punkte, die um ihn herum gravitieren. Zur Vereinfachung habe den Code ich lege nur ein Beispiel:

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 

Ergebnisse sind:

{(355385, 6689060.0): [[(355277, 6689010.0), (355501, 6689120.0), (355364, 6689100.0), (355277, 6689010.0)], [177.4925133253854, 90.349597027985112, 87.142916297400205], 354.98502665077069]} 

Wie Sie sehen können, sum = 354. Ich habe eine große Menge von Daten und manchmal I bekomme die richtige 360, aber größtenteils nicht. Aber in jeder Logik, durch Drehen um einen einzelnen Punkt und Beenden der Berechnung, wo es begann, ist das einzige Ergebnis, das ich erhalten sollte 360.

Ich habe einen zweiten Weg versucht, nur um zu sehen, ob die cosine-angle und angle nicht die waren Problem:

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

Aber die Ergebnisse sind nach wie vor:

177.492513325 
90.349597028 
87.1429162974 

Deshalb denke ich, dass wir die Mathematik aus dem Problem überwinden können ... also eine Möglichkeit, ein Problem mit, wie qgis (oder python ist?) verwaltet die Koordinaten. Wie kann ich das umgehen?

ich sagen sollte, die Codes sind weitgehend die gleichen wie here, here und here

+1

Im letzten Beispiel haben Sie wahrscheinlich einen Winkel, der 180 Grad ist>. Das Problem ist, dass der Standardzweig der Funktion 'acos()' nur Werte aus [0, pi/2] zurückliefern kann. Höchstwahrscheinlich muss der erste Winkel 182,51 Grad betragen - dann sind die Zahlen gut zusammengefasst. Aber ich habe jetzt keine Zeit, die Zahlen zu überprüfen. Um dies zu beheben, benötigen Sie eine zusätzliche Prüflogik. –

Antwort

0

Dank Hellmar Angabe, hier ist der Arbeitscode. Ich machte zwei Dinge: Ich gab alle zentralen Punkte (0,0) in meinem Flugzeug, subtrahierte die Entfernung zwischen dem zentralen Punkt und (0,0) von allen anderen verwandten Punkten. Ich konnte dann atan2 verwenden, weil alle Winkel, die ich berechnen musste, bei (0,0) lagen. Atan2 ist in diesem Zusammenhang sehr praktisch, weil es nur zwei Punkte benötigt, um den Winkel zu berechnen: Der gemessene Winkel ist immer der bei 0,0. Dies bedeutet wahrscheinlich, dass ich meinen zentralen Punkt nicht als 0,0 setzen muss, da er einfach aus der Gleichung gestrichen wird. Hier ist mein Code. Jeder weitere Rat ist sehr willkommen.

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 

Ich nahm die angle_between Funktion von here