在编程语言(Python,C#等)中,我需要确定如何计算直线和水平轴之间的角度?
我认为一张图片最能说明我想要的内容:
给定(P1x,P1y)和(P2x,P2y),计算此角度的最佳方法是什么?原点在左上角,仅使用正象限。
最佳答案
首先找到起点和终点之间的差异(在这里,这更多的是有向线段,而不是“线”,因为线无限延伸且不在特定点处开始)。
deltaY = P2_y - P1_y
deltaX = P2_x - P1_x
然后计算角度(从
P1
的正X轴到P1
的正Y轴)。angleInDegrees = arctan(deltaY / deltaX) * 180 / PI
但是
arctan
可能并不理想,因为以这种方式划分差异将消除区分角度所在象限所需的区分(请参见下文)。如果您的语言包含atan2
函数,请改用以下代码:angleInDegrees = atan2(deltaY, deltaX) * 180 / PI
编辑(2017年2月22日):但是,通常来说,仅为了获得
atan2(deltaY,deltaX)
和cos
的正确角度而调用sin
可能不太好。在这种情况下,通常可以改为执行以下操作:(deltaX, deltaY)
视为向量。 deltaX
和deltaY
除以向量的长度(sqrt(deltaX*deltaX+deltaY*deltaY)
),除非长度为0。deltaX
现在将是向量和水平轴之间的角度的余弦值(在P1
处,从X轴正方向到Y轴正方向)。 deltaY
现在将成为该角度的正弦。 编辑(2017年2月28日):即使未规范化
(deltaX, deltaY)
:deltaX
的符号将告诉您步骤3中描述的余弦是正还是负。 deltaY
的符号将告诉您步骤4中描述的正弦是正还是负。 deltaX
和deltaY
的符号会告诉您相对于P1
的正X轴,该角度位于哪个象限:+deltaX
,+deltaY
:0到90度。 -deltaX
,+deltaY
:90至180度。 -deltaX
,-deltaY
:180到270度(-180到-90度)。 +deltaX
,-deltaY
:270至360度(-90至0度)。 使用弧度的Python实现(由2015年7月19日由编辑我的答案的Eric Leschinski提供):
from math import *
def angle_trunc(a):
while a < 0.0:
a += pi * 2
return a
def getAngleBetweenPoints(x_orig, y_orig, x_landmark, y_landmark):
deltaY = y_landmark - y_orig
deltaX = x_landmark - x_orig
return angle_trunc(atan2(deltaY, deltaX))
angle = getAngleBetweenPoints(5, 2, 1,4)
assert angle >= 0, "angle must be >= 0"
angle = getAngleBetweenPoints(1, 1, 2, 1)
assert angle == 0, "expecting angle to be 0"
angle = getAngleBetweenPoints(2, 1, 1, 1)
assert abs(pi - angle) <= 0.01, "expecting angle to be pi, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 3)
assert abs(angle - pi/2) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 0)
assert abs(angle - (pi+pi/2)) <= 0.01, "expecting angle to be pi+pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(1, 1, 2, 2)
assert abs(angle - (pi/4)) <= 0.01, "expecting angle to be pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -2, -2)
assert abs(angle - (pi+pi/4)) <= 0.01, "expecting angle to be pi+pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -1, 2)
assert abs(angle - (pi/2)) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
所有测试均通过。参见https://en.wikipedia.org/wiki/Unit_circle
关于c# - 如何计算一条线与水平轴之间的角度?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7586063/