例項講解C語言atan和atan2函式
使用時需要預包含#include <math.h>
(1)atan(x) 不包括角度的象限資訊,返回值在[-pi/2,pi/2]
The atan function computes the principal value of the arc tangent of x, returning a value in the range [-pi/2, pi/2]. 由於tan函式是以pi為週期的tanθ=tan(θ+pi),所以radAngle=atan(slope)實際上返回的是數學上atan(slope)的在[-pi/2, pi/2]之間的主值部分,注意radAngle以弧度為單位。例如pi/4的正切值為1,pi/4 + pi = 5pi/4的正切值也是1,此時C語言中計算的atan(1)=pi/4僅僅是位於tan函式在[-pi/2,pi/2]的部分,也就是說atan丟失了角度的象限資訊,不能通過radAngle=atan(slope)來判斷radAngle位於哪個象限。
#include <stdio.h>
#include <math.h>
#define PI 3.14159
int main(int argc, char *argv[])
{
float radAngle,degAngle;
radAngle = atan(1); //atan(x) returns a value in the range [-pi/2, pi/2]
degAngle = radAngle*180/PI;
printf("arctangent in radians %f\n",radAngle); // 僅僅給出了第一象限的結果,第三象限的角度值不可能通過atan求出
printf("arctangent in degrees %f\n",degAngle);
radAngle = atan(-1);
degAngle = radAngle*180/PI;
printf("arctangent in radians %f\n",radAngle); //僅僅給出了第四象限的結果,不可能給出第二象限的結果
printf("arctangent in degrees %f\n",degAngle);
return 0;
}
(2)atan2(y,x) 包含角度的象限資訊,返回值在[-pi,pi]
The atan2 function computes the principal value of the arc tangent of y / x, using the signs of both arguments to determine the quadrant of the return value. 由於atan2包含角度的象限資訊所以用的比atan多。
1)一個比較實用的功能就是將直角座標系下的點(x,y)轉換為極座標系下的點(rho,theta)。x = rho * cos(theta); y = rho * sin(theta),rho = sqrt( x^2 + y^2); theta = atan2(y,x)。
2)atan2計算兩點間連線的傾斜角,這種方法非常的有用。在OpengL中視角fovy的計算就用到了atan2如下所示
// Calculating Field of View
#define PI 3.1415926535
double calculateAngle(double size, double distance)
{
double radtheta, degtheta;
radtheta = 2.0 * atan2 (size/2.0, distance);
degtheta = (180.0 * radtheta) / PI;
return degtheta;
}
atan2(y,x)函式返回點(x,y)和原點(0,0)之間直線的傾斜角.那麼如何計算任意兩點間直線的傾斜角呢?只需要將兩點x,y座標分別相減得到一個新的點(x2-x1,y2-y1).然後利用他求出角度就可以了.使用下面的一個轉換可以實現計算出兩點間連線的夾角.
atan2(y2-y1,x2-x1)不過這樣我們得到的是一個弧度值,在一般情況下我們需要把它轉換為一個角度.
下面我們用一段程式碼來測試一下這樣的轉換.
//測試,計算點(3,3)和(5,5)構成的連線的夾角
x=atan2(5-3,5-3)//輸出0.785398
x=x*180/pi//轉換為角度,輸出45.000038
#include <stdio.h>
#include <math.h>
#define PI 3.14159
int main(int argc, char *argv[])
{
float radAngle,degAngle;
radAngle = atan2(7,7); //atan(x) returns a value in the range [-pi/2, pi/2]
degAngle = radAngle*180/PI;
printf("in the fist quadrant,arctangent in radians %f\n",radAngle);
printf("in the fist quadrant,arctangent in degrees %f\n",degAngle);
radAngle = atan2(-7,7);
degAngle = radAngle*180/PI;
printf("in the second quadrant,arctangent in radians %f\n",radAngle);
printf("in the second quadrant,arctangent in degrees %f\n",degAngle);
radAngle = atan2(-7,-7);
degAngle = radAngle*180/PI;
printf("in the third quadrant,arctangent in radians %f\n",radAngle);
printf("in the third quadrant,arctangent in degrees %f\n",degAngle);
radAngle = atan2(7,-7);
degAngle = radAngle*180/PI;
printf("in the fourth quadrant,arctangent in radians %f\n",radAngle);
printf("in the fourth quadrant,arctangent in degrees %f\n",degAngle);
return 0;
}