2
* mathfuncs.h - General mathematic functions header
3
* Copyright (C) 2012, D Haley
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
26
#include "assertion.h"
27
#include "endianTest.h"
30
//!A 3D point data class storage
31
/*! A 3D point data class
32
* contains operator overloads and some basic
33
* mathematical functions
43
//!Constructor with initialising values
44
inline Point3D(float x,float y,float z)
45
{ value[0] = x, value[1] = y, value[2] = z;}
46
//!Set by value (ith dim 0, 1 2)
47
inline void setValue(unsigned int ui, float val){value[ui]=val;};
49
inline void setValue(float fX,float fY, float fZ)
50
{value[0]=fX; value[1]=fY; value[2]=fZ;}
53
inline void setValueArr(const float *val)
60
//!Get value of ith dim (0, 1, 2)
61
inline float getValue(unsigned int ui) const {return value[ui];};
62
//Retrieve the internal pointer. Only use if you know why.
63
inline const float *getValueArr() const { return value;};
65
//!get into an array (note array must hold sizeof(float)*3 bytes of valid mem
66
void copyValueArr(float *value) const;
68
//!Add a point to this, without generating a return value
69
void add(const Point3D &obj);
72
bool operator==(const Point3D &pt) const;
73
//!assignment operator
74
const Point3D &operator=(const Point3D &pt);
76
const Point3D &operator+=(const Point3D &pt);
78
const Point3D operator+(float f) const;
79
//!multiplication operator
80
const Point3D &operator*=(const float scale);
82
const Point3D operator+(const Point3D &pt) const;
83
//!elemental multiplication
84
const Point3D operator*(float scale) const;
86
const Point3D operator*(const Point3D &pt) const;
88
const Point3D operator/(float scale) const;
90
const Point3D operator-(const Point3D &pt) const;
91
//!returns a negative of the existing value
92
const Point3D operator-() const;
93
//!Output streaming operator. Users (x,y,z) as format for output
94
friend std::ostream &operator<<(std::ostream &stream, const Point3D &);
95
//!make point unit magnitude, maintaining direction
97
//!returns the square of distance another pt
98
float sqrDist(const Point3D &pt) const;
100
//!Calculate the dot product of this and another pint
101
float dotProd(const Point3D &pt) const;
102
//!Calculate the cross product of this and another point
103
Point3D crossProd(const Point3D &pt) const;
105
//!Calculate the angle between two position vectors in radiians
106
float angle(const Point3D &pt) const;
108
//!overload for array indexing returns |pt|^2
109
float sqrMag() const;
112
inline float operator[](unsigned int ui) const { ASSERT(ui < 3); return value[ui];}
113
//!Retrieve element by referene
114
inline float &operator[](unsigned int ui) { ASSERT(ui < 3); return value[ui];}
116
//!Is a given point stored inside a box bounded by orign and this pt?
117
/*!returns true if this point is located inside (0,0,0) -> Farpoint
118
* assuming box shape (non zero edges return false)
119
* farPoint must be positive in all dim
121
bool insideBox(const Point3D &farPoint) const;
124
//!Tests if this point lies inside the rectangular prism
125
/*!Returns true if this point lies inside the box bounded
126
* by lowPoint and highPoint
128
bool insideBox(const Point3D &lowPoint, const Point3D &highPoint) const;
130
//!Makes each value negative of old value
133
//Perform a 3x3 matrix transformation.
134
void transform3x3(const float *matrix);
136
//Perform a cross-product based orthogonalisation
137
//with the specified vector
138
bool orthogonalise(const Point3D &p);
139
#ifdef __LITTLE_ENDIAN__
140
//!Flip the endian state for data stored in this point
147
//Do NOT use multiple instances of this in your code
148
//with the same initialisation technique (e.g. initialising from system clock)
149
//this would be BAD, correlations might well be introduced into your results
150
//that are simply a result of using correlated random sequences!!! (think about it)
151
//use ONE random number generator in the project, initialise it and then "register"
152
//it with any objects that need a random generator.
164
void initialise(int seedVal);
168
float genUniformDev();
170
//This generates a number chosen from
171
//a gaussian distribution range is (-inf, inf)
199
//Uses quaternion mathematics to perform a rotation around your favourite axis
200
//IMPORTANT: rotVec must be normalised before passing to this function
201
//failure to do so will have weird results
202
//Note result is stored in point passed as argument
203
//angle is in radians.
204
void quat_rot(Point3f *point, Point3f *rotVec, float angle);
206
//Retrieve the quaternion for repeated rotations. Pass to the quat_rot_apply_quats.
207
//angle is in radians
208
void quat_get_rot_quat(Point3f *rotVec, float angle, Quaternion *rotQuat);
210
//Use previously generated quats from quat_get_rot_quats to rotate a point
211
void quat_rot_apply_quat(Point3f *point, Quaternion *rotQuat);
213
//This class implements a Linear Feedback Shift Register (in software)
214
//This is a mathematical construct based upon polynomials over closed natural numbers (N mod p).
215
//This will generate a weakly random digit string, but with guaranteed no duplicates, using O(1)
216
//memory and O(n) calls. The no duplicate guarantee is weak-ish, with no repetition in the
217
//shift register for 2^n-1 iterations. n can be set by setMaskPeriod.
218
class LinearFeedbackShiftReg
224
//Get a value from the shift register, and advance
226
//Set the internal lfsr state. Note 0 is the lock-up state.
227
void setState(size_t newState) { lfsr=newState;};
228
//set the mask to use such that the period is 2^n-1. 3 is minimum 60 is maximum
229
void setMaskPeriod(unsigned int newMask);
231
//!Check the validity of the table
236
//Determines the volume of a quadrilateral pyramid
237
//input points "planarpts" must be adjacent (connected) by
238
//0 <-> 1 <-> 2 <-> 0, all points connected to apex
239
double pyramidVol(const Point3D *planarPts, const Point3D &apex);
241
//!Inline func for calculating a(dot)b
242
inline float dotProduct(float a1, float a2, float a3,
243
float b1, float b2, float b3)
245
return a1*b1 + a2*b2 + a3* b3;
248
inline unsigned int ilog2(unsigned int value)
251
while( (value >> l) > 1 )