ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitCommon/MathTools/interface/Angle.h
Revision: 1.4
Committed: Sun Jan 24 21:00:19 2010 UTC (15 years, 3 months ago) by bendavid
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_032, Mit_031, Mit_025c_branch2, Mit_025c_branch1, Mit_030, Mit_029c, Mit_030_pre1, Mit_029a, Mit_029, Mit_029_pre1, Mit_028a, Mit_025c_branch0, Mit_028, Mit_027a, Mit_027, Mit_026, Mit_025e, Mit_025d, Mit_025c, Mit_025b, Mit_025a, Mit_025, Mit_025pre2, Mit_024b, Mit_025pre1, Mit_024a, Mit_024, Mit_023, Mit_022a, Mit_022, Mit_020d, TMit_020d, Mit_020c, Mit_021, Mit_021pre2, Mit_021pre1, Mit_020b, Mit_020a, Mit_020, Mit_020pre1, Mit_018, Mit_017, Mit_017pre3, Mit_017pre2, Mit_017pre1, V07-05-00, Mit_016, Mit_015b, Mit_015a, Mit_015, Mit_014e, Mit_014d, Mit_014c, Mit_014b, ConvRejection-10-06-09, Mit_014a, Mit_014, Mit_014pre3, Mit_014pre2, Mit_014pre1, Mit_013d, Mit_013c, Mit_013b, Mit_013a, Mit_013, Mit_013pre1, HEAD
Branch point for: Mit_025c_branch
Changes since 1.3: +10 -9 lines
Log Message:
Fix compiler errors and warnings moving to slc5_ia32_gcc434

File Contents

