GeoAngle類

 

//=========================================================================
// 作者   : 楊文華
// 郵箱   : [email protected]
// 鏈接   : http://blog.csdn.net/wallsky
// 描述   : 空間角度類的定義文件,GeoAngle.h
// 日期   : 2014年01月29日
//=========================================================================
 
#pragma once
#include <cmath>
#include <string>
using namespace std;
const double pi=3.1415926;
 
class Angle
{
public:
    enum Unit
    {
        radian,     // 弧度,角的基本度量
        degree,     // 角度
        minute,     // 角分
        second,     // 角秒
        dms,        // 度分秒
        degmin,     // 度分
        minsec,     // 分秒
        turn,       // 週數
        gradian,    // 梯度
    };
private:
    double value;
    Unit unit;
public:
    Angle(double v=0,Unit u=radian);
    Angle(int d,int m,double s);
    Angle(int dm,double ms,Unit u);
    Angle(const Angle& other);
 
    void setValue(double v);
    void setUnit(Unit u);
    void assign(double v=0,Unit u=radian);
    void assign(int d,int m,double s);
    void assign(int dm,double ms,Unit u);
 
    double getValue() const;
    Unit getUnit() const;
    string getUnitName() const;
 
    const Angle& toRadian();
    const Angle& toRadian(Angle& an) const;
    const Angle& toDegree();
    const Angle& toDegree(Angle& an) const;
    const Angle& toMinute();
    const Angle& toMinute(Angle& an) const;
    const Angle& toSecond();
    const Angle& toSecond(Angle& an) const;
    const Angle& toDMS();
    const Angle& toDMS(Angle& an) const;
    const Angle& toDegmin();
    const Angle& toDegmin(Angle& an) const;
    const Angle& toMinsec();
    const Angle& toMinsec(Angle& an) const;
    const Angle& toTurn();
    const Angle& toTurn(Angle& an) const;
    const Angle& toGradian();
    const Angle& toGradian(Angle& an) const;
    const Angle& convertTo(Unit u);
    const Angle& convertTo(Angle& an,Unit u) const;
    
    double getRadians() const;
    double getDegrees() const;
    double getMinutes() const;
    double getSeconds() const;
    int getDegreesAsDMS() const;
    int getMinutesAsDMS() const;
    double getSecondsAsDMS() const;
    int getDegreesAsDegmin() const;
    double getMinutesAsDegmin() const;
    int getMinutesAsMinsec() const;
    double getSecondsAsMinsec() const;
    double getTurns() const;
    double getGradians() const;
    double getValue(Unit u) const;
 
    // 關係操作符
    bool operator == (const Angle& rhs) const;
    bool operator != (const Angle& rhs) const;
    bool operator < (const Angle& rhs) const;
    bool operator <= (const Angle& rhs) const;
    bool operator > (const Angle& rhs) const;
    bool operator >= (const Angle& rhs) const;
 
    // 算術運算符
    Angle operator + (const Angle& rhs) const;
    Angle operator - (const Angle& rhs) const;
    friend Angle operator *(const Angle& lhs,double rhs);
    friend Angle operator *(double lhs,const Angle& rhs);
    Angle operator /(double rhs) const;
 
    // 賦值運算符
    Angle& operator = (const Angle& rhs);
    Angle& operator += (const Angle& rhs);
    Angle& operator -= (const Angle& rhs);
    Angle& operator *= (double rhs);
    Angle& operator /= (double rhs);
 
    friend ostream& operator<<(ostream &os,const Angle &other);
};

 

//=========================================================================
// 作者   : 楊文華
// 郵箱   : [email protected]
// 鏈接   : http://blog.csdn.net/wallsky
// 描述   : 空間角度類的定義文件,GeoAngle.h
// 日期   : 2014年01月29日
//=========================================================================
 
#include "GeoAngle.h"
#include <iostream>
#include <process.h>
using namespace std;

int main()
{
 Angle an(pi/2,Angle::radian);
 // 測試角分秒轉換
    an.assign(12,60,30);
    cout<<an<<endl;
    an.assign(112.27,Angle::degree);
    cout<<an.toDMS()<<endl;
    an.assign(70,36,0);
    cout<<an.toDegree()<<endl;
    an.assign(37,14,24);
    cout<<an.toDegree()<<endl<<endl;
 system("pause");
 return 0;
}
 
Angle::Angle(double v,Unit u)
{
    assign(v,u);
}
 
Angle::Angle(int d,int m,double s)
{
    assign(d,m,s);
}
 
Angle::Angle(int dm,double ms,Unit u)
{
    assign(dm,ms,u);
}
 
Angle::Angle(const Angle& other)
{
    value=other.value;
    unit=other.unit;
}
 
void Angle::setValue(double v)
{
    value=v;
}
 
void Angle::setUnit(Unit u)
{
    unit=u;
}
 
void Angle::assign(double v,Unit u)
{
    value=v;
    unit=u;
}
 
void Angle::assign(int d,int m,double s)
{  
    value=d*3600+m*60+s;
    unit=dms;
}
 
