为什么atan2函数的参数是Y,X而不是X,Y?

34

C语言中,atan2函数的签名如下:

double atan2( double y, double x );

其他语言也这样做。这是我所知道的唯一一个按Y,X顺序而不是X,Y顺序获取参数的函数,它经常让我混淆,因为当我考虑坐标时,我想到的是(X,Y)。

有人知道为什么atan2的参数顺序约定是这样吗?


为什么这被标记为语言无关? - Matthew Groves
@mgroves 这种情况在许多编程语言中都会发生。 - victor hugo
因为相同的格式出现在很多语言中。从atan2维基条目中可以看到:“它至少可以追溯到FORTRAN编程语言,并且目前可以在C编程语言的math.h标准库、Java Math库、C#静态Math类以及其他地方找到。许多脚本语言,如Perl,包括C风格的atan2函数。” - CookieOfFortune
对于给你带来的困扰我很抱歉,但如果是(x,y)的话,那就会让我陷入麻烦。 - Nosredna
我在80年代用BASIC编写了我的第一个Atan2()函数,当时并不知道任何惯例(我认为我发明了切片面包),所以我将参数设为(x,y)。从那时起,我总是搞混参数的顺序。也许提问者有类似的经历。这完全取决于你熟悉什么。 - John Alexiou
6个回答

29

因为它涉及到arctan(y/x),所以y先出现。

这里有一个很棒的链接,谈论了一些关于它的内容:Angles and Directions


某个程序员在时间的迷雾中决定这样做是有道理的。(为什么叫做'atan2'呢?为什么不叫'angle_for'呢?我曾经以为它是反正切平方...) - Alex Feinman
2
是的,arctan(y/x) 出现的频率非常高,如果 arctan2 接受 x,y 作为参数,那么我会一直被搞糊涂。把斜杠改成逗号真是太好了。 - Nosredna
@alex - 这里使用atan2是因为它需要两个参数,以区分于atan(),后者需要在之前进行y/x的除法运算。 - JustJeff
2
这不是唯一的原因,atan()不能处理当x和y都为负数时的差异,而atan2()可以。 - CookieOfFortune
1
@1owk3y 谢谢,我已经修复了。 - CookieOfFortune

13

我一直认为这是由于三角函数的定义,也就是说

tan(theta) = opposite / adjacent

当使用原点的正角度时,对边始终是Y轴,临边始终是X轴,因此:

atan2(opposite, adjacent) = theta

也就是说,这样做是为了避免与数学定义相关的排序混乱。


Soh Cah Toa 是我的助记词 :) - Not Sure
2
七年级?你肯定没上过公立学校 :) - Not Sure

1
假设一个直角三角形,对边称为y,邻边称为x:
tan(角度) = y/x
arctan(tan(角度)) = arctan(y/x)

1

这是因为在学校中,计算梯度的助记符是上升/前进,或者换句话说是dy/dx,更简洁地说就是y/x。

这个顺序已经悄悄地进入了反正切函数的参数中。

所以这是一个历史文物。对我来说,这取决于我使用atan2时正在思考什么。如果我在考虑微分,我就能理解它,如果我在考虑坐标对,我就会错误地使用它。


我在想如果变量被标记为dx和dy是否会更清晰? - CookieOfFortune

0

在Excel中,顺序是atan2(X,Y),所以我认为反向顺序是一种编程技巧。将atan(Y/X)轻松更改为atan2(Y,X),只需在“n”和“(”之间放置一个“2”,并用“,”替换“/”,仅需两个操作。相反的顺序需要4个操作,并且其中一些操作会更加复杂(剪切和粘贴)。

我经常在Excel中计算数学问题,然后将其移植到.NET,因此有时会卡在atan2上。最好能够统一规范atan2的使用方式。


0

如果 atan2 的参数顺序被颠倒,那将更加方便。这样,在计算极角时就不需要担心翻转参数了。Mathematica 的等效函数就是这样做的:https://reference.wolfram.com/language/ref/ArcTan.html

早在 FORTRAN 时代,就有一个 ATAN2 函数,其参数顺序不太方便,在 this reference manual 中被(有些不准确地)描述为 arctan(arg1 / arg2)。

初期创建者可能固执于 atan2(arg1, arg2) 是(或多或少是)arctan(arg1 / arg2),并且这个决定被盲目地从 FORTRAN 复制到了 C、C++、Python、Java 和 JavaScript 中。


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