feisty meow concerns codebase  2.140
angle.h
Go to the documentation of this file.
1 #ifndef ANGLE_CLASS
2 #define ANGLE_CLASS
3 
4 /*****************************************************************************\
5 * *
6 * Name : angle *
7 * Author : Chris Koeritz *
8 * *
9 *******************************************************************************
10 * Copyright (c) 1992-$now By Author. This program is free software; you can *
11 * redistribute it and/or modify it under the terms of the GNU General Public *
12 * License as published by the Free Software Foundation; either version 2 of *
13 * the License or (at your option) any later version. This is online at: *
14 * http://www.fsf.org/copyleft/gpl.html *
15 * Please send any updates to: fred@gruntose.com *
16 \*****************************************************************************/
17 
18 #include <basis/byte_array.h>
19 #include <basis/common_outcomes.h>
20 #include <basis/contracts.h>
22 
23 #include <math.h>
24 
25 namespace geometric {
26 
28 
31 
32 template <class contents>
33 class angle : public basis::packable
34 {
35 public:
37 
38  angle(contents inital_rotation = 0, angular_units unit = RADIANS);
40 
41  void set(contents a, angular_units unit);
43  contents get(angular_units unit) const;
45 
46  angle operator - (void) const;
48 
49  angle operator + (const angle &to_add) const;
50  angle operator - (const angle &to_subtract) const;
51  angle operator * (contents to_multiply) const;
52  angle operator / (contents to_divide) const;
53  angle &operator += (const angle &to_add);
54  angle &operator -= (const angle &to_subtract);
55  angle &operator *= (contents to_multiply);
56  angle &operator /= (contents to_divide);
57 
58  contents sine() const;
60  contents cosine() const;
62  contents tangent() const;
64 
65  static angle arctangent(contents opposite, contents adjacent,
66  basis::outcome &retval);
68 
70  static angle arccosine(contents adjacent, contents hypotenuse,
71  basis::outcome &retval);
73  static angle arcsine(contents opposite, contents hypotenuse,
74  basis::outcome &retval);
76 
77  virtual int packed_size() const;
78  virtual void pack(basis::byte_array &packed_form) const;
80  virtual bool unpack(basis::byte_array &packed_form);
82 
83 private:
84  contents _theta;
85 
86  contents to_internal(contents initial, angular_units unit) const;
88  contents from_internal(contents initial, angular_units unit) const;
90 };
91 
93 
95 
96 class double_angle : public angle<double>
97 {
98 public:
99  double_angle(double init = 0, angular_units unit = RADIANS)
100  : angle<double>(init, unit) {}
101  double_angle(const angle<double> &to_copy) : angle<double>(to_copy) {}
102 };
103 
105 
106 // implementation of larger methods below.
107 
108 template <class contents>
109 angle<contents>::angle(contents a, angular_units unit) { set(a, unit); }
110 
111 template <class contents>
113 { angle<contents> to_return(*this); to_return *= -1; return to_return; }
114 
115 template <class contents>
117 { angle<contents> to_return(*this); to_return += a; return to_return; }
118 
119 template <class contents>
121 { angle<contents> to_return(*this); to_return -= a; return to_return; }
122 
123 template <class contents>
125 {
126  angle<contents> to_return(*this);
127  to_return *= to_multiply;
128  return to_return;
129 }
130 
131 template <class contents>
133 { angle<contents> to_return(*this); to_return /= to_divide; return to_return; }
134 
135 template <class contents>
137 { _theta += a._theta; return *this; }
138 
139 template <class contents>
141 { _theta -= a._theta; return *this; }
142 
143 template <class contents>
145 { _theta *= f; return *this; }
146 
147 template <class contents>
149 { _theta /= f; return *this; }
150 
151 template <class contents>
152 contents angle<contents>::sine() const { return sin(_theta); }
153 
154 template <class contents>
155 contents angle<contents>::cosine() const { return cos(_theta); }
156 
157 template <class contents>
158 contents angle<contents>::tangent() const { return tan(_theta); }
159 
160 template <class contents>
162 {
163  basis::byte_array temp;
164 //hmmm: inefficient!
165  pack(temp);
166  return temp.length();
167 }
168 
169 template <class contents>
170 void angle<contents>::pack(basis::byte_array &packed_form) const
171 { structures::attach(packed_form, _theta); }
172 
173 template <class contents>
175 { return structures::detach(packed_form, _theta); }
176 
177 template <class contents>
178 contents angle<contents>::to_internal(contents a, angular_units unit) const
179 {
180  switch(unit) {
181  case RADIANS: return a;
182  case DEGREES: return a * PI_APPROX / 180.0;
183  default: return 0;
184  }
185 }
186 
187 template <class contents>
188 contents angle<contents>::from_internal(contents a, angular_units unit) const
189 {
190  switch(unit) {
191  case RADIANS: return a;
192  case DEGREES: return a * 180.0 / PI_APPROX;
193  default: return 0;
194  }
195 }
196 
197 template <class contents>
198 void angle<contents>::set(contents a, angular_units unit)
199 { _theta = to_internal(a, unit); }
200 
201 template <class contents>
203 { return from_internal(_theta, unit); }
204 
205 template <class contents>
207  contents hypotenuse, basis::outcome &retval)
208 {
209  contents d = adjacent / hypotenuse;
210  retval = basis::common::BAD_INPUT;
211  bounds_return(d, -1.0, 1.0, angle<contents>());
212  retval = basis::common::OKAY;
213  return angle<contents>(acos(d), RADIANS);
214 }
215 
216 template <class contents>
217 angle<contents> angle<contents>::arcsine(contents opposite, contents hypotenuse,
218  basis::outcome &retval)
219 {
220  contents d = opposite / hypotenuse;
221  retval = basis::common::BAD_INPUT;
222  bounds_return(d, -1.0, 1.0, angle<contents>());
223  retval = basis::common::OKAY;
224  return angle<contents>(asin(d), RADIANS);
225 }
226 
227 template <class contents>
228 angle<contents> angle<contents>::arctangent(contents opposite, contents adjacent,
229  basis::outcome &retval)
230 {
231  retval = basis::common::BAD_INPUT;
232  if ( (adjacent == 0.0) && (opposite == 0.0) ) return angle<contents>();
233  retval = basis::common::OKAY;
234  return angle<contents>(atan2(opposite, adjacent), RADIANS);
235 }
236 
237 } // namespace.
238 
239 #endif
240 
int length() const
Returns the current reported length of the allocated C array.
Definition: array.h:115
A very common template for a dynamic array of bytes.
Definition: byte_array.h:36
Outcomes describe the state of completion for an operation.
Definition: outcome.h:31
A base class for objects that can pack into an array of bytes.
Definition: byte_array.h:87
contents cosine() const
returns the cos function of this angle.
Definition: angle.h:155
angle operator*(contents to_multiply) const
Definition: angle.h:124
angle & operator/=(contents to_divide)
Definition: angle.h:148
angle & operator+=(const angle &to_add)
Definition: angle.h:136
virtual void pack(basis::byte_array &packed_form) const
packs the angle for shipping in bytes.
Definition: angle.h:170
contents sine() const
returns the sin function of this angle.
Definition: angle.h:152
contents get(angular_units unit) const
retrieves the current angular measure.
Definition: angle.h:202
static angle arcsine(contents opposite, contents hypotenuse, basis::outcome &retval)
returns the asin of the angle.
Definition: angle.h:217
static angle arctangent(contents opposite, contents adjacent, basis::outcome &retval)
returns the atan of the angle.
Definition: angle.h:228
void set(contents a, angular_units unit)
sets the angle to a new rotation "a" in the "unit".
Definition: angle.h:198
contents tangent() const
returns the tan function of this angle.
Definition: angle.h:158
virtual bool unpack(basis::byte_array &packed_form)
unpacks the angle from the "packed_form".
Definition: angle.h:174
angle(contents inital_rotation=0, angular_units unit=RADIANS)
constructs a new angle with "initial_rotation" in the "unit".
Definition: angle.h:109
angle operator-(void) const
returns the negation of this angle.
Definition: angle.h:112
angle operator+(const angle &to_add) const
Definition: angle.h:116
angle & operator*=(contents to_multiply)
Definition: angle.h:144
static angle arccosine(contents adjacent, contents hypotenuse, basis::outcome &retval)
returns the acos of the angle.
Definition: angle.h:206
DEFINE_CLASS_NAME("angle")
angle & operator-=(const angle &to_subtract)
Definition: angle.h:140
angle operator/(contents to_divide) const
Definition: angle.h:132
virtual int packed_size() const
Estimates the space needed for the packed structure.
Definition: angle.h:161
double_angle provides a non-templated class for forward declarations.
Definition: angle.h:97
double_angle(double init=0, angular_units unit=RADIANS)
Definition: angle.h:99
double_angle(const angle< double > &to_copy)
Definition: angle.h:101
#define PI_APPROX
An approximation of the fundamental circular constant.
Definition: definitions.h:41
#define bounds_return(value, low, high, to_return)
Verifies that "value" is between "low" and "high", inclusive.
Definition: guards.h:48
Contains all of our objects for geometry and avoids name clashes.
Definition: angle.h:25
angular_units
Represents a geometric angle.
Definition: angle.h:30
@ DEGREES
Definition: angle.h:30
@ RADIANS
Definition: angle.h:30
void attach(byte_array &packed_form, const byte_array &to_attach)
Packs a byte_array "to_attach" into "packed_form".
void pack(basis::byte_array &packed_form, const set< contents > &to_pack)
provides a way to pack any set that stores packable objects.
Definition: set.h:131
bool detach(byte_array &packed_form, byte_array &to_detach)
Unpacks a byte_array "to_detach" from "packed_form".