在编程语言(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
现在将是该角度的正弦。 - 如果向量的长度为 0,则它与水平轴之间不会有角度(因此它不会有有意义的正弦和余弦)。
编辑(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 实现(由编辑我的答案的 Eric Leschinski 于 2015 年 7 月 19 日提供):
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)
关于c# - 如何计算直线与水平轴之间的角度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7586063/