在编程语言(Python, c#等),我需要确定如何计算一条线和水平轴之间的角度?

我认为图片最能描述我想要的东西:

已知(P1x,P1y)和(P2x,P2y)计算这个角的最佳方法是什么?原点在上左叶,只使用正象限。


当前回答

根据参考“彼得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)); }

其他回答

根据参考“彼得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)); }
import math
from collections import namedtuple


Point = namedtuple("Point", ["x", "y"])


def get_angle(p1: Point, p2: Point) -> float:
    """Get the angle of this line with the horizontal axis."""
    dx = p2.x - p1.x
    dy = p2.y - p1.y
    theta = math.atan2(dy, dx)
    angle = math.degrees(theta)  # angle is in (-180, 180]
    if angle < 0:
        angle = 360 + angle
    return angle

测试

为了测试,我让假设生成测试用例。

import hypothesis.strategies as s
from hypothesis import given


@given(s.floats(min_value=0.0, max_value=360.0))
def test_angle(angle: float):
    epsilon = 0.0001
    x = math.cos(math.radians(angle))
    y = math.sin(math.radians(angle))
    p1 = Point(0, 0)
    p2 = Point(x, y)
    assert abs(get_angle(p1, p2) - angle) < epsilon

我已经在Python中找到了一个很好的解决方案!

from math import atan2,degrees

def GetAngleOfLineBetweenTwoPoints(p1, p2):
    return degrees(atan2(p2 - p1, 1))

print GetAngleOfLineBetweenTwoPoints(1,3)

一个从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)))

抱歉,但我很确定彼得的答案是错的。注意y轴是向下的(在图形中很常见)。因此,延迟计算必须反转,否则就会得到错误的答案。

考虑:

System.out.println (Math.toDegrees(Math.atan2(1,1)));
System.out.println (Math.toDegrees(Math.atan2(-1,1)));
System.out.println (Math.toDegrees(Math.atan2(1,-1)));
System.out.println (Math.toDegrees(Math.atan2(-1,-1)));

给了

45.0
-45.0
135.0
-135.0

因此,如果在上面的例子中,P1是(1,1),P2是(2,2)[因为Y在页面上向下增加],上面的代码将给出所示示例的45.0度,这是错误的。改变延迟计算的顺序,它就能正常工作。