Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef GEOMETRY_ANGLES_UTILS_H
00036 #define GEOMETRY_ANGLES_UTILS_H
00037
00038 #include <algorithm>
00039 #include <cmath>
00040
00041 namespace angles
00042 {
00043
00048 static inline double from_degrees(double degrees)
00049 {
00050 return degrees * M_PI / 180.0;
00051 }
00052
00056 static inline double to_degrees(double radians)
00057 {
00058 return radians * 180.0 / M_PI;
00059 }
00060
00061
00068 static inline double normalize_angle_positive(double angle)
00069 {
00070 return fmod(fmod(angle, 2.0*M_PI) + 2.0*M_PI, 2.0*M_PI);
00071 }
00072
00073
00081 static inline double normalize_angle(double angle)
00082 {
00083 double a = normalize_angle_positive(angle);
00084 if (a > M_PI)
00085 a -= 2.0 *M_PI;
00086 return a;
00087 }
00088
00089
00102 static inline double shortest_angular_distance(double from, double to)
00103 {
00104 double result = normalize_angle_positive(normalize_angle_positive(to) - normalize_angle_positive(from));
00105
00106 if (result > M_PI)
00107
00108
00109 result = -(2.0*M_PI - result);
00110
00111 return normalize_angle(result);
00112 }
00113
00123 static inline double two_pi_complement(double angle)
00124 {
00125
00126 if (angle > 2*M_PI || angle < -2.0*M_PI)
00127 angle = fmod(angle, 2.0*M_PI);
00128 if(angle < 0)
00129 return (2*M_PI+angle);
00130 else if (angle > 0)
00131 return (-2*M_PI+angle);
00132
00133 return(2*M_PI);
00134 }
00135
00147 static bool find_min_max_delta(double from, double left_limit, double right_limit, double &result_min_delta, double &result_max_delta)
00148 {
00149 double delta[4];
00150
00151 delta[0] = shortest_angular_distance(from,left_limit);
00152 delta[1] = shortest_angular_distance(from,right_limit);
00153
00154 delta[2] = two_pi_complement(delta[0]);
00155 delta[3] = two_pi_complement(delta[1]);
00156
00157 if(delta[0] == 0)
00158 {
00159 result_min_delta = delta[0];
00160 result_max_delta = std::max<double>(delta[1],delta[3]);
00161 return true;
00162 }
00163
00164 if(delta[1] == 0)
00165 {
00166 result_max_delta = delta[1];
00167 result_min_delta = std::min<double>(delta[0],delta[2]);
00168 return true;
00169 }
00170
00171
00172 double delta_min = delta[0];
00173 double delta_min_2pi = delta[2];
00174 if(delta[2] < delta_min)
00175 {
00176 delta_min = delta[2];
00177 delta_min_2pi = delta[0];
00178 }
00179
00180 double delta_max = delta[1];
00181 double delta_max_2pi = delta[3];
00182 if(delta[3] > delta_max)
00183 {
00184 delta_max = delta[3];
00185 delta_max_2pi = delta[1];
00186 }
00187
00188
00189
00190 if((delta_min <= delta_max_2pi) || (delta_max >= delta_min_2pi))
00191 {
00192 result_min_delta = delta_max_2pi;
00193 result_max_delta = delta_min_2pi;
00194 if(left_limit == -M_PI && right_limit == M_PI)
00195 return true;
00196 else
00197 return false;
00198 }
00199 result_min_delta = delta_min;
00200 result_max_delta = delta_max;
00201 return true;
00202 }
00203
00204
00222 static inline bool shortest_angular_distance_with_limits(double from, double to, double left_limit, double right_limit, double &shortest_angle)
00223 {
00224
00225 double min_delta = -2*M_PI;
00226 double max_delta = 2*M_PI;
00227 double min_delta_to = -2*M_PI;
00228 double max_delta_to = 2*M_PI;
00229 bool flag = find_min_max_delta(from,left_limit,right_limit,min_delta,max_delta);
00230 double delta = shortest_angular_distance(from,to);
00231 double delta_mod_2pi = two_pi_complement(delta);
00232
00233
00234 if(flag)
00235 {
00236 if(delta >= min_delta && delta <= max_delta)
00237 {
00238 shortest_angle = delta;
00239 return true;
00240 }
00241 else if(delta_mod_2pi >= min_delta && delta_mod_2pi <= max_delta)
00242 {
00243 shortest_angle = delta_mod_2pi;
00244 return true;
00245 }
00246 else
00247 {
00248 find_min_max_delta(to,left_limit,right_limit,min_delta_to,max_delta_to);
00249 if(fabs(min_delta_to) < fabs(max_delta_to))
00250 shortest_angle = std::max<double>(delta,delta_mod_2pi);
00251 else if(fabs(min_delta_to) > fabs(max_delta_to))
00252 shortest_angle = std::min<double>(delta,delta_mod_2pi);
00253 else
00254 {
00255 if (fabs(delta) < fabs(delta_mod_2pi))
00256 shortest_angle = delta;
00257 else
00258 shortest_angle = delta_mod_2pi;
00259 }
00260 return false;
00261 }
00262 }
00263 else
00264 {
00265 find_min_max_delta(to,left_limit,right_limit,min_delta_to,max_delta_to);
00266
00267 if(fabs(min_delta) < fabs(max_delta))
00268 shortest_angle = std::min<double>(delta,delta_mod_2pi);
00269 else if (fabs(min_delta) > fabs(max_delta))
00270 shortest_angle = std::max<double>(delta,delta_mod_2pi);
00271 else
00272 {
00273 if (fabs(delta) < fabs(delta_mod_2pi))
00274 shortest_angle = delta;
00275 else
00276 shortest_angle = delta_mod_2pi;
00277 }
00278 return false;
00279 }
00280
00281 shortest_angle = delta;
00282 return false;
00283 }
00284
00285
00286
00287
00288
00289 }
00290
00291 #endif