1. 程式人生 > >例項講解C語言atan和atan2函式

例項講解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;
}