make util::normalize_angle reasonably fast on large values
Because it simply calculates the remainder after division by full turn, it shouldn't take time proportional to the magnitude of its operand.
This commit is contained in:
parent
354be41811
commit
7c4ccf0209
2 changed files with 20 additions and 6 deletions
|
@ -27,9 +27,11 @@
|
|||
|
||||
namespace mapnik { namespace util {
|
||||
|
||||
constexpr double pi = 3.1415926535897932384626433832795;
|
||||
constexpr double tau = 6.283185307179586476925286766559;
|
||||
|
||||
MAPNIK_DECL double normalize_angle(double angle);
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
22
src/math.cpp
22
src/math.cpp
|
@ -22,7 +22,6 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/util/math.hpp>
|
||||
#include <mapnik/global.hpp>
|
||||
|
||||
// stl
|
||||
#include <cmath>
|
||||
|
@ -33,13 +32,26 @@ namespace util {
|
|||
|
||||
double normalize_angle(double angle)
|
||||
{
|
||||
while (angle >= M_PI)
|
||||
if (angle > pi)
|
||||
{
|
||||
angle -= 2.0 * M_PI;
|
||||
if (angle > 16 * tau)
|
||||
{
|
||||
// the angle is too large; better compute the remainder
|
||||
// directly to avoid subtracting circles ad infinitum
|
||||
return std::remainder(angle, tau);
|
||||
}
|
||||
// std::remainder would take longer than a few subtractions
|
||||
while ((angle -= tau) > pi)
|
||||
;
|
||||
}
|
||||
while (angle < -M_PI)
|
||||
else if (angle < -pi)
|
||||
{
|
||||
angle += 2.0 * M_PI;
|
||||
if (angle < -16 * tau)
|
||||
{
|
||||
return std::remainder(angle, tau);
|
||||
}
|
||||
while ((angle += tau) < -pi)
|
||||
;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue