如何将atan2()与其他弧度角系统结合使用

6

我在JavaScript中遇到了这个问题,但这个问题也适用于许多其他语言/环境。

我想让一个对象朝向另一个对象的位置旋转,并使用:

atan2(obj1.dy, obj1.dx) - obj2.getRotation()

来检查第二个对象在给定时间应该顺时针还是逆时针旋转。

在KineticJS中,我正在使用JS / HTML5 / Canvas编程环境,角度从正Y轴开始,按顺时针方向指定为0到2pi的弧度。许多其他编程环境也表现出这种行为。

然而,在使用 Math.atan2(y,x)函数计算第二个对象的移动角度时,角度从正X轴开始,按逆时针方向指定为-π到π。

为了澄清:

Difference between normal radians and atan2()

问题是:

如何从atan2()函数的结果计算出常规弧度的角度?


1
在Javascript/HTML5/Canvas(以及许多其他编程环境)中,角度从0到2 pi以弧度为单位指定,从正Y轴开始顺时针旋转。您确定这是语言规定的约定,而不是您自己的代码库吗?上次我使用画布时,我假设弧度从正X轴开始逆时针移动,一切都按照我预期的方式工作。 - Kevin
1
Kevin,你可能是对的。事实上,我正在为我的当前应用程序使用KineticJS,它的行为方式就像我所说的那样。我不确定这个约定在原始画布上下文中是如何指定的。谢谢你指出这一点,我会进行编辑。 - Qqwy
5个回答

3
值在两种情况下都相同,除以2*PI的余数,并根据不同的符号和偏移约定进行调整。 伪代码:
theta = 0.5*M_PI - atan2(y, x); // adjust for required sign/offset
theta = fmod(theta, 2.0*M_PI);  // make result modulo 2*PI

这似乎是正确的,但答案仍按逆时针方向旋转并旋转了0.5pi弧度。 - Qqwy
错过了那部分,抱歉 - 现在已经更新答案来涵盖这一点。 - Paul R

2

如果你希望角度从y轴的0度开始顺时针增加,则可将角度计算为atan2(x,y)。然而,当x<0时,这会给出负角度,因此在这种情况下应该加上2*pi。


1
如果你的结果在0和π之间,那么结果就很直截了当。如果你的结果在-π和0之间,则将2 * Pi加到你的结果中,这样你的结果就在0、2 * Pi的区间内。
当然,如果你能实现一个单独的函数来进行这种转换,避免重复编写代码,那就更好了。

0

只需使用条件

 var radians = Math.atan2(e.y - cy, e.x - cx);
 if(radians < 0 ) {radians += 2*Math.PI;}

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
canvas.onmousedown = function(e){
var rect = canvas.getBoundingClientRect();
var cx = rect.left + rect.width / 2, cy = rect.top + rect.height / 2;
var radians = Math.atan2(e.y - cy, e.x - cx);
if(radians < 0 ) {radians += 2*Math.PI;}
ctx.moveTo(cx,cy);
ctx.lineTo(cx + 100 * Math.cos(radians), cy + 100* Math.sin(radians));
ctx.stroke();
};
<canvas id="canvas" width="200px" height="200px" style="background-color: gold;"></canvas>


0
float getAngle(float x, float y)
{
    float TAU=PI*2;
    return (atan2(x,y)+TAU)%TAU;
}

感谢您为Stack Overflow社区做出的贡献。这可能是一个正确的答案,但如果您能提供代码的额外解释,那将非常有帮助,这样开发人员就可以理解您的思路。对于不太熟悉语法或难以理解概念的新手开发人员来说,这尤其有用。您是否愿意编辑您的答案,以便为社区的利益提供更多细节? - Jeremy Caney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接