在编程语言(Python, c#等),我需要确定如何计算一条线和水平轴之间的角度?
我认为图片最能描述我想要的东西:
已知(P1x,P1y)和(P2x,P2y)计算这个角的最佳方法是什么?原点在上左叶,只使用正象限。
在编程语言(Python, c#等),我需要确定如何计算一条线和水平轴之间的角度?
我认为图片最能描述我想要的东西:
已知(P1x,P1y)和(P2x,P2y)计算这个角的最佳方法是什么?原点在上左叶,只使用正象限。
当前回答
我已经在Python中找到了一个很好的解决方案!
from math import atan2,degrees
def GetAngleOfLineBetweenTwoPoints(p1, p2):
return degrees(atan2(p2 - p1, 1))
print GetAngleOfLineBetweenTwoPoints(1,3)
其他回答
首先找到起点和终点之间的差值(这里,这更像是一个有向线段,而不是一条“直线”,因为直线无限延伸,而不是从某个特定的点开始)。
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(delay,deltaX)只是为了获得cos和sin的适当角度可能是不优雅的。在这些情况下,你通常可以做以下事情:
Treat (deltaX, deltaY) as a vector. Normalize that vector to a unit vector. To do so, divide deltaX and deltaY by the vector's length (sqrt(deltaX*deltaX+deltaY*deltaY)), unless the length is 0. After that, deltaX will now be the cosine of the angle between the vector and the horizontal axis (in the direction from the positive X to the positive Y axis at P1). And deltaY will now be the sine of that angle. If the vector's length is 0, it won't have an angle between it and the horizontal axis (so it won't have a meaningful sine and cosine).
编辑(2017年2月28日):即使没有归一化(deltaX, delta):
The sign of deltaX will tell you whether the cosine described in step 3 is positive or negative. The sign of deltaY will tell you whether the sine described in step 4 is positive or negative. The signs of deltaX and deltaY will tell you which quadrant the angle is in, in relation to the positive X axis at P1: +deltaX, +deltaY: 0 to 90 degrees. -deltaX, +deltaY: 90 to 180 degrees. -deltaX, -deltaY: 180 to 270 degrees (-180 to -90 degrees). +deltaX, -deltaY: 270 to 360 degrees (-90 to 0 degrees).
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)
所有测试都通过。参见https://en.wikipedia.org/wiki/Unit_circle
根据参考“彼得O”..这是java版本
private static final float angleBetweenPoints(PointF a, PointF b) {
float deltaY = b.y - a.y;
float deltaX = b.x - a.x;
return (float) (Math.atan2(deltaY, deltaX)); }
matlab函数:
function [lineAngle] = getLineAngle(x1, y1, x2, y2)
deltaY = y2 - y1;
deltaX = x2 - x1;
lineAngle = rad2deg(atan2(deltaY, deltaX));
if deltaY < 0
lineAngle = lineAngle + 360;
end
end
deltaY = Math.Abs(P2.y - P1.y);
deltaX = Math.Abs(P2.x - P1.x);
angleInDegrees = Math.atan2(deltaY, deltaX) * 180 / PI
if(p2.y > p1.y) // Second point is lower than first, angle goes down (180-360)
{
if(p2.x < p1.x)//Second point is to the left of first (180-270)
angleInDegrees += 180;
else //(270-360)
angleInDegrees += 270;
}
else if (p2.x < p1.x) //Second point is top left of first (90-180)
angleInDegrees += 90;
一个从0到2的角的公式。
有x=x2-x1 y=y2-y1。这个公式适用于
x和y的任意值。对于x=y=0,结果没有定义。
f (x, y) = pi) -pi () / 2 * (1 + (x)) * (1-sign (y ^ 2))
-pi()/4*(2+sign(x))*sign(y)
-sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))