void Angle::assign(int dm,double ms,Unit u)
{
    switch(u)
    {
    case degmin:
        value=dm*60+ms;
        unit=degmin;
        break;
    case minsec:
        value=dm*60+ms;
        unit=minsec;
        break;
    default:
        // 不建議
        value=dm+ms;
        unit=u;
        break;
    }
}
 
double Angle::getValue() const
{
    return value;
}
 
Angle::Unit Angle::getUnit() const
{
    return unit;
}
 
string Angle::getUnitName() const
{
    string result;
    switch(unit)
    {
    case radian:
        result="rad"; break;
    case degree:
        result="度"; break;
    case minute:
        result="分"; break;
    case second:
        result="秒"; break;
    case dms:
        result="dms"; break;
    case degmin:
        result="degmin"; break;
    case minsec:
        result="minsec"; break;
    case turn:
        result="turn"; break;  
    case gradian:
        result="grad"; break;
    default:
        result="wrong, undefined unit!"; break;
    }
    return result;
}
 
const Angle& Angle::toRadian()
{
    if(unit!=radian)
    {
        switch(unit)
        {
        case turn:
            value=value*2*pi; break;
        case degree:
            value=value*pi/180; break;
        case minute:
        case degmin:
            value=value*pi/(180*60); break;
        case second:
        case dms:
        case minsec:
            value=value*pi/(180*60*60); break;
        case gradian:
            value=value*pi/200; break;
        default:
            break;
        }
        unit=radian;
    }
    return *this;
}
 
const Angle& Angle::toRadian(Angle& an) const
{
    an=*this;
    an.toRadian();
    return an;
}
 
const Angle& Angle::toDegree()
{
    if(unit!=degree)
    {
        toRadian();
        value=value*180/pi;
        unit=degree;
    }
    return *this;
}
 
const Angle& Angle::toDegree(Angle& an) const
{
    an=*this;
    an.toDegree();
    return an;
}
 
const Angle& Angle::toMinute()
{
    if(unit!=minute)
    {
        toRadian();
        value=value*180*60/pi;
        unit=minute;
    }
    return *this;
}
 
const Angle& Angle::toMinute(Angle& an) const
{
    an=*this;
    an.toMinute();
    return an;
}
 
const Angle& Angle::toSecond()
{
    if(unit!=second)
    {
        toRadian();
        value=value*180*60*60/pi;
        unit=second;
    }
    return *this;
}
 
const Angle& Angle::toSecond(Angle& an) const
{
    an=*this;
    an.toSecond();
    return an;
}
 
const Angle& Angle::toDMS()
{
    toSecond();
    unit=dms;
    return *this;
}
 
const Angle& Angle::toDMS(Angle& an) const
{
    an=*this;
    an.toDMS();
    return an;
}
 
const Angle& Angle::toDegmin()
{
    toMinute();
    unit=degmin;
    return *this;
}
 
const Angle& Angle::toDegmin(Angle& an) const
{
    an=*this;
    an.toDegmin();
    return an;
}
 
const Angle& Angle::toMinsec()
{
    toSecond();
    unit=minsec;
    return *this;
}
 
const Angle& Angle::toMinsec(Angle& an) const
{
    an=*this;
    an.toMinsec();
    return an;
}
 
const Angle& Angle::toTurn()
{
    if(unit!=turn)
    {
        toRadian();
        value=value/(2*pi);
        unit=turn;
    }
    return *this;
}
 
const Angle& Angle::toTurn(Angle& an) const
{
    an=*this;
    an.toTurn();
    return an;
}
 
const Angle& Angle::toGradian()
{
    if(unit!=gradian)
    {
        toRadian();
        value=value*200/pi;
        unit=gradian;
    }
    return *this;
}
 
const Angle& Angle::toGradian(Angle& an) const
{
    an=*this;
    an.toGradian();
    return an;
}
 
const Angle& Angle::convertTo(Unit u)
{
    switch(u)
    {
    case radian:
        toRadian(); break;
    case degree:
        toDegree(); break;
    case minute:
        toMinute(); break;
    case second:
        toSecond(); break;
    case dms:
        toDMS(); break;
    case degmin:
        toDegmin(); break;
    case minsec:
        toMinsec(); break;
    case turn:
        toTurn(); break;
    case gradian:
        toGradian(); break;
    default:
        break;
    }
    return *this;
}
 
const Angle& Angle::convertTo(Angle& an,Unit u) const
{
    switch(u)
    {
    case radian:
        toRadian(an); break;
    case degree:
        toDegree(an); break;
    case minute:
        toMinute(an); break;
    case second:
        toSecond(an); break;
    case dms:
        toDMS(an); break;
    case degmin:
        toDegmin(an); break;
    case minsec:
        toMinsec(an); break;
    case turn:
        toTurn(an); break;
    case gradian:
        toGradian(an); break;
    default:
        break;
    }
    return an;
}
 
double Angle::getRadians() const
{
    Angle t(*this);
    t.toRadian();
    return t.getValue();
}
 
