angle.h
Go to the documentation of this file.00001 #ifndef ANGLE_CLASS
00002 #define ANGLE_CLASS
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <basis/byte_array.h>
00019 #include <basis/common_outcomes.h>
00020 #include <basis/contracts.h>
00021 #include <structures/object_packers.h>
00022
00023 #include <math.h>
00024
00025 namespace geometric {
00026
00028
00030 enum angular_units { DEGREES, RADIANS };
00031
00032 template <class contents>
00033 class angle : public basis::packable
00034 {
00035 public:
00036 DEFINE_CLASS_NAME("angle");
00037
00038 angle(contents inital_rotation = 0, angular_units unit = RADIANS);
00040
00041 void set(contents a, angular_units unit);
00043 contents get(angular_units unit) const;
00045
00046 angle operator - (void) const;
00048
00049 angle operator + (const angle &to_add) const;
00050 angle operator - (const angle &to_subtract) const;
00051 angle operator * (contents to_multiply) const;
00052 angle operator / (contents to_divide) const;
00053 angle &operator += (const angle &to_add);
00054 angle &operator -= (const angle &to_subtract);
00055 angle &operator *= (contents to_multiply);
00056 angle &operator /= (contents to_divide);
00057
00058 contents sine() const;
00060 contents cosine() const;
00062 contents tangent() const;
00064
00065 static angle arctangent(contents opposite, contents adjacent,
00066 basis::outcome &retval);
00068
00070 static angle arccosine(contents adjacent, contents hypotenuse,
00071 basis::outcome &retval);
00073 static angle arcsine(contents opposite, contents hypotenuse,
00074 basis::outcome &retval);
00076
00077 virtual int packed_size() const;
00078 virtual void pack(basis::byte_array &packed_form) const;
00080 virtual bool unpack(basis::byte_array &packed_form);
00082
00083 private:
00084 contents _theta;
00085
00086 contents to_internal(contents initial, angular_units unit) const;
00088 contents from_internal(contents initial, angular_units unit) const;
00090 };
00091
00093
00095
00096 class double_angle : public angle<double>
00097 {
00098 public:
00099 double_angle(double init = 0, angular_units unit = RADIANS)
00100 : angle<double>(init, unit) {}
00101 double_angle(const angle<double> &to_copy) : angle<double>(to_copy) {}
00102 };
00103
00105
00106
00107
00108 template <class contents>
00109 angle<contents>::angle(contents a, angular_units unit) { set(a, unit); }
00110
00111 template <class contents>
00112 angle<contents> angle<contents>::operator - (void) const
00113 { angle<contents> to_return(*this); to_return *= -1; return to_return; }
00114
00115 template <class contents>
00116 angle<contents> angle<contents>::operator + (const angle<contents> &a) const
00117 { angle<contents> to_return(*this); to_return += a; return to_return; }
00118
00119 template <class contents>
00120 angle<contents> angle<contents>::operator - (const angle<contents> &a) const
00121 { angle<contents> to_return(*this); to_return -= a; return to_return; }
00122
00123 template <class contents>
00124 angle<contents> angle<contents>::operator * (contents to_multiply) const
00125 {
00126 angle<contents> to_return(*this);
00127 to_return *= to_multiply;
00128 return to_return;
00129 }
00130
00131 template <class contents>
00132 angle<contents> angle<contents>::operator / (contents to_divide) const
00133 { angle<contents> to_return(*this); to_return /= to_divide; return to_return; }
00134
00135 template <class contents>
00136 angle<contents> &angle<contents>::operator += (const angle<contents> &a)
00137 { _theta += a._theta; return *this; }
00138
00139 template <class contents>
00140 angle<contents> &angle<contents>::operator -= (const angle<contents> &a)
00141 { _theta -= a._theta; return *this; }
00142
00143 template <class contents>
00144 angle<contents> &angle<contents>::operator *= (contents f)
00145 { _theta *= f; return *this; }
00146
00147 template <class contents>
00148 angle<contents> &angle<contents>::operator /= (contents f)
00149 { _theta /= f; return *this; }
00150
00151 template <class contents>
00152 contents angle<contents>::sine() const { return sin(_theta); }
00153
00154 template <class contents>
00155 contents angle<contents>::cosine() const { return cos(_theta); }
00156
00157 template <class contents>
00158 contents angle<contents>::tangent() const { return tan(_theta); }
00159
00160 template <class contents>
00161 int angle<contents>::packed_size() const
00162 {
00163 basis::byte_array temp;
00164
00165 pack(temp);
00166 return temp.length();
00167 }
00168
00169 template <class contents>
00170 void angle<contents>::pack(basis::byte_array &packed_form) const
00171 { structures::attach(packed_form, _theta); }
00172
00173 template <class contents>
00174 bool angle<contents>::unpack(basis::byte_array &packed_form)
00175 { return structures::detach(packed_form, _theta); }
00176
00177 template <class contents>
00178 contents angle<contents>::to_internal(contents a, angular_units unit) const
00179 {
00180 switch(unit) {
00181 case RADIANS: return a;
00182 case DEGREES: return a * PI_APPROX / 180.0;
00183 default: return 0;
00184 }
00185 }
00186
00187 template <class contents>
00188 contents angle<contents>::from_internal(contents a, angular_units unit) const
00189 {
00190 switch(unit) {
00191 case RADIANS: return a;
00192 case DEGREES: return a * 180.0 / PI_APPROX;
00193 default: return 0;
00194 }
00195 }
00196
00197 template <class contents>
00198 void angle<contents>::set(contents a, angular_units unit)
00199 { _theta = to_internal(a, unit); }
00200
00201 template <class contents>
00202 contents angle<contents>::get(angular_units unit) const
00203 { return from_internal(_theta, unit); }
00204
00205 template <class contents>
00206 angle<contents> angle<contents>::arccosine(contents adjacent,
00207 contents hypotenuse, basis::outcome &retval)
00208 {
00209 contents d = adjacent / hypotenuse;
00210 retval = basis::common::BAD_INPUT;
00211 bounds_return(d, -1.0, 1.0, angle<contents>());
00212 retval = basis::common::OKAY;
00213 return angle<contents>(acos(d), RADIANS);
00214 }
00215
00216 template <class contents>
00217 angle<contents> angle<contents>::arcsine(contents opposite, contents hypotenuse,
00218 basis::outcome &retval)
00219 {
00220 contents d = opposite / hypotenuse;
00221 retval = basis::common::BAD_INPUT;
00222 bounds_return(d, -1.0, 1.0, angle<contents>());
00223 retval = basis::common::OKAY;
00224 return angle<contents>(asin(d), RADIANS);
00225 }
00226
00227 template <class contents>
00228 angle<contents> angle<contents>::arctangent(contents opposite, contents adjacent,
00229 basis::outcome &retval)
00230 {
00231 retval = basis::common::BAD_INPUT;
00232 if ( (adjacent == 0.0) && (opposite == 0.0) ) return angle<contents>();
00233 retval = basis::common::OKAY;
00234 return angle<contents>(atan2(opposite, adjacent), RADIANS);
00235 }
00236
00237 }
00238
00239 #endif
00240