-
Notifications
You must be signed in to change notification settings - Fork 199
/
Copy pathMathUtil.h
executable file
·72 lines (58 loc) · 1.8 KB
/
MathUtil.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//-*-c++-*-
#ifndef MATHUTIL_H
#define MATHUTIL_H
#include <cfloat>
#include <cmath>
#include <cstdlib>
#include <ostream>
#include <utility>
namespace AprilTags {
std::ostream &operator<<(std::ostream &os, const std::pair<float, float> &pt);
//! Miscellaneous math utilities and fast exp functions.
class MathUtil {
public:
//! Returns the square of a value.
static inline float square(float x) { return x * x; }
static inline float distance2D(const std::pair<float, float> &p0,
const std::pair<float, float> &p1) {
float dx = p0.first - p1.first;
float dy = p0.second - p1.second;
return std::sqrt(dx * dx + dy * dy);
}
//! Returns a result in [-Pi, Pi]
static inline float mod2pi(float vin) {
const float twopi = 2 * (float)M_PI;
const float twopi_inv = 1.f / (2.f * (float)M_PI);
float absv = std::abs(vin);
float q = absv * twopi_inv + 0.5f;
int qi = (int)q;
float r = absv - qi * twopi;
return (vin < 0) ? -r : r;
}
//! Returns a value of v wrapped such that ref and v differ by no more than
//! +/- Pi
static inline float mod2pi(float ref, float v) {
return ref + mod2pi(v - ref);
}
// lousy approximation of arctan function, but good enough for our purposes
// (about 4 degrees)
static inline double fast_atan2(double y, double x) {
double coeff_1 = M_PI / 4;
double coeff_2 = 3 * coeff_1;
double abs_y = fabs(y) + 1e-10; // kludge to prevent 0/0 condition
double angle;
if (x >= 0) {
double r = (x - abs_y) / (x + abs_y);
angle = coeff_1 - coeff_1 * r;
} else {
double r = (x + abs_y) / (abs_y - x);
angle = coeff_2 - coeff_1 * r;
}
if (y < 0)
return -angle; // negate if in quad III or IV
else
return angle;
}
};
} // namespace
#endif