//=========================================================================
// 作者 : 杨文华
// 邮箱 : wallsky@sina.cn
// 链接 : http://blog.youkuaiyun.com/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);
};
//=========================================================================
// 作者 : 杨文华
// 邮箱 : wallsky@sina.cn
// 链接 : http://blog.youkuaiyun.com/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;
}