Je n'utilise plus les mathématiques depuis longtemps et cela devrait être un problème simple à résoudre.
Supposons que j'ai deux points A: (1, 0) et B: (1, -1).
Je veux utiliser un programme (Python ou autre langage de programmation) pour calculer l'angle dans le sens des aiguilles d'une montre entre A, Origine (0, 0) et B. Cela ressemblera à ceci:
angle_clockwise(point1, point2)
Notez que l'ordre des paramètres est important. Puisque le calcul de l'angle se fera dans le sens des aiguilles d'une montre:
En d'autres termes, l'algorithme est comme ceci:
Est-il possible de coder ce problème?
Utilisez le produit interne et le déterminant des deux vecteurs. C’est vraiment ce que vous devez comprendre si vous voulez comprendre comment cela fonctionne. Vous aurez besoin de connaître/lire sur les mathématiques vectorielles pour comprendre.
Voir: https://en.wikipedia.org/wiki/Dot_product et https://en.wikipedia.org/wiki/Determinant
from math import acos
from math import sqrt
from math import pi
def length(v):
return sqrt(v[0]**2+v[1]**2)
def dot_product(v,w):
return v[0]*w[0]+v[1]*w[1]
def determinant(v,w):
return v[0]*w[1]-v[1]*w[0]
def inner_angle(v,w):
cosx=dot_product(v,w)/(length(v)*length(w))
rad=acos(cosx) # in radians
return rad*180/pi # returns degrees
def angle_clockwise(A, B):
inner=inner_angle(A,B)
det = determinant(A,B)
if det<0: #this is a property of the det. If the det < 0 then B is clockwise of A
return inner
else: # if the det > 0 then A is immediately clockwise of B
return 360-inner
Dans le calcul du déterminant, vous concaténez les deux vecteurs pour former une matrice 2 x 2, pour laquelle vous calculez le déterminant.
Numpy's arctan2(y, x)
calculera l'angle dans le sens contraire des aiguilles d'une montre (une valeur en radians comprise entre -π et π) entre l'origine et le point (x, y)
.
Vous pouvez le faire pour vos points A
et B
, puis soustrayez le deuxième angle du premier pour obtenir la différence angulaire signée signée. Cette différence sera comprise entre -2π et 2π. Pour obtenir un angle positif entre 0 et 2π, vous pouvez alors prendre le modulo contre 2π. Enfin, vous pouvez convertir des radians en degrés en utilisant np.rad2deg
.
import numpy as np
def angle_between(p1, p2):
ang1 = np.arctan2(*p1[::-1])
ang2 = np.arctan2(*p2[::-1])
return np.rad2deg((ang1 - ang2) % (2 * np.pi))
Par exemple:
A = (1, 0)
B = (1, -1)
print(angle_between(A, B))
# 45.
print(angle_between(B, A))
# 315.
Si vous ne voulez pas utiliser numpy, vous pouvez utiliser math.atan2
à la place de np.arctan2
et utiliser math.degrees
(ou simplement multiplier par 180 / math.pi
) pour convertir les radians en degrés. Un des avantages de la version numpy est que vous pouvez également passer deux tableaux (2, ...)
pour p1
et p2
afin de calculer les angles entre plusieurs paires de points de manière vectorielle.
Voici une solution qui ne nécessite pas cmath
.
import math
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
v1 = Vector(0, 1)
v2 = Vector(0, -1)
v1_theta = math.atan2(v1.y, v1.x)
v2_theta = math.atan2(v2.y, v2.x)
r = (v2_theta - v1_theta) * (180.0 / math.pi)
if r < 0:
r += 360.0
print r
Découvrez la bibliothèque cmath python.
>>> import cmath
>>> a_phase = cmath.phase(complex(1,0))
>>> b_phase = cmath.phase(complex(1,-1))
>>> (a_phase - b_phase) * 180 / cmath.pi
45.0
>>> (b_phase - a_phase) * 180 / cmath.pi
-45.0
Vous pouvez vérifier si un nombre est inférieur à 0 et ajouter 360 si vous voulez également tous les angles positifs.
Chris St Pierre: lorsque vous utilisez votre fonction avec:
A = (x=1, y=0)
B = (x=0, y=1)
Ceci est supposé être un angle de 90
degré de A
à B
. Votre fonction retournera 270
.
Y a-t-il une erreur dans la façon dont vous traitez le signe du det ou est-ce que je manque quelque chose?
Une formule qui calcule un angle dans le sens des aiguilles d'une montre et qui est utilisée pour l'arpentage:
f(E,N)=pi()-pi()/2*(1+sign(N))* (1-sign(E^2))-pi()/4*(2+sign(N))*sign(E)
-sign(N*E)*atan((abs(N)-abs(E))/(abs(N)+abs(E)))
La formule donne des angles de 0 à 2pi, partant du nord et
travaille pour toute valeur deNetE. ( N = N2-N1 et E = E2-E1 )
Pour N = E = 0 le résultat est indéfini.