angle.h

00001
00002 /***************************************************************************
00003  *  angle.h - angle related math helper functions
00004  *
00005  *  Created: Wed Jul 13 16:51:46 2005 (from FireVision)
00006  *  Copyright  2005-2008  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023
00024 #ifndef __UTILS_MATH_ANGLE_H_
00025 #define __UTILS_MATH_ANGLE_H_
00026 
00027 #include <cmath>
00028
00029 namespace fawkes {
00030
00031 
00032 /** Convert an angle given in degrees to radians.
00033  * @param deg original value in degrees
00034  * @return converted value in radians
00035  */
00036 inline float
00037 deg2rad(float deg)
00038 {
00039   return (deg * M_PI / 180.f);
00040 }
00041
00042 
00043 /** Convert an angle given in radians to degrees.
00044  * @param rad original value in radians
00045  * @return converted value in degrees
00046  */
00047 inline float
00048 rad2deg(float rad)
00049 {
00050   return (rad * 180.f / M_PI);
00051 }
00052
00053 
00054 /** Get distance between two 2D cartesian coordinates.
00055  * @param x1 X coordinate of first point
00056  * @param y1 Y coordinate of first point
00057  * @param x2 X coordinate of second point
00058  * @param y2 Y coordinate of second point
00059  */
00060 inline float
00061 distance(float x1, float y1, float x2, float y2)
00062 {
00063   return sqrt( (x2-x1) * (x2-x1) + (y2-y1) * (y2-y1) );
00064 }
00065 
00066 /** Normalize angle in radian between -PI and PI.
00067  * The given angle in radians is taken as an angle on the unit circle.
00068  * It is then normalized into the range -PI and PI, such that it is the
00069  * exact same angle on the unit circle but in the usual angle range.
00070  * @param angle_rad original value
00071  * @return normalized angle
00072  */
00073 inline float
00074 normalize_mirror_rad(float angle_rad)
00075 {
00076   if ( (angle_rad < -M_PI) || (angle_rad > M_PI) ) {
00077     return ( angle_rad - 2 * M_PI * round(angle_rad / (2 * M_PI)) );
00078   } else {
00079     return angle_rad;
00080   }
00081 }
00082 
00083 /** Normalize angle in radian between 0 and 2*PI.
00084  * The given angle in radians is taken as an angle on the unit circle.
00085  * It is then normalized into the range 0 and 2*PI, such that it is the
00086  * exact same angle on the unit circle but in the usual angle range.
00087  * @param angle_rad original value
00088  * @return normalized angle
00089  */
00090 inline float
00091 normalize_rad(float angle_rad)
00092 {
00093   if ( (angle_rad < 0) || (angle_rad > 2 * M_PI) ) {
00094     return angle_rad - 2 * M_PI * floor(angle_rad / (M_PI * 2));
00095   } else {
00096     return angle_rad;
00097   }
00098 }
00099
00100 
00101 /** Normalizes angle in radian between -3*PI and 3*PI.
00102  * If the angle is above 2*PI or below 2*PI the angle will be clipped.
00103  * The largest full amount of (-)2*PI is subtracted, such that only the amount
00104  * within the range [-2*PI, 2*PI] remains. Then (-)2*PI is added again.
00105  * @param angle_rad original value
00106  * @return normalized angle
00107  */
00108 inline float
00109 normalize_bigmirror_rad(float angle_rad)
00110 {
00111   if ( (angle_rad < -2*M_PI) || (angle_rad > 2*M_PI) ) {
00112     return (normalize_mirror_rad(angle_rad) + copysign(2*M_PI, angle_rad) );
00113   } else {
00114     return angle_rad;
00115   }
00116 }
00117
00118 
00119 /** Determines the distance between two angle provided as radians. 
00120  * Quadrants of the angles are considered to determine really the minimal
00121  * angle difference.
00122  * @param angle_rad1 first angle in radian
00123  * @param angle_rad2 first angle in radian
00124  * @return distance between the two angles
00125  */
00126 inline float
00127 angle_distance(float angle_rad1,
00128                float angle_rad2)
00129 {
00130   if(angle_rad2 > angle_rad1)
00131     {
00132       return angle_rad2 - angle_rad1 < M_PI ? angle_rad2 - angle_rad1 : - 2.0 * M_PI + angle_rad2 - angle_rad1;
00133     }
00134   else
00135     {
00136       return angle_rad1 - angle_rad2 < M_PI ? angle_rad2 - angle_rad1 : 2.0 * M_PI - angle_rad1 + angle_rad2;
00137     }
00138 }
00139
00140
00141 } // end namespace fawkes
00142
00143 #endif