1 //------------------------------------------------------------------------------
2 // Copyright (c) 2001-2002, Haiku, Inc.
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
22 // File Name: Angle.cpp
23 // Author: DarkWyrm <bpmagic@columbus.rr.com>
24 // Description: Angle class for speeding up trig functions
26 //------------------------------------------------------------------------------
31 #define ANGLE_PI 3.14159265358979323846
34 static bool sTablesInitialized
= false;
35 static float sSinTable
[360];
36 static float sCosTable
[360];
37 static float sTanTable
[360];
41 \param angle Value in degrees
43 Angle::Angle(float angle
)
61 //! Constrains angle to 0 <= angle <= 360
65 // if the value of the angle is >=360 or <0, make it so that it is
66 // within those bounds
67 fAngleValue
= fmodf(fAngleValue
, 360);
73 \brief Obtains the sine of the angle
74 \return The sine of the angle
79 return sSinTable
[(int)fAngleValue
];
83 \brief Calculates an angle given a float value
84 \param value Number between 0 and 1 inclusive
85 \return The angle obtained or 0 if value passed was invalid
88 Angle::InvSine(float value
)
90 // Returns the inverse sine of a value in the range 0 <= value <= 1 via
91 // reverse-lookup any value out of range causes the function to return 0
93 // Filter out bad values
100 while (value
< sSinTable
[i
])
103 // current sSinTable[i] is less than value. Pick the degree value which is closer
104 // to the passed value
105 if ((value
- sSinTable
[i
]) > (sSinTable
[i
+ 1] - value
))
108 return Angle(i
); // value is closer to previous
113 \brief Obtains the cosine of the angle
114 \return The cosine of the angle
119 return sCosTable
[(int)fAngleValue
];
123 \brief Calculates an angle given a float value
124 \param value Number between 0 and 1 inclusive
125 \return The angle obtained or 0 if value passed was invalid
128 Angle::InvCosine(float value
)
130 // Returns the inverse cosine of a value in the range 0 <= value <= 1 via
131 // reverse-lookup any value out of range causes the function to return 0
133 // Filter out bad values
140 while (value
> sCosTable
[i
])
143 // current sCosTable[i] is less than value. Pick the degree value which is closer
144 // to the passed value
145 if ((value
- sCosTable
[i
]) < (sCosTable
[i
+ 1] - value
))
148 return Angle(i
); // value is closer to previous
152 \brief Obtains the tangent of the angle
153 \return The tangent of the angle
156 Angle::Tangent(int *status
)
158 if (fAngleValue
== 90 || fAngleValue
== 270) {
164 return sTanTable
[(int)fAngleValue
];
168 \brief Returns the inverse tangent of a value given
169 \param value Number between 0 and 1 inclusive
170 \return The angle found or 0 if value was invalid
173 Angle::InvTangent(float value
)
175 // Filter out bad values
182 while (value
> sTanTable
[i
])
185 if ((value
- sTanTable
[i
]) < (sTanTable
[i
+1] - value
))
188 return Angle(i
); // value is closer to previous
192 \brief Returns a value based on what quadrant the angle is in
194 - \c 1: 0 <= angle <90
195 - \c 2: 90 <= angle < 180
196 - \c 3: 180 <= angle < 270
197 - \c 4: 270 <= angle < 360
202 // We can get away with not doing extra value checks because of the order in
203 // which the checks are done.
204 if (fAngleValue
< 90)
207 if (fAngleValue
< 180)
210 if (fAngleValue
< 270)
217 \brief Obtains the angle constrained to between 0 and 180 inclusive
218 \return The constrained value
221 Angle::Constrain180()
223 // Constrains angle to 0 <= angle < 180
224 if (fAngleValue
< 180)
225 return Angle(fAngleValue
);
227 float value
= fmodf(fAngleValue
, 180);;
234 \brief Obtains the angle constrained to between 0 and 90 inclusive
235 \return The constrained value
240 // Constrains angle to 0 <= angle < 90
241 if (fAngleValue
< 90)
242 return Angle(fAngleValue
);
244 float value
= fmodf(fAngleValue
, 90);;
251 \brief Sets the angle's value and normalizes the value
252 \param angle Value in degrees
255 Angle::SetValue(float angle
)
268 //! Initializes the global trig tables
270 Angle::_InitTrigTables()
272 if (sTablesInitialized
)
274 sTablesInitialized
= true;
276 for(int32 i
= 0; i
< 90; i
++) {
277 double currentRadian
= (i
* ANGLE_PI
) / 180.0;
279 // Get these so that we can do some superfast assignments
280 double sinValue
= sin(currentRadian
);
281 double cosValue
= cos(currentRadian
);
283 // Do 4 assignments, taking advantage of sin/cos symmetry
284 sSinTable
[i
] = sinValue
;
285 sSinTable
[i
+ 90] = cosValue
;
286 sSinTable
[i
+ 180] = sinValue
* -1;
287 sSinTable
[i
+ 270] = cosValue
* -1;
289 sCosTable
[i
] = cosValue
;
290 sCosTable
[i
+ 90] = sinValue
* -1;
291 sCosTable
[i
+ 180] = cosValue
* -1;
292 sCosTable
[i
+ 270] = sinValue
;
294 double tanValue
= sinValue
/ cosValue
;
296 sTanTable
[i
] = tanValue
;
297 sTanTable
[i
+ 90] = tanValue
;
298 sTanTable
[i
+ 180] = tanValue
;
299 sTanTable
[i
+ 270] = tanValue
;
305 Angle::operator=(const Angle
&from
)
307 fAngleValue
= from
.fAngleValue
;
313 Angle::operator=(const float &from
)
321 Angle::operator=(const long &from
)
323 fAngleValue
= (float)from
;
329 Angle::operator=(const int &from
)
331 fAngleValue
= (float)from
;
337 Angle::operator==(const Angle
&from
)
339 return (fAngleValue
== from
.fAngleValue
);
344 Angle::operator!=(const Angle
&from
)
346 return (fAngleValue
!= from
.fAngleValue
);
351 Angle::operator>(const Angle
&from
)
353 return (fAngleValue
> from
.fAngleValue
);
358 Angle::operator<(const Angle
&from
)
360 return (fAngleValue
< from
.fAngleValue
);
365 Angle::operator>=(const Angle
&from
)
367 return (fAngleValue
>= from
.fAngleValue
);
372 Angle::operator<=(const Angle
&from
)
374 return (fAngleValue
<= from
.fAngleValue
);