angle.h

Go to the documentation of this file.
00001 #ifndef ANGLE_CLASS
00002 #define ANGLE_CLASS
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : angle                                                             *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 1992-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
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 // implementation of larger methods below.
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 //hmmm: inefficient!
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 } // namespace.
00238 
00239 #endif
00240 
Generated on Sat Jan 28 04:22:41 2012 for hoople2 project by  doxygen 1.6.3