在编程语言(Python, c#等),我需要确定如何计算一条线和水平轴之间的角度?
我认为图片最能描述我想要的东西:
已知(P1x,P1y)和(P2x,P2y)计算这个角的最佳方法是什么?原点在上左叶,只使用正象限。
在编程语言(Python, c#等),我需要确定如何计算一条线和水平轴之间的角度?
我认为图片最能描述我想要的东西:
已知(P1x,P1y)和(P2x,P2y)计算这个角的最佳方法是什么?原点在上左叶,只使用正象限。
当前回答
一个从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)))
其他回答
我已经在Python中找到了一个很好的解决方案!
from math import atan2,degrees
def GetAngleOfLineBetweenTwoPoints(p1, p2):
return degrees(atan2(p2 - p1, 1))
print GetAngleOfLineBetweenTwoPoints(1,3)
抱歉,但我很确定彼得的答案是错的。注意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度,这是错误的。改变延迟计算的顺序,它就能正常工作。
考虑到这个确切的问题,将我们置于一个“特殊”坐标系中,其中正轴意味着向下移动(如屏幕或界面视图),你需要调整这个函数,并负Y坐标:
Swift 2.0中的示例
func angle_between_two_points(pa:CGPoint,pb:CGPoint)->Double{
let deltaY:Double = (Double(-pb.y) - Double(-pa.y))
let deltaX:Double = (Double(pb.x) - Double(pa.x))
var a = atan2(deltaY,deltaX)
while a < 0.0 {
a = a + M_PI*2
}
return a
}
这个函数给出了问题的正确答案。答案是以弧度为单位,所以用角度来表示角度的用法是:
let p1 = CGPoint(x: 1.5, y: 2) //estimated coords of p1 in question
let p2 = CGPoint(x: 2, y : 3) //estimated coords of p2 in question
print(angle_between_two_points(p1, pb: p2) / (M_PI/180))
//returns 296.56
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
一个从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)))