[算法][C]計算向量的角度


C 語言里 double atan2(double y,double x) 返回的是原點至點(x,y)的方位角,即與 x 軸的夾角。也可以理解為復數 x+yi 的輻角。返回值的單位為弧度,取值范圍為
   
Excel 里 ATAN2(x,y)返回的是原點至點(x,y)的方位角。返回值的單位為弧度,取值范圍為
   
注意:
1、C 函數與 Excel 函數的參數順序正好相反;
2、C 函數允許 x、y 同時為零,Excel 不允許 x、y 同時為零。

與 atan 的不同

atan2 比 atan 穩定。
如:atan(y/x),當 y 遠遠大於 x 時,計算結果是不穩定的。
atan2(y,x)的做法:當 x 的絕對值比 y 的絕對值大時使用 atan(y/x);反之使用 atan(x/y)。這樣就保證了數值穩定性。

舉例

atan2(y,x)是表示X-Y平面上所對應的(x,y)坐標的角度,它的值域范圍是(-Pi,Pi)
用數學表示就是:atan2(y,x)=arg(y/x)-Pi
當y<0時,其值為負,
當y>0時,其值為正.

例子:
#include <stdio.h>
#include <math.h>

int main(void)
{
double result;
double x = 20.0, y = 10.0;

result = atan2(y, x);
printf("The arc tangent ratio of %lf is %lf\n", (y / x), result);
return 0;
}

 

在C語言的math.h或C++中的cmath中有兩個求反正切的函數atan(double x)與atan2(double y,double x)  他們返回的值是弧度 要轉化為角度再自己處理下。

前者接受的是一個正切值(直線的斜率)得到夾角,但是由於正切的規律性本可以有兩個角度的但它卻只返回一個,因為atan的值域是從-90~90 也就是它只處理一四象限,所以一般不用它。

第二個atan2(double y,double x) 其中y代表已知點的Y坐標 同理x ,返回值是此點與遠點連線與x軸正方向的夾角,這樣它就可以處理四個象限的任意情況了,它的值域相應的也就是-180~180了

例如:

例1:斜率是1的直線的夾角

cout<<atan(1.0)*180/PI;//45°

cout<<atan2(1.0,1.0)*180/PI;//45° 第一象限

cout<<atan2(-1.0,-1.0)*180/PI;//-135°第三象限

后兩個斜率都是1 但是atan只能求出一個45°

例2:斜率是-1的直線的角度

cout<<atan(-1.0)*180/PI;//-45°

cout<<atan2(-1.0,1.0)*180/PI;//-45° y為負 在第四象限

cout<<atan2(1.0,-1.0)*180/PI;//135° x為負 在第二象限

 

常用的不是求過原點的直線的夾角 往往是求一個線段的夾角 這對於atan2就更是如魚得水了

例如求A(1.0,1.0) B(3.0,3.0)這個線段AB與x軸正方向的夾角

用atan2表示為 atan2(y2-y1,x2-x1) 即 atan2(3.0-1.0,3.0-1.0)

它的原理就相當於把A點平移到原點B點相應變成B'(x2-x1,y2-y1)點 這樣就又回到先前了

例三:

A(0.0,5.0) B(5.0,10.0)

線段AB的夾角為

cout<<atan2(5.0,5.0)*180/PI;//45°

 

#include "stdafx.h"
#include <iostream>
using namespace  std;
//#define F_PATH "D:\\project\\testtest\\test_tan\\test_tan\\1.txt"  
#define  PI 3.1415926
int _tmain(int argc, _TCHAR* argv[])
{
 
    double ang = 0.0 ;
    double  angle = 0.0 ;
 
    angle = atan2(2.0,1.0);              //63
    ang = angle*180/PI ;
    cout << ang <<endl ;
 
    angle = atan2(-2.0,1.0) ;     // -63 , 4象限
    ang = angle*180/PI ;
    cout << ang <<endl ;
 
    angle = atan2(2.0,-1.0) ;            // 116  ,2象限
    ang = angle*180/PI ;
    cout << ang <<endl ;
 
    angle = atan2(-2.0,-1.0) ;            // -116   3象限
    ang = angle*180/PI ;
    cout << ang <<endl ; 
    cin.get();
    return 0;
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM