给定围绕坐标的-PI-> PI范围内的2个角度,它们之间的2个角度中的最小值是多少?2角之间的最小差异
考虑到PI和-PI之间的差异不是2PI,而是零。
实施例:
想象一个圆圈,用2线从中心出来,还有那些线之间的2个角度,它们使在里面又名较小角度的角度,和所述角度他们在外面制造,又名大角度。两个角度加起来形成一个完整的圆。假设每个角度都可以在一定范围内,角度值越小,考虑到翻转
给定围绕坐标的-PI-> PI范围内的2个角度,它们之间的2个角度中的最小值是多少?2角之间的最小差异
考虑到PI和-PI之间的差异不是2PI,而是零。
实施例:
想象一个圆圈,用2线从中心出来,还有那些线之间的2个角度,它们使在里面又名较小角度的角度,和所述角度他们在外面制造,又名大角度。两个角度加起来形成一个完整的圆。假设每个角度都可以在一定范围内,角度值越小,考虑到翻转
这使任何角度签署的角度:
a = targetA - sourceA
a = (a + 180) % 360 - 180
当心在许多语言中modulo
操作返回的值与与红利相同的符号(如C,C++,C#,JavaScript,full list here)。这需要一个定制mod
功能,像这样:
mod = (a, n) -> a - floor(a/n) * n
或者说:
mod = (a, n) -> (a % n + n) % n
如果角度在[-180,180]这也适用:
a = targetA - sourceA
a += (a>180) ? -360 : (a<-180) ? 360 : 0
在更详细方式:
a = targetA - sourceA
a -= 360 if a > 180
a += 360 if a < -180
更简单,更有意义的朗读,尽管实际上是同样的东西,第一个bti计算出角度,第二个部分确保它始终是2个可能角度中较小的一个 – 2011-10-25 11:48:29
,尽管人们可能想要做一个%360,例如。如果我有角度0和目标角度721,正确的答案将是1,上面给出的答案将是361 – 2011-10-25 11:51:56
是的,这是真实的和有意的,但绝对值得指出。在我的例子中,我先前从'atan2'得到了'targetA'和'sourceA',因此它们的绝对角度决不会大于360. – bennedich 2011-10-26 01:31:56
如果你的两个角度是x和y,那么它们之间的角度之一是abs(x - Y)。另一个角度是(2 * PI) - abs(x - y)。这样的最小的2角的值是:
min((2 * PI) - abs(x - y), abs(x - y))
这给你的角度的绝对值,它假定输入是归一化(即:范围[0, 2π)
内)。
如果要保留角度的符号(即:方向),并且也接受范围[0, 2π)
以外的角度,则可以概括上述内容。这里是广义的版本Python代码:
PI = math.pi
TAU = 2*PI
def smallestSignedAngleBetween(x, y):
a = (x - y) % TAU
b = (y - x) % TAU
return -a if a < b else b
注意,%
运营商不具有相同的行为在所有的语言,特别是当负值都参与其中,所以如果移植一些迹象的调整可能是必要的。
测试套件失败https://gist.github.com/bradphelan/7fe21ad8ebfcb43696b8 – bradgonesurfing 2015-07-13 08:45:19
@bradgonesurfing这是/是真的,但公平地说,你的测试检查了东西原始问题中没有指定,特别是非标准化的输入和标志保存。编辑答案中的第二个版本应该通过您的测试。 – 2015-07-23 19:20:31
x是目标角度。 y是源或起始角度:
atan2(sin(x-y), cos(x-y))
它返回带符号的增量角度。请注意,根据您的API,atan2()函数的参数顺序可能不同。
这个工程。为什么? – ericsoco 2013-05-11 18:25:52
'x-y'给你角度的不同,但它可能超出了期望的范围。想想这个角度定义单位圆上的一个点。该点的坐标是'(cos(x-y),sin(x-y))'。 'atan2'返回该点的角度(相当于'x-y'),除了它的范围是[-PI,PI]。 – Max 2013-09-02 16:17:55
这通过测试套件https://gist.github.com/bradphelan/7fe21ad8ebfcb43696b8 – bradgonesurfing 2015-07-13 08:43:09
我升到提供签名回答的挑战:
def f(x,y):
import math
return min(y-x, y-x+2*math.pi, y-x-2*math.pi, key=abs)
啊...答案是顺便说一句Python函数。对不起,我暂时处于Python模式。希望没关系。 – 2010-01-05 16:20:46
我会在楼上的代码中插入新的公式,看看会发生什么!(thankyou^_ ^) – 2010-01-05 17:25:42
我很确定PeterB的回答也是正确的。和evilly hackish。 :) – 2010-01-05 18:04:17
Ari (与算法相反)解决方案:
angle = Pi - abs(abs(a1 - a2) - Pi);
测试套件失败https://gist.github.com/bradphelan/7fe21ad8ebfcb43696b8 – bradgonesurfing 2015-07-13 08:39:58
没有必要计算三角函数。在C语言中的简单代码:
#include <math.h>
#define PIV2 M_PI+M_PI
#define C360 360.0000000000000000000
double difangrad(double x, double y)
{
double arg;
arg = fmod(y-x, PIV2);
if (arg < 0) arg = arg + PIV2;
if (arg > M_PI) arg = arg - PIV2;
return (-arg);
}
double difangdeg(double x, double y)
{
double arg;
arg = fmod(y-x, C360);
if (arg < 0) arg = arg + C360;
if (arg > 180) arg = arg - C360;
return (-arg);
}
让DIF = A - B,弧度
dif = difangrad(a,b);
让DIF = A - B,以度
dif = difangdeg(a,b);
difangdeg(180.000000 , -180.000000) = 0.000000
difangdeg(-180.000000 , 180.000000) = -0.000000
difangdeg(359.000000 , 1.000000) = -2.000000
difangdeg(1.000000 , 359.000000) = 2.000000
没有罪,没有COS,没有棕褐色,....只有几何!
错误!由于您将PIV2定义为“M_PI + M_PI” ,而不是“(M_PI + M_PI)“,行'arg = arg - PIV2;'扩展为'arg = arg - M_PI + M_PI',所以什么都不做。 – canton7 2014-01-19 11:53:03
对于UnityEngine用户,简单的方法是使用Mathf.DeltaAngle。
在我明白你的意思之前,我读了3次。请添加一个例子,或者更好地解释... – Kobi 2009-12-10 06:12:04
想象一个圆,从中心向外划出两条线,这两条线之间有两个角度,它们在内部形成的角度又称为较小的角度,以及它们形成的角度在外面,也就是更大的角度。两个角度加起来形成一个完整的圆。考虑到每个角度都可以在一定的范围内,考虑到翻转,角度值越小越好 – 2009-12-10 06:14:32
[如何计算直线与横轴之间的角度?](https://stackoverflow.com/questions/7586063/how-to-calculation-the-angle-between-a-line-and-the-horizontal-axis) – 2017-07-09 20:33:49