00001 #ifndef ANGLE_IMPLEMENTATION
00002 #define ANGLE_IMPLEMENTATION
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "angle.h"
00019
00020 #include <basis/definitions.h>
00021 #include <basis/guards.h>
00022
00023 #include <math.h>
00024
00025 namespace geometric {
00026
00027 template <class contents>
00028 angle<contents>::angle(contents a, angular_units unit) { set(a, unit); }
00029
00030 template <class contents>
00031 angle<contents> angle<contents>::operator - (void) const
00032 { angle<contents> to_return(*this); to_return *= -1; return to_return; }
00033
00034 template <class contents>
00035 angle<contents> angle<contents>::operator + (const angle<contents> &a) const
00036 { angle<contents> to_return(*this); to_return += a; return to_return; }
00037
00038 template <class contents>
00039 angle<contents> angle<contents>::operator - (const angle<contents> &a) const
00040 { angle<contents> to_return(*this); to_return -= a; return to_return; }
00041
00042 template <class contents>
00043 angle<contents> angle<contents>::operator * (contents to_multiply) const
00044 {
00045 angle<contents> to_return(*this);
00046 to_return *= to_multiply;
00047 return to_return;
00048 }
00049
00050 template <class contents>
00051 angle<contents> angle<contents>::operator / (contents to_divide) const
00052 { angle<contents> to_return(*this); to_return /= to_divide; return to_return; }
00053
00054 template <class contents>
00055 angle<contents> &angle<contents>::operator += (const angle<contents> &a)
00056 { _theta += a._theta; return *this; }
00057
00058 template <class contents>
00059 angle<contents> &angle<contents>::operator -= (const angle<contents> &a)
00060 { _theta -= a._theta; return *this; }
00061
00062 template <class contents>
00063 angle<contents> &angle<contents>::operator *= (contents f)
00064 { _theta *= f; return *this; }
00065
00066 template <class contents>
00067 angle<contents> &angle<contents>::operator /= (contents f)
00068 { _theta /= f; return *this; }
00069
00070 template <class contents>
00071 contents angle<contents>::sine() const { return sin(_theta); }
00072
00073 template <class contents>
00074 contents angle<contents>::cosine() const { return cos(_theta); }
00075
00076 template <class contents>
00077 contents angle<contents>::tangent() const { return tan(_theta); }
00078
00079 template <class contents>
00080 void angle<contents>::pack(byte_array &packed_form) const
00081 { basis::attach(packed_form, _theta); }
00082
00083 template <class contents>
00084 bool angle<contents>::unpack(byte_array &packed_form)
00085 { return basis::detach(packed_form, _theta); }
00086
00087 template <class contents>
00088 contents angle<contents>::to_internal(contents a, angular_units unit) const
00089 {
00090 switch(unit) {
00091 case RADIANS: return a;
00092 case DEGREES: return a * PI_APPROX / 180.0;
00093 default: return 0;
00094 }
00095 }
00096
00097 template <class contents>
00098 contents angle<contents>::from_internal(contents a, angular_units unit) const
00099 {
00100 switch(unit) {
00101 case RADIANS: return a;
00102 case DEGREES: return a * 180.0 / PI_APPROX;
00103 default: return 0;
00104 }
00105 }
00106
00107 template <class contents>
00108 void angle<contents>::set(contents a, angular_units unit)
00109 { _theta = to_internal(a, unit); }
00110
00111 template <class contents>
00112 contents angle<contents>::get(angular_units unit) const
00113 { return from_internal(_theta, unit); }
00114
00115 template <class contents>
00116 angle<contents> angle<contents>::arccosine(contents adjacent,
00117 contents hypotenuse, outcome &retval)
00118 {
00119 contents d = adjacent / hypotenuse;
00120 retval = common::BAD_INPUT;
00121 bounds_return(d, -1.0, 1.0, angle<contents>());
00122 retval = common::OKAY;
00123 return angle<contents>(acos(d), angle<contents>::RADIANS);
00124 }
00125
00126 template <class contents>
00127 angle<contents> angle<contents>::arcsine(contents opposite, contents hypotenuse,
00128 outcome &retval)
00129 {
00130 contents d = opposite / hypotenuse;
00131 retval = common::BAD_INPUT;
00132 bounds_return(d, -1.0, 1.0, angle<contents>());
00133 retval = common::OKAY;
00134 return angle<contents>(asin(d), angle<contents>::RADIANS);
00135 }
00136
00137 template <class contents>
00138 angle<contents> angle<contents>::arctangent(contents adjacent,
00139 contents opposite, outcome &retval)
00140 {
00141 retval = common::BAD_INPUT;
00142 if ( (adjacent == 0.0) && (opposite == 0.0) ) return angle<contents>();
00143 retval = common::OKAY;
00144 return angle<contents>(atan2(opposite, adjacent), angle<contents>::RADIANS);
00145 }
00146
00147 }
00148
00149 #endif
00150