plastimatch
Loading...
Searching...
No Matches
plm_math.h
Go to the documentation of this file.
1/* -----------------------------------------------------------------------
2 See COPYRIGHT.TXT and LICENSE.TXT for copyright and license information
3 ----------------------------------------------------------------------- */
4#ifndef _plm_math_h_
5#define _plm_math_h_
6
7//#include "plmsys_config.h"
8#include <float.h>
9#include <math.h>
10#include <string.h>
11#include <limits>
12#include "compiler_warnings.h"
13
14#ifndef M_PI
15#define M_PI 3.14159265358979323846
16#endif
17#ifndef M_SQRT2
18#define M_SQRT2 1.41421356237309504880
19#endif
20#ifndef M_SQRTPI
21#define M_SQRTPI 1.77245385090551602792981
22#endif
23#ifndef M_TWOPI
24#define M_TWOPI (M_PI * 2.0)
25#endif
26#ifndef DBL_MAX
27#define DBL_MAX (1E+37)
28#endif
29#ifndef M_SQRT1_2
30#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
31#endif
32#ifndef M_SQRT3_OVER_2
33#define M_SQRT3_OVER_2 0.866025403784439 /* sqrt(3)/2 - nonstandard */
34#endif
35#ifndef M_SQRT2PI
36#define M_SQRT2PI 2.50662827463100 /* sqrt(2*pi) - nonstandard */
37#endif
38#ifndef M_PI_2
39#define M_PI_2 1.57079632679489661923 /* pi/2 */
40#endif
41#ifndef M_PI_3
42#define M_PI_3 1.04719755119660 /* pi/3 - nonstandard */
43#endif
44#ifndef M_PI_4
45#define M_PI_4 0.78539816339744830962 /* pi/4 */
46#endif
47
48/* Returns integer data type */
49#define ROUND_INT(x) (((x) >= 0) ? ((long)((x)+0.5)) : (long)(-(-(x)+0.5)))
50
51/* Returns plm_long data type */
52#define FLOOR_PLM_LONG(x) ((plm_long) floor (x))
53#define ROUND_PLM_LONG(x) \
54 (((x) >= 0) ? ((plm_long)((x)+0.5)) : (plm_long)(-(-(x)+0.5)))
55
56/* Returns unsigned integer data type */
57#define FLOOR_SIZE_T(x) (((x) >= 0) ? ((size_t)(x)) : 0)
58#define ROUND_SIZE_T(x) (((x) >= 0) ? ((size_t)((x)+0.5)) : 0)
59
60/* Returns double data type -- note MSVC does not have C99 round(). */
61#define ROUND(x) ((double) (ROUND_INT(x)))
62
63/* Returns +1 or -1, depeding on sign. Zero yeilds +1. */
64#define SIGN(x) (((x) >= 0) ? (+1) : (-1))
65
66// Fix for logf() under MSVC 2005 32-bit (math.h has an erronous semicolon)
67// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98751
68#if _MSC_VER == 1400
69#if !defined (_M_IA64) && !defined (_M_AMD64) && defined (_WIN32)
70#ifdef logf
71#undef logf
72#define logf(x) ((float)log((double)(x)))
73#endif
74#endif
75#endif
76
77/* How small is too small of a vector to normalize ? */
78#define FLOAT_SMALL_VECTOR_LENGTH 1e-6
79
80/* exp10() is not in C/C++ standard */
81static inline double exp10_ (double m) {
82 return exp (2.3025850929940456840179914546844 * m);
83}
84
85/* Primatives */
86static inline void vec2_add2 (double* v1, const double* v2) {
87 v1[0] += v2[0]; v1[1] += v2[1];
88}
89
90static inline void vec3_add2 (double* v1, const double* v2) {
91 v1[0] += v2[0]; v1[1] += v2[1]; v1[2] += v2[2];
92}
93
94static inline void vec3_add3 (double* v1, const double* v2, const double* v3) {
95 v1[0] = v2[0] + v3[0]; v1[1] = v2[1] + v3[1]; v1[2] = v2[2] + v3[2];
96}
97
98template<class T> static inline void
99vec3_add (T* v1, const T* v2) {
100 v1[0] += v2[0]; v1[1] += v2[1]; v1[2] += v2[2];
101}
102
103template<class T> static inline void
104vec3_add (T* v1, const T* v2, const T* v3) {
105 v1[0] = v2[0] + v3[0]; v1[1] = v2[1] + v3[1]; v1[2] = v2[2] + v2[2];
106}
107
108template<class T> static inline void
109vec3_copy (T* v1, const T* v2) {
110 v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2];
111}
112
113static inline void vec4_copy (double* v1, const double* v2) {
114 v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3];
115}
116
117template<class T> static inline T
118vec3_dot (const T* v1, const T* v2) {
119 return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
120}
121
122template<class T, class U> static inline float
123vec3_dot (const T* v1, const U* v2) {
124 return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
125}
126
127static inline double vec4_dot (const double* v1, const double* v2) {
128 return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + v1[3] * v2[3];
129}
130
131static inline void vec3_scale2 (double* v1, double a) {
132 v1[0] *= a; v1[1] *= a; v1[2] *= a;
133}
134
135template<class T, class U> static inline void
136vec3_scale3 (T* v1, const T* v2, U a) {
137 v1[0] = a * v2[0]; v1[1] = a * v2[1]; v1[2] = a * v2[2];
138}
139
140template<class T> static inline void
141vec3_sub2 (T* v1, const T* v2) {
142 v1[0] -= v2[0]; v1[1] -= v2[1]; v1[2] -= v2[2];
143}
144
145template<class T, class U, class V> static inline void
146vec3_sub3 (T* v1, const U* v2, const V* v3) {
147 v1[0] = v2[0] - v3[0]; v1[1] = v2[1] - v3[1]; v1[2] = v2[2] - v3[2];
148}
149
150static inline void vec3_invert (double* v1) {
151 vec3_scale2 (v1, -1.0);
152}
153
154static inline void vec_zero (double* v1, int n) {
155 memset (v1, 0, n*sizeof(double));
156}
157
158/* Length & distance */
159template<class T> static inline T
160vec3_lensq (const T* v1) {
161 return vec3_dot(v1,v1);
162}
163
164template<class T> static T vec3_len (const T*);
165
166template<> inline double
167vec3_len<> (const double* v1) {
168 return sqrt(vec3_dot(v1,v1));
169}
170
171template<> inline float
172vec3_len<float> (const float* v1) {
173 return sqrtf(vec3_dot(v1,v1));
174}
175
176static inline void vec3_normalize1 (double* v1) {
177 vec3_scale2 (v1, 1 / vec3_len(v1));
178}
179
180template<class T> static inline T
181vec3_distsq (const T* v1, const T* v2) {
182 T tmp[3];
183 vec3_sub3 (tmp, v1, v2);
184 return vec3_lensq(tmp);
185}
186
187template<class T> static inline T
188vec3_dist (const T* v1, const T* v2) {
189 T tmp[3];
190 vec3_sub3 (tmp, v1, v2);
191 return vec3_len(tmp);
192}
193
194/* Cross product */
195template<class T> static inline void
196vec3_cross (T* v1, const T* v2, const T* v3)
197{
198 v1[0] = v2[1] * v3[2] - v2[2] * v3[1];
199 v1[1] = v2[2] * v3[0] - v2[0] * v3[2];
200 v1[2] = v2[0] * v3[1] - v2[1] * v3[0];
201}
202
203/* Outer product */
204static inline void vec_outer (double* v1, const double* v2, const double* v3, const int n)
205{
206 int i,j;
207 for (j=0; j<n; j++) {
208 for (i=0; i<n; i++) {
209 v1[n*j + i] = v2[j] * v3[i];
210 }
211 }
212}
213
214/* Matrix ops */
215
216/* Matrix element m[i,j] for matrix with c columns */
217#define m_idx(m1,c,i,j) m1[i*c+j]
218
219/* v1 = m2 * v3 */
220static inline void mat43_mult_vec4 (double* v1, const double* m2, const double* v3) {
221 v1[0] = vec4_dot(&m2[0], v3);
222 v1[1] = vec4_dot(&m2[4], v3);
223 v1[2] = vec4_dot(&m2[8], v3);
224}
225
226/* m1 = m2 * m3 */
227static inline void mat_mult_mat (
228 double* m1,
229 const double* m2, int m2_rows, int m2_cols,
230 const double* m3, int m3_rows, int m3_cols)
231{
232 UNUSED_VARIABLE (m3_rows);
233 int i,j,k;
234 for (i = 0; i < m2_rows; i++) {
235 for (j = 0; j < m3_cols; j++) {
236 double acc = 0.0;
237 for (k = 0; k < m2_cols; k++) {
238 acc += m_idx(m2,m2_cols,i,k) * m_idx(m3,m3_cols,k,j);
239 }
240 m_idx(m1,m3_cols,i,j) = acc;
241 }
242 }
243}
244
245/* 0 when value is NaN or infinity */
246static inline int is_number (const double x)
247{
248 // nan
249 if (!(x == x)) return 0;
250
251 // inf
252 if (x > DBL_MAX || x < -DBL_MAX) return 0;
253#if defined (commentout)
254 if (std::numeric_limits<double>::has_infinity &&
255 x == std::numeric_limits<double>::infinity())
256 {
257 return 0;
258 }
259#endif
260
261 return 1;
262}
263
264template<class T> T
265clamp (T value, T min_value, T max_value) {
266 if (value < min_value) return min_value;
267 if (value > max_value) return max_value;
268 return value;
269}
270
271template<class T> T
272plm_max (T v1, T v2) {
273 return (v1 > v2) ? v1 : v2;
274}
275
276template<class T> T
277plm_min (T v1, T v2) {
278 return (v1 < v2) ? v1 : v2;
279}
280
281template<class T> T
283 return degrees * M_PI / 180.;
284}
285
286// Cf. http://realtimecollisiondetection.net/blog/?p=89
287// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
288static inline bool
289within_abs_tolerance (float value, float comp_value, float tolerance)
290{
291 return (fabsf (value - comp_value) <= tolerance);
292}
293
294#define NLMIN(T) (-std::numeric_limits<T>::max())
295#define NLMAX(T) std::numeric_limits<T>::max()
296
297#endif
#define UNUSED_VARIABLE(a)
Definition compiler_warnings.h:7
static void mat_mult_mat(double *m1, const double *m2, int m2_rows, int m2_cols, const double *m3, int m3_rows, int m3_cols)
Definition plm_math.h:227
static void vec_zero(double *v1, int n)
Definition plm_math.h:154
static void vec3_sub3(T *v1, const U *v2, const V *v3)
Definition plm_math.h:146
static T vec3_lensq(const T *v1)
Definition plm_math.h:160
static int is_number(const double x)
Definition plm_math.h:246
static void vec3_copy(T *v1, const T *v2)
Definition plm_math.h:109
static T vec3_len(const T *)
static void vec3_add3(double *v1, const double *v2, const double *v3)
Definition plm_math.h:94
static void vec3_invert(double *v1)
Definition plm_math.h:150
float vec3_len< float >(const float *v1)
Definition plm_math.h:172
static void mat43_mult_vec4(double *v1, const double *m2, const double *v3)
Definition plm_math.h:220
static void vec3_scale3(T *v1, const T *v2, U a)
Definition plm_math.h:136
T plm_max(T v1, T v2)
Definition plm_math.h:272
T clamp(T value, T min_value, T max_value)
Definition plm_math.h:265
static T vec3_dot(const T *v1, const T *v2)
Definition plm_math.h:118
static void vec3_add(T *v1, const T *v2)
Definition plm_math.h:99
static void vec4_copy(double *v1, const double *v2)
Definition plm_math.h:113
static bool within_abs_tolerance(float value, float comp_value, float tolerance)
Definition plm_math.h:289
static void vec3_add2(double *v1, const double *v2)
Definition plm_math.h:90
static double vec4_dot(const double *v1, const double *v2)
Definition plm_math.h:127
static void vec3_scale2(double *v1, double a)
Definition plm_math.h:131
static T vec3_distsq(const T *v1, const T *v2)
Definition plm_math.h:181
static void vec3_sub2(T *v1, const T *v2)
Definition plm_math.h:141
T plm_min(T v1, T v2)
Definition plm_math.h:277
static double exp10_(double m)
Definition plm_math.h:81
static void vec3_normalize1(double *v1)
Definition plm_math.h:176
static T vec3_dist(const T *v1, const T *v2)
Definition plm_math.h:188
#define m_idx(m1, c, i, j)
Definition plm_math.h:217
#define M_PI
Definition plm_math.h:15
static void vec3_cross(T *v1, const T *v2, const T *v3)
Definition plm_math.h:196
T radians_from_degrees(T degrees)
Definition plm_math.h:282
static void vec_outer(double *v1, const double *v2, const double *v3, const int n)
Definition plm_math.h:204
static void vec2_add2(double *v1, const double *v2)
Definition plm_math.h:86
#define DBL_MAX
Definition plm_math.h:27