Add infos into target window
[ryzomcore.git] / ryzom / server / src / ai_share / angle.h
blob06ea870ee268864547e2b78a60ee94b01049774d
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef RY_ANGLE_H
20 #define RY_ANGLE_H
22 #include "nel/misc/types_nl.h"
23 #include "nel/misc/vector_2d.h"
25 #include <string>
27 class CAngle
29 public:
30 // enum for pseudo contante
31 enum
33 // the pi value
34 PI = 0x8000
37 CAngle(): _data(0) {}
39 inline CAngle(const CAngle &other) : _data(other._data) {}
40 inline CAngle(const sint16 &val) : _data(val) {}
41 inline CAngle(const sint32 &val) : _data((sint16)val) {}
42 inline CAngle(const uint16 &val) : _data((sint16)val) {}
43 inline CAngle(const uint32 &val) : _data((sint16)val) {}
44 inline CAngle(const double &val)
46 // This code correct a nasty bug :
47 // GCC and MSVC don't handle the cast from a float
48 // into a 16 bit signed interger when the
49 // float value overflow inside the integer.
50 // It seeems that GCC bound the value to 0x8000 (-32768) and 0x7fff (32767)
51 // but MSVC just truncate the exedent bits (as if it perform a float
52 // to 32 bit interger conversion first).
53 // NB : Fundamentaly, the problem is that it is bad to cast something with an overflow... ;)
54 sint32 a = sint32(val*(PI/NLMISC::Pi));
55 while (a >= PI)
56 a-=2*PI;
57 while (a < -PI)
58 a+=2*PI;
60 _data = sint16(a);
63 #ifdef NL_COMP_VC6
64 inline CAngle(const sint &val) : _data((sint16)val) {}
65 inline CAngle(const uint &val) : _data((sint16)val) {}
66 #endif
68 template <class C> bool operator>(const C &other) const { return _data>CAngle(other)._data; }
69 template <class C> bool operator<(const C &other) const { return _data<CAngle(other)._data; }
70 template <class C> bool operator>=(const C &other) const { return _data>=CAngle(other)._data; }
71 template <class C> bool operator<=(const C &other) const { return _data<=CAngle(other)._data; }
72 template <class C> bool operator==(const C &other) const { return _data==CAngle(other)._data; }
73 template <class C> bool operator!=(const C &other) const { return _data!=CAngle(other)._data; }
75 template <class C> CAngle &operator=(const C &val) { _data=CAngle(val)._data; return *this; }
76 template <class C> CAngle &operator+=(const C &val) { _data+=CAngle(val)._data; return *this; }
77 template <class C> CAngle &operator-=(const C &val) { _data-=CAngle(val)._data; return *this; }
78 template <class C> CAngle &operator*=(const C &val) { _data*=val; return *this; }
79 template <class C> CAngle &operator/=(const C &val) { _data/=val; return *this; }
81 template <class C> CAngle operator+(const C &val) { return CAngle(_data+CAngle(val)._data); }
82 template <class C> CAngle operator-(const C &val) { return CAngle(_data-CAngle(val)._data); }
83 template <class C> CAngle operator*(const C &val) { return CAngle(sint16(_data*val)); }
85 CAngle operator/(const double &val) const { return CAngle((sint16)(_data/val)); }
86 float operator/(const CAngle &val) const { return (float)_data/(float)val._data; }
88 CAngle &operator-() { _data=-_data; return *this; }
90 float asRadians() const { return (float)((float)_data*(NLMISC::Pi/PI)); }
91 sint16 asRawSint16() const { return _data; }
92 int asDegrees() const { return (360*(uint16)_data+PI)/(2*PI); }
94 const char* asCompassHeading() { return "NOT IMPLEMENTED YET"; }
95 NLMISC::CVector2d asVector2d() const { float radians=asRadians();return NLMISC::CVector2d(cos(radians), sin(radians)); }
97 inline static const CAngle &pi() { static CAngle p(PI); return p; }
99 private:
100 sint16 _data;
104 //-----------------------------------------------
105 // computeShortestAngle :
106 // Compute the angle between a source and a destination using the shortest way.
107 // \param from : angle between -Pi and Pi;
108 // \param to : angle between -Pi and Pi;
109 //-----------------------------------------------
110 inline double computeShortestAngle(double from, double to)
112 double difAngle = to - from;
113 if (difAngle<-NLMISC::Pi) // Angle in the wrong direction.
114 return difAngle+2.0*NLMISC::Pi;
115 else
117 if (difAngle>NLMISC::Pi) // Angle in the wrong direction.
118 return difAngle-2.0*NLMISC::Pi;
119 else
120 return difAngle;
122 }// computeShortestAngle //
124 #endif