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