double Angle::getDegrees() const
{
    Angle t(*this);
    t.toDegree();
    return t.getValue();
}
 
double Angle::getMinutes() const
{
    Angle t(*this);
    t.toMinute();
    return t.getValue();
}
 
double Angle::getSeconds() const
{
    Angle t(*this);
    t.toSecond();
    return t.getValue();
}
 
int Angle::getDegreesAsDMS() const
{
    Angle t(*this);
    t.toDMS();
    return int(t.getValue()/3600);
}
 
int Angle::getMinutesAsDMS() const
{
    Angle t(*this);
    t.toDMS();
    return int(abs(fmod(t.getValue(),3600))/60);
}
 
double Angle::getSecondsAsDMS() const
{
    Angle t(*this);
    t.toDMS();
    return abs(fmod(t.getValue(),60));
}
 
int Angle::getDegreesAsDegmin() const
{
    Angle t(*this);
    t.toDegmin();
    return int(t.getValue()/60);
}
 
double Angle::getMinutesAsDegmin() const
{
    Angle t(*this);
    t.toDegmin();
    return abs(fmod(t.getValue(),60));
}
 
int Angle::getMinutesAsMinsec() const
{
    Angle t(*this);
    t.toMinsec();
    return int(t.getValue()/60);
}
 
double Angle::getSecondsAsMinsec() const
{
    Angle t(*this);
    t.toMinsec();
    return abs(fmod(t.getValue(),60));
}
 
double Angle::getTurns() const
{
    Angle t(*this);
    t.toTurn();
    return t.getValue();
}
 
double Angle::getGradians() const
{
    Angle t(*this);
    t.toGradian();
    return t.getValue();
}
 
double Angle::getValue(Unit u) const
{
    switch(u)
    {
    case radian:
        return getRadians();
    case degree:
        return getDegrees();
    case minute:
    case degmin:
        return getMinutes();
    case second:
    case dms:
    case minsec:
        return getSeconds();
    case turn:
        return getTurns();
    case gradian:
        return getGradians();
    default:
        break;
    }
}
 
// 關係操作符
bool Angle::operator == (const Angle& rhs) const
{
    return abs(getRadians()-rhs.getRadians())<1.0e-6;
}
 
bool Angle::operator != (const Angle& rhs) const
{
    return !(*this==rhs);
}
 
bool Angle::operator < (const Angle& rhs) const
{
    return getRadians()-rhs.getRadians()<-1.0e-6;
}
 
bool Angle::operator <= (const Angle& rhs) const
{
    return !(rhs<*this);
}
 
bool Angle::operator > (const Angle& rhs) const
{
    return (rhs<*this);
}
 
bool Angle::operator >= (const Angle& rhs) const
{
    return !(*this<rhs);
}
 
// 算術運算符
Angle Angle::operator + (const Angle& rhs) const
{
    Angle t;
    t.value=getValue()+rhs.getValue(unit);
    t.unit=unit;
    return t;
}
 
Angle Angle::operator - (const Angle& rhs) const
{
    Angle t;
    t.value=getValue()-rhs.getValue(unit);
    t.unit=unit;
    return t;
}
 
Angle operator *(const Angle& lhs,double rhs)
{
    Angle t;
    t.value=lhs.getValue()*rhs;
    t.unit=lhs.unit;
    return t;
}
 
Angle operator *(double lhs,const Angle& rhs)
{
    Angle t;
    t.value=rhs.getValue()*lhs;
    t.unit=rhs.unit;
    return t;
}
 
Angle Angle::operator /(double rhs) const
{
    Angle t;
    t.value=getValue()/rhs;
    t.unit=unit;
    return t;
}
 
// 賦值運算符
Angle& Angle::operator = (const Angle& rhs)
{
    assign(rhs.value,rhs.unit);
    return *this;
}
 
Angle& Angle::operator += (const Angle& rhs)
{
    *this=*this+rhs;
    return *this;
}
 
Angle& Angle::operator -= (const Angle& rhs)
{
    *this=*this-rhs;
    return *this;
}
 
Angle& Angle::operator *= (double rhs)
{
    *this=*this*rhs;
    return *this;
}
 
Angle& Angle::operator /= (double rhs)
{
    *this=*this/rhs;
    return *this;
}
 
ostream& operator<<(ostream &os,const Angle &other)
{
    switch(other.unit)
    {
    case Angle::dms:
        os<<other.getDegreesAsDMS()<<"度"
            <<other.getMinutesAsDMS()<<"分"
            <<other.getSecondsAsDMS()<<"秒";
        break;
    case Angle::degmin:
        os<<other.getDegreesAsDegmin()<<"度"
            <<other.getMinutesAsDegmin()<<"分";
        break;
    case Angle::minsec:
        os<<other.getMinutesAsMinsec()<<"分"
            <<other.getSecondsAsMinsec()<<"秒";
        break;
    default:
        os<<other.getValue()<<other.getUnitName();
        break;
    }
    return os;
}
 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章