00001 #ifndef INCLUDE_UNITCIRCLEANGLE
00002 #define INCLUDE_UNITCIRCLEANGLE
00003
00004 #include "rescuenumerics.h"
00005 #include <math.h>
00006
00007 namespace rescue
00008 {
00009
00024 template<class arithmetic>
00025 class unit_circle_angle
00026 {
00027
00028 public:
00029 arithmetic s;
00030 arithmetic c;
00031 enum {regular,two_pi} type;
00032
00033 public:
00034
00035 unit_circle_angle<arithmetic>()
00036 {
00037 s = 0.0;
00038 c = 1.0;
00039 type = regular;
00040 }
00041
00042 unit_circle_angle<arithmetic>(const unit_circle_angle<arithmetic>& uca)
00043 {
00044 s = uca.s;
00045 c = uca.c;
00046 type = uca.type;
00047 }
00048
00049 unit_circle_angle<arithmetic>(bool angle_two_pi)
00050 {
00051 s = 0.0;
00052 c = 1.0;
00053 if (angle_two_pi)
00054 type = two_pi;
00055 else
00056 type = regular;
00057 }
00058
00059 arithmetic sin() const
00060 {
00061 return s;
00062 }
00063
00064 arithmetic cos() const
00065 {
00066 return c;
00067 }
00068
00070 void bisect()
00071 {
00072 arithmetic s_new = sqrt((1-c)/2.0);
00073 arithmetic c_new = sqrt((1+c)/2.0);
00074 int q = quadrant();
00075 switch (q) {
00076 case 0:
00077 s = s_new;
00078 c = c_new;
00079 break;
00080 case 1:
00081 s = s_new;
00082 c = c_new;
00083 break;
00084 case 2:
00085 s = s_new;
00086 c = -c_new;
00087 break;
00088 case 3:
00089 s = s_new;
00090 c = -c_new;
00091 break;
00092 }
00093
00094
00095 }
00096
00097 inline bool operator==(const unit_circle_angle<arithmetic>& B) const
00098 {
00099 return (type==B.type && s==B.s && c==B.c);
00100 }
00101
00102 inline unit_circle_angle<arithmetic>& operator=(const unit_circle_angle<arithmetic>& uca)
00103 {
00104 type = uca.type;
00105 c = uca.c;
00106 s = uca.s;
00107 return *this;
00108 }
00109
00113 inline int quadrant() const
00114 {
00115 if (type==two_pi)
00116 return 3;
00117
00118
00119
00120 if (sign(s)==0)
00121 if (sign(c)>=0)
00122 return 0;
00123 else
00124 return 2;
00125 else if (sign(s)>0)
00126 if (sign(c)==1)
00127 return 0;
00128 else
00129 return 1;
00130 else
00131 if (sign(c)<0)
00132 return 2;
00133 else
00134 return 3;
00135 }
00136
00137
00138 inline unit_circle_angle<arithmetic>& operator-=(const unit_circle_angle<arithmetic>& B)
00139 {
00140
00141
00142 type = regular;
00143
00144
00145
00146
00147 arithmetic c2 = c*B.c + s*B.s;
00148 arithmetic s2 = s*B.c - c*B.s;
00149 c = c2;
00150 s = s2;
00151 return *this;
00152
00153 }
00154
00155 inline unit_circle_angle<arithmetic>& operator+=(const unit_circle_angle<arithmetic>& B)
00156 {
00157
00158
00159 type = regular;
00160
00161
00162
00163
00164 arithmetic c2 = c*B.c - s*B.s;
00165 arithmetic s2 = s*B.c + c*B.s;
00166 c = c2;
00167 s = s2;
00168 return *this;
00169
00170 }
00171
00172 inline unit_circle_angle<arithmetic> operator+(const unit_circle_angle<arithmetic>& B) const
00173 {
00174 unit_circle_angle<arithmetic> A;
00175 A = *this;
00176 A += B;
00177 return A;
00178 }
00179
00180 inline unit_circle_angle<arithmetic> operator-(const unit_circle_angle<arithmetic>& B) const
00181 {
00182 unit_circle_angle<arithmetic> A;
00183 A = *this;
00184 A -= B;
00185 return A;
00186 }
00187
00188 inline unit_circle_angle<arithmetic>(const arithmetic& sin1, const arithmetic& cos1)
00189 {
00190 type = regular;
00191 00192 00193 00194 00195 00196 00197 00198 00199 00200 00201 00202 00203 00204 00205 00206 00207 00208 00209 00210 00211 00212 00213 00214
00215 s = sin1;
00216 c = cos1;
00217 }
00218
00219 inline bool operator<(const unit_circle_angle<arithmetic>& A) const
00220 {
00221 int q = quadrant();
00222 int qa = A.quadrant();
00223 if (q<qa)
00224 return true;
00225 if (q>qa)
00226 return false;
00227
00228
00229 switch(q)
00230 {
00231 case 0:
00232 return s<A.s;
00233 case 1:
00234 return s>A.s;
00235 case 2:
00236 return s>A.s;
00237 case 3:
00238 return s<A.s;
00239
00240 }
00241 return false;
00242 }
00243
00244 inline bool operator<=(const unit_circle_angle<arithmetic>& A) const
00245 {
00246 return (*this)<A || (*this)==A;
00247 }
00248
00249 inline bool between(const unit_circle_angle<arithmetic>& lower, const unit_circle_angle<arithmetic>& upper) const
00250 {
00251 if (lower<upper)
00252
00253 return lower<*this && *this<upper;
00254 else
00255
00256 return lower<*this || *this<upper;
00257 }
00258
00263 #ifndef RESCUE__IGNORE_RAD
00264 double rad() const
00265 {
00266 double x = atan(s/c);
00267 int q = quadrant();
00268 switch(q)
00269 {
00270 case 0:
00271 return x;
00272 case 1:
00273 return x+PI;
00274 case 2:
00275 return x+PI;
00276 case 3:
00277 return x+2.0*PI;
00278 }
00279 return x;
00280 }
00281 #endif
00282
00283 };
00284
00285 }
00286
00287 #endif