# User Rev Content
1 loizides 1.1 //--------------------------------------------------------------------------------------------------
2 bendavid 1.4 // $Id: Angle.h,v 1.3 2009/07/20 03:12:22 loizides Exp $
3 loizides 1.1 //
4     // Angle classes, with automatic range checking. SignedAngle ranges from -PI to PI, UnsignedAngle
5     // from 0 to 2PI. The two types of angle convert implicitly into double.
6     //
7     // The Angle classes reimplement (inline) most arithmetic operators, instead of relying on the
8     // implicit conversion to double and converting the result back when it is assigned to an Angle
9     // variable. There are two reasons for this:
10     //
11     // 1) Temporary values are kept in range (example: std::cout << alpha+beta)
12     // 2) Optimization (the difference of two Angles is guaranteed to lie less
13     // than 2PI outside the allowed range, for example)
14     //
15     // The only exception is multiplication: the "2" in "2 * alpha" could be interpreted as a length. If
16     // you want the result of a multiplication to be bounded, assign it to a temporary Angle, or use *=.
17     //
18     // Due to operator ambiguity, some mixed-type arithmetics might fail:
19     // for example, (int + Angle) or (Angle / long)
20     // The most common operations are supported:
21     // double +- angle; angle +-/ double; angle / int
22     //
23     // Comparison between Angles is done via conversion to double. Make sure you do not compare a
24     // SignedAngle to an UnsignedAngle.
25     //
26     // Since the bounds and return types for the two classes are different, operators cannot be factored
27     // in a single superclass.
28     //
29     // In C++, implicit conversion operators are shallow - they are not nested. Therefore, if you want
30     // to convert a SignedAngle into an UnsignedAngle, you need an intermediate cast into double. For
31     // example:
32     //
33     // SignedAngle s; UnsignedAngle u = double(s);
34     //
35     // Adding a direct conversion between the two types of angle would result in several ambiguities.
36     //
37 loizides 1.2 // Author: C.Paus (stolen from CDF implementation of Paolo Gatti, University of Padova / INFN,
38     // therefore not all our coding conventions fulfilled)
39 loizides 1.1 //--------------------------------------------------------------------------------------------------
40    
41     #ifndef MITCOMMON_MATHTOOLS_ANGLE_H
42     #define MITCOMMON_MATHTOOLS_ANGLE_H
43    
44 loizides 1.3 #include <Riostream.h>
45     #include <Rtypes.h>
46 loizides 1.1 #include <math.h>
47 bendavid 1.4 #include <limits>
48 loizides 1.1
49     namespace mithep
50     {
51     //--------------------------------------------------------------------------------------------------
52     //
53     // Signed angles, ranging from -PI to +PI
54     //
55     //--------------------------------------------------------------------------------------------------
56     class SignedAngle
57     {
58     public:
59     // Constructor
60     SignedAngle(double angle = 0.0);
61    
62     // No destructor; use standard copy constructor and assignment operator
63    
64     // Implicit conversion to double
65     operator double() const;
66    
67     // Self-modifying operations
68     SignedAngle& operator += (const SignedAngle& other);
69     SignedAngle& operator -= (const SignedAngle& other);
70     SignedAngle& operator *= (double other);
71     SignedAngle& operator /= (double other);
72    
73     // Other operations
74     friend SignedAngle operator + (double me, const SignedAngle& other);
75     SignedAngle operator + (const SignedAngle& other) const;
76     SignedAngle operator + (double other) const;
77     friend SignedAngle operator - (double me, const SignedAngle& other);
78     SignedAngle operator - (const SignedAngle& other) const;
79     SignedAngle operator - (double other) const;
80     SignedAngle operator / (double other) const;
81     SignedAngle operator / (int other) const;
82    
83     // I/O
84 bendavid 1.4 //friend std::ostream& operator << (std::ostream& out, const SignedAngle& me)
85     // { out << me.fValue; return out; }
86 loizides 1.1
87 bendavid 1.4 //friend std::istream& operator >> (std::istream& in, SignedAngle& me)
88     // { in >> me.fValue; me.FixRangeSlow(); return in; }
89 loizides 1.1
90     private:
91     // Enforce the correct range for the angle's value. The first version is faster, but assumes
92     // the current value is within 2PI of the correct range. The second version is slower but
93     // always works
94     void FixRangeFast();
95     void FixRangeSlow();
96    
97     double fValue;
98 loizides 1.3
99     ClassDef(SignedAngle, 0) // Signed angle class
100 loizides 1.1 };
101    
102    
103     //--------------------------------------------------------------------------------------------------
104     //
105     // Unsigned angles, ranging from 0 to 2PI
106     //
107     //--------------------------------------------------------------------------------------------------
108     class UnsignedAngle
109     {
110     public:
111     // Constructor
112     UnsignedAngle(double angle = 0.0);
113    
114     // No destructor; use standard copy constructor and assignment operator
115    
116     // Implicit conversion to double
117     operator double() const;
118    
119     // Self-modifying operations
120     UnsignedAngle& operator += (const UnsignedAngle& other);
121     UnsignedAngle& operator -= (const UnsignedAngle& other);
122     UnsignedAngle& operator *= (double other);
123     UnsignedAngle& operator /= (double other);
124    
125     // Other operations
126     friend UnsignedAngle operator + (double me, const UnsignedAngle& other);
127     UnsignedAngle operator + (const UnsignedAngle& other) const;
128     UnsignedAngle operator + (double other) const;
129     friend UnsignedAngle operator - (double me, const UnsignedAngle& other);
130     UnsignedAngle operator - (const UnsignedAngle& other) const;
131     UnsignedAngle operator - (double other) const;
132     UnsignedAngle operator / (double other) const;
133     UnsignedAngle operator / (int other) const;
134    
135     // I/O
136 bendavid 1.4 // friend std::ostream& operator << (std::ostream& out, const UnsignedAngle& me)
137     // { out << me.fValue; return out; }
138     // friend std::istream& operator >> (std::istream& in, UnsignedAngle& me)
139     // { in >> me.fValue; me.FixRangeSlow(); return in; }
140 loizides 1.1
141     private:
142     // Enforce the correct range for the angle's value. The first version is faster,
143     // but assumes the current value is within 2PI of the correct range.
144     // The second version is slower but always works.
145    
146     void FixRangeFast();
147     void FixRangeSlow();
148    
149     double fValue;
150 loizides 1.3
151     ClassDef(UnsignedAngle, 0) // Unsigned angle class
152 loizides 1.1 };
153    
154     // By default, "Angles" are unsigned (CDF convention: 0-2PI range).
155     typedef UnsignedAngle Angle;
156    
157 loizides 1.2 //--------------------------------------------------------------------------------------------------
158     inline
159     void mithep::SignedAngle::FixRangeFast()
160     {
161     if (fValue >= M_PI)
162 loizides 1.1 fValue -= 2 * M_PI;
163 loizides 1.2 else if (fValue < -M_PI)
164     fValue += 2 * M_PI;
165     }
166 loizides 1.1
167 loizides 1.2 //--------------------------------------------------------------------------------------------------
168     inline
169     void mithep::SignedAngle::FixRangeSlow()
170     {
171     if (fValue < -M_PI) {
172     if (fValue < double(std::numeric_limits<int>::min()) * 2 * M_PI)
173     std::cout << "@SUB=SignedAngle::FixRangeSlow"
174     << "Angle out of range: " << fValue << std::endl;
175     else {
176     int shift = int((M_PI - fValue) / (2 * M_PI));
177     fValue += shift * 2 * M_PI;
178     }
179 loizides 1.1 }
180 loizides 1.2 // The previous step might have brought -3PI to +PI, so no 'else' here.
181     if (fValue >= M_PI) {
182     if (fValue > double(std::numeric_limits<int>::max()) * 2 * M_PI) {
183     std::cout << "@SUB=SignedAngle::FixRangeSlow"
184     << "Angle out of range: " << fValue << std::endl;
185     }
186     else {
187     int shift = int((fValue + M_PI) / (2 * M_PI));
188     fValue -= shift * 2 * M_PI;
189     }
190 loizides 1.1 }
191     }
192    
193    
194 loizides 1.2 //--------------------------------------------------------------------------------------------------
195     inline
196     mithep::SignedAngle::SignedAngle(double angle)
197     : fValue(angle)
198     {
199     // Constructor
200 loizides 1.1
201 loizides 1.2 FixRangeSlow();
202     }
203 loizides 1.1
204 loizides 1.2 //--------------------------------------------------------------------------------------------------
205     inline
206     mithep::SignedAngle::operator double() const
207     {
208     // Implicit conversion to double
209     return fValue;
210     }
211 loizides 1.1
212     // Self-modifying operations
213 loizides 1.2 //--------------------------------------------------------------------------------------------------
214     inline
215     mithep::SignedAngle& mithep::SignedAngle::operator += (const mithep::SignedAngle& other)
216     {
217     fValue += other.fValue;
218     FixRangeFast(); // other.fValue is guaranteed to be in range
219     return *this;
220     }
221 loizides 1.1
222 loizides 1.2 //--------------------------------------------------------------------------------------------------
223 loizides 1.1 inline
224 loizides 1.2 mithep::SignedAngle& mithep::SignedAngle::operator -= (const mithep::SignedAngle& other)
225     {
226     fValue -= other.fValue;
227     FixRangeFast(); // other.fValue is guaranteed to be in range
228     return *this;
229     }
230 loizides 1.1
231 loizides 1.2 //--------------------------------------------------------------------------------------------------
232     inline
233     mithep::SignedAngle& mithep::SignedAngle::operator *= (double other)
234     {
235     fValue *= other;
236     FixRangeSlow();
237     return *this;
238     }
239 loizides 1.1
240 loizides 1.2 //--------------------------------------------------------------------------------------------------
241     inline
242     mithep::SignedAngle& mithep::SignedAngle::operator /= (double other)
243     {
244     fValue /= other;
245     FixRangeSlow();
246     return *this;
247     }
248 loizides 1.1
249     // Other operations
250 loizides 1.2 //--------------------------------------------------------------------------------------------------
251     inline
252     mithep::SignedAngle operator + (double me, const mithep::SignedAngle& other)
253     {
254     mithep::SignedAngle result(me);
255     result += other;
256     return result;
257     }
258 loizides 1.1
259 loizides 1.2 //--------------------------------------------------------------------------------------------------
260     inline
261     mithep::SignedAngle mithep::SignedAngle::operator + (const mithep::SignedAngle& other) const
262     {
263     mithep::SignedAngle result(*this);
264     result += other;
265     return result;
266     }
267 loizides 1.1
268 loizides 1.2 //--------------------------------------------------------------------------------------------------
269     inline
270     mithep::SignedAngle mithep::SignedAngle::operator + (double other) const
271     {
272     return mithep::SignedAngle(fValue + other);
273     }
274 loizides 1.1
275 loizides 1.2 //--------------------------------------------------------------------------------------------------
276     inline
277     mithep::SignedAngle operator - (double me, const mithep::SignedAngle& other)
278     {
279     mithep::SignedAngle result(me);
280     result -= other;
281     return result;
282     }
283 loizides 1.1
284 loizides 1.2 //--------------------------------------------------------------------------------------------------
285     inline
286     mithep::SignedAngle mithep::SignedAngle::operator - (const mithep::SignedAngle& other) const
287     {
288     mithep::SignedAngle result(*this);
289     result -= other;
290     return result;
291     }
292 loizides 1.1
293 loizides 1.2 //--------------------------------------------------------------------------------------------------
294     inline
295     mithep::SignedAngle mithep::SignedAngle::operator - (double other) const
296     {
297     return mithep::SignedAngle(fValue - other);
298     }
299 loizides 1.1
300 loizides 1.2 //--------------------------------------------------------------------------------------------------
301     inline
302     mithep::SignedAngle mithep::SignedAngle::operator / (double other) const
303     {
304     mithep::SignedAngle result(*this);
305     result /= other;
306     return result;
307     }
308 loizides 1.1
309 loizides 1.2 //--------------------------------------------------------------------------------------------------
310     inline
311     mithep::SignedAngle mithep::SignedAngle::operator / (int other) const
312     {
313     mithep::SignedAngle result(*this);
314     result /= other;
315     return result;
316     }
317 loizides 1.1
318 loizides 1.2 //--------------------------------------------------------------------------------------------------
319     inline
320     void mithep::UnsignedAngle::FixRangeFast()
321     {
322     if (fValue >= 2 * M_PI)
323     fValue -= 2 * M_PI;
324     else if (fValue < 0)
325     fValue += 2 * M_PI;
326     }
327 loizides 1.1
328 loizides 1.2 //--------------------------------------------------------------------------------------------------
329     inline
330     void mithep::UnsignedAngle::FixRangeSlow()
331     {
332     if (fValue < 0) {
333     if (fValue < double(std::numeric_limits<int>::min()) * 2 * M_PI)
334     std::cout << "@SUB=UnsignedAngle::FixRangeSlow"
335     << "Angle out of range: " << fValue << std::endl;
336     else {
337     int shift = 1 - int(fValue / (2 * M_PI));
338     fValue += shift * 2 * M_PI;
339     }
340 loizides 1.1 }
341     // The previous step might have brought -2PI to +2PI, so no 'else' here.
342 loizides 1.2 if (fValue >= 2 * M_PI) {
343     if (fValue > double(std::numeric_limits<int>::max()) * 2 * M_PI)
344     std::cout << "@SUB=UnsignedAngle::FixRangeSlow"
345     << "Angle out of range: " << fValue << std::endl;
346     else {
347     int shift = int(fValue / (2 * M_PI));
348     fValue -= shift * 2 * M_PI;
349     }
350 loizides 1.1 }
351     }
352    
353 loizides 1.2 //--------------------------------------------------------------------------------------------------
354     inline
355     mithep::UnsignedAngle::UnsignedAngle(double angle)
356     : fValue(angle)
357     {
358     // Constructor
359     FixRangeSlow();
360     }
361 loizides 1.1
362 loizides 1.2 //--------------------------------------------------------------------------------------------------
363     inline
364     mithep::UnsignedAngle::operator double() const
365     {
366     // Implicit conversion to double
367    
368     return fValue;
369     }
370 loizides 1.1
371     // Self-modifying operations
372 loizides 1.2 //--------------------------------------------------------------------------------------------------
373     inline
374     mithep::UnsignedAngle& mithep::UnsignedAngle::operator += (const mithep::UnsignedAngle& other)
375     {
376     fValue += other.fValue;
377     FixRangeFast(); // other.fValue is guaranteed to be in range
378     return *this;
379     }
380 loizides 1.1
381 loizides 1.2 //--------------------------------------------------------------------------------------------------
382     inline
383     mithep::UnsignedAngle& mithep::UnsignedAngle::operator -= (const mithep::UnsignedAngle& other)
384     {
385     fValue -= other.fValue;
386     FixRangeFast(); // other.fValue is guaranteed to be in range
387     return *this;
388     }
389 loizides 1.1
390 loizides 1.2 //--------------------------------------------------------------------------------------------------
391     inline
392     mithep::UnsignedAngle& mithep::UnsignedAngle::operator *= (double other)
393     {
394     fValue *= other;
395     FixRangeSlow();
396     return *this;
397     }
398 loizides 1.1
399 loizides 1.2 //--------------------------------------------------------------------------------------------------
400     inline
401     mithep::UnsignedAngle& mithep::UnsignedAngle::operator /= (double other)
402     {
403     fValue /= other;
404     FixRangeSlow();
405     return *this;
406     }
407 loizides 1.1
408     // Other operations
409 loizides 1.2 //--------------------------------------------------------------------------------------------------
410     inline
411     mithep::UnsignedAngle operator + (double me, const mithep::UnsignedAngle& other)
412     {
413     mithep::UnsignedAngle result(me);
414     result += other;
415     return result;
416     }
417 loizides 1.1
418 loizides 1.2 //--------------------------------------------------------------------------------------------------
419     inline
420     mithep::UnsignedAngle mithep::UnsignedAngle::operator + (const mithep::UnsignedAngle& other) const
421     {
422     mithep::UnsignedAngle result(*this);
423     result += other;
424     return result;
425     }
426 loizides 1.1
427 loizides 1.2 //--------------------------------------------------------------------------------------------------
428     inline
429     mithep::UnsignedAngle mithep::UnsignedAngle::operator + (double other) const
430     {
431     return mithep::UnsignedAngle(fValue + other);
432     }
433 loizides 1.1
434 loizides 1.2 //--------------------------------------------------------------------------------------------------
435     inline
436     mithep::UnsignedAngle operator - (double me, const mithep::UnsignedAngle& other)
437     {
438     mithep::UnsignedAngle result(me);
439     result -= other;
440     return result;
441     }
442 loizides 1.1
443 loizides 1.2 //--------------------------------------------------------------------------------------------------
444     inline
445     mithep::UnsignedAngle mithep::UnsignedAngle::operator - (const mithep::UnsignedAngle& other) const
446     {
447     mithep::UnsignedAngle result(*this);
448     result -= other;
449     return result;
450     }
451 loizides 1.1
452 loizides 1.2 //--------------------------------------------------------------------------------------------------
453     inline
454     mithep::UnsignedAngle mithep::UnsignedAngle::operator - (double other) const
455     {
456     return mithep::UnsignedAngle(fValue - other);
457     }
458 loizides 1.1
459 loizides 1.2 //--------------------------------------------------------------------------------------------------
460     inline
461     mithep::UnsignedAngle mithep::UnsignedAngle::operator / (double other) const
462     {
463     mithep::UnsignedAngle result(*this);
464     result /= other;
465     return result;
466     }
467 loizides 1.1
468 loizides 1.2 //--------------------------------------------------------------------------------------------------
469     inline
470     mithep::UnsignedAngle mithep::UnsignedAngle::operator / (int other) const
471     {
472     mithep::UnsignedAngle result(*this);
473     result /= other;
474     return result;
475     }
476 loizides 1.1 } //close namespace here because of friend declarations
477     #endif