任务:计算两条线之间的角度
输入:
浮点数x1,y1(起点)
浮点数x2,y2(终点)
输出:
浮点phi(以度为单位的角度,介于两行之间)
另外:
一条线平行于x轴,且phi为0°≤phi <359°
选项1:
import math
rad_to deg = lambda x: 180.0/math.pi * x
# start-point
x1 = float(input("x1: "))
y1 = float(input("y1: "))
# end-point
x2 = float(input("x2: "))
y2 = float(input("y2: "))
# slope of one line (parallel to the x-axis)
m1 = 0
# slope between the start-point and end-point
# special-case: division with zero
if x1 == x2:
m2 = "Not defined!"
if y2 > y1: # end-point over start-point
phi = 90
elif y2 < y1: # end-point under start-point
phi = 270
else:
m2 = (y2 - y2) / (x2 - x1)
# angle between two lines (smaller angle: 0° < phi < 90°)
angle = rad_to_deg(math.atan(abs((m1 - m2) / (1 + m1 * m2))))
if x1 < x2 and y1 < y2: # 1. quadrant
phi = sw
elif x1 > x2 and y1 < y2: # 2. quadrant
phi = 180 - sw
elif x1 > x2 and y1 > y2: # 3. quadrant
phi = 180 + sw
elif x1 < x2 and y1 > y2: # 4. quadrant
phi = 360 - sw
elif y1 == y2 and x1 > x2: # end-point left from start-point
phi = 180
elif y1 == y2 and x1 < x2 : # end-point right from start-point
phi = 0
elif x1 == x2 and y1 == y2:
phi = "Error, start-point is end-point"
print("angle phi: " + str(phi))
或者应该是try / except的特殊情况?
try:
m2 = (y2 - y2) / (x2 - x1)
except ZeroDivisionError: # x1 == x2
m2 = "Not defined!"
if y2 > y1: # end-point over start-point
phi = 90
elif y2 < y1: # end-point under start-point
phi = 270
选项2:带向量
for math import sqrt, acos, pi
rad_to_deg = lambda x: 180.0/pi * x
x1 = float(input("x1: "))
y1 = float(input("y1: "))
x2 = float(input("x1: "))
y2 = float(input("x2: "))
# vectors
u = [1, 0] # start-point and (a point right from the start-point)
v = [x2 - x1, y2 - y1]
# calculation
u_scalar_v = u[0] * v[0] + u[1] * v[1]
u_amount = sqrt(u[0] * u[0] + u[1] * u[1])
v_amount = sqrt(v[0] * v[0] + v[1] * v[1])
# scalar product
phi = round(rad_to_deg(acos(u_scalar_v / (u_amount * v_amount))), 5)
if y2 >= y1:
pass
else:
phi = 360 - phi
print(phi)
选项3: 是将s的起点,终点和右边的点看成一个三角形,然后计算余弦定理
最有效的计算方法是什么?如何确定?
答案 0 :(得分:1)
Find the Angle between three points from 2D using python提供了一个简单的解决方案。
import math
def getAngle(a, b, c):
ang = math.degrees(math.atan2(c[1]-b[1], c[0]-b[0]) - math.atan2(a[1]-b[1], a[0]-b[0]))
return ang + 360 if ang < 0 else ang
# starting-point
x1 = float(input("x1: "))
y1 = float(input("y1: "))
# middle-point (intersection point)
x2 = float(input("x2: "))
y2 = float(input("y2: "))
# ending point of horizontal line
x3 = x2 + 1 # i.e. horizontal offset from mid-point (x2, y2)
y3 = y2
a = (x1, y1)
b = (x2, y2)
c = (x3, y3)
angle = getAngle(a, b, c)
示例
a = (5, 0)
b = (0, 0)
c = (0, 5)
print(getAngle(a, b, c)) # result 90.0
示例2-随机得分测试
from random import randrange, sample
radius = 10
points = []
for i1 in range(10):
for i2 in range(10):
points.append((randrange(-radius, radius+1), randrange(-radius, radius+1)))
x1y1 = sample(points[:50], 10)
x2y2 = sample(points[50:], 10)
x3y3 = [(x+1, y) for x, y in x2y2]
for i in range(len(x1y1)):
a, b, c = x1y1[i], x2y2[i], x3y3[i]
angle = getAngle(a, b, c)
print(i, ": ", a, b, c, '=> ', angle)
结果
0 : (10, -6) (8, -10) (9, -10) => 296.565051177078
1 : (0, -9) (-4, -3) (-3, -3) => 56.309932474020215
2 : (-6, 10) (5, 9) (6, 9) => 185.1944289077348
3 : (0, 1) (-2, 1) (-1, 1) => 0.0
4 : (2, -1) (-3, 7) (-2, 7) => 57.9946167919165
5 : (2, -3) (-10, -8) (-9, -8) => 337.3801350519596
6 : (2, -6) (-10, 5) (-9, 5) => 42.510447078000844
7 : (7, 8) (7, 3) (8, 3) => 270.0
8 : (2, -2) (-4, 4) (-3, 4) => 45.0
9 : (1, -2) (-2, 7) (-1, 7) => 71.56505117707799