00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef pvec_h
00014 #define pvec_h
00015
00016 #include <iostream>
00017 #include <cmath>
00018
00019 #ifndef M_PI
00020 #define M_PI 3.1415926535897932384626433f
00021 #endif
00022
00023 #ifdef WIN32
00024
00025 #define inline __forceinline
00026 #endif
00027
00028 namespace PAPI
00029 {
00030 typedef unsigned long long puint64;
00031
00032 const float P_SQRT2PI = 2.506628274631000502415765284811045253006f;
00033 const float P_ONEOVERSQRT2PI = (1.f / P_SQRT2PI);
00034
00035 inline float fsqr(float f) { return f * f; }
00036
00037 #ifdef unix
00038 inline float pRandf() { return drand48(); }
00039 inline void pSRandf(int x) { srand48(x); }
00040 #else
00041 const float P_ONEOVER_RAND_MAX = (1.0f/((float) RAND_MAX));
00042 inline float pRandf() { return ((float) rand())*P_ONEOVER_RAND_MAX; }
00043 inline void pSRandf(int x) { srand(x); }
00044 #endif
00045
00046 inline bool pSameSign(const float &a, const float &b) { return a * b >= 0.0f; }
00047
00049 inline float pNRandf(float sigma = 1.0f)
00050 {
00051 float x, y, r2;
00052 do {
00053 x = pRandf()*2.0f-1.0f;
00054 y = pRandf()*2.0f-1.0f;
00055 r2 = x*x+y*y;
00056 }
00057 while(r2 > 1.0f || r2 == 0.0f);
00058
00059 float m = sqrtf(-2.0f * logf(r2)/r2);
00060
00061 float px = x*m*sigma;
00062
00063
00064 return px;
00065 }
00066
00072 class pVec
00073 {
00074 float vx, vy, vz;
00075
00076 public:
00077 inline pVec(float ax, float ay, float az) : vx(ax), vy(ay), vz(az) {}
00078 inline pVec(float a) : vx(a), vy(a), vz(a) {}
00079 inline pVec() {}
00080
00081 const float& x() const { return vx; }
00082 const float& y() const { return vy; }
00083 const float& z() const { return vz; }
00084
00085 float& x() { return vx; }
00086 float& y() { return vy; }
00087 float& z() { return vz; }
00088
00089 inline float length() const
00090 {
00091 return sqrtf(vx*vx+vy*vy+vz*vz);
00092 }
00093
00094 inline float length2() const
00095 {
00096 return (vx*vx+vy*vy+vz*vz);
00097 }
00098
00099 inline float normalize()
00100 {
00101 float onel = 1.0f / sqrtf(vx*vx+vy*vy+vz*vz);
00102 vx *= onel;
00103 vy *= onel;
00104 vz *= onel;
00105
00106 return onel;
00107 }
00108
00109
00110 friend inline float dot(const pVec &a, const pVec &b)
00111 {
00112 return b.x()*a.x() + b.y()*a.y() + b.z()*a.z();
00113 }
00114
00115
00116 inline pVec operator*(const float s) const
00117 {
00118 return pVec(vx*s, vy*s, vz*s);
00119 }
00120
00121 inline pVec operator/(const float s) const
00122 {
00123 float invs = 1.0f / s;
00124 return pVec(vx*invs, vy*invs, vz*invs);
00125 }
00126
00127 inline pVec operator+(const pVec& a) const
00128 {
00129 return pVec(vx+a.x(), vy+a.y(), vz+a.z());
00130 }
00131
00132 inline pVec operator-(const pVec& a) const
00133 {
00134 return pVec(vx-a.x(), vy-a.y(), vz-a.z());
00135 }
00136
00137 inline bool operator==(const pVec &a) const
00138 {
00139 return vx==a.x() && vy==a.y() && vz==a.z();
00140 }
00141
00142 inline pVec operator-()
00143 {
00144 vx = -vx;
00145 vy = -vy;
00146 vz = -vz;
00147 return *this;
00148 }
00149
00150 inline pVec& operator+=(const pVec& a)
00151 {
00152 vx += a.x();
00153 vy += a.y();
00154 vz += a.z();
00155 return *this;
00156 }
00157
00158 inline pVec& operator-=(const pVec& a)
00159 {
00160 vx -= a.x();
00161 vy -= a.y();
00162 vz -= a.z();
00163 return *this;
00164 }
00165
00166 inline pVec& operator*=(const float a)
00167 {
00168 vx *= a;
00169 vy *= a;
00170 vz *= a;
00171 return *this;
00172 }
00173
00174 inline pVec& operator/=(const float a)
00175 {
00176 float b = 1.0f / a;
00177 vx *= b;
00178 vy *= b;
00179 vz *= b;
00180 return *this;
00181 }
00182
00183 inline pVec& operator=(const pVec& a)
00184 {
00185 vx = a.x();
00186 vy = a.y();
00187 vz = a.z();
00188 return *this;
00189 }
00190
00191
00192 friend inline pVec Abs(const pVec &a)
00193 {
00194 return pVec(fabs(a.x()), fabs(a.y()), fabs(a.z()));
00195 }
00196
00197
00198 friend inline pVec CompMult(const pVec &a, const pVec& b)
00199 {
00200 return pVec(b.x()*a.x(), b.y()*a.y(), b.z()*a.z());
00201 }
00202
00203 friend inline pVec Cross(const pVec& a, const pVec& b)
00204 {
00205 return pVec(
00206 a.y()*b.z()-a.z()*b.y(),
00207 a.z()*b.x()-a.x()*b.z(),
00208 a.x()*b.y()-a.y()*b.x());
00209 }
00210
00211 friend inline std::ostream& operator<<(std::ostream& os, const pVec& v)
00212 {
00213 os << &v << '[' << v.x() << ", " << v.y() << ", " << v.z() << ']';
00214
00215 return os;
00216 }
00217 };
00218
00219
00220 static pVec vHalf(0.5, 0.5, 0.5);
00221
00222 inline pVec pRandVec()
00223 {
00224 return pVec(pRandf(), pRandf(), pRandf());
00225 }
00226
00227 inline pVec pNRandVec(float sigma)
00228 {
00229 float x, y, r2;
00230 do {
00231 x = pRandf()*2.0f-1.0f;
00232 y = pRandf()*2.0f-1.0f;
00233 r2 = x*x+y*y;
00234 }
00235 while(r2 > 1.0f || r2 == 0.0f);
00236
00237 float m = sqrtf(-2.0f * logf(r2)/r2);
00238
00239 float px = x*m*sigma;
00240 float py = y*m*sigma;
00241 return pVec(px, py, pNRandf(sigma));
00242 }
00243
00244 };
00245
00246 #endif