00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdafx.h"
00023 #include <math.h>
00024 #include "CoordGeom.h"
00025
00026 #define EPSILON (1e-7)
00027 #define BIGNUMBER (1e+9)
00028 #define IsZero(d) (fabs(d) < EPSILON)
00029
00030
00031
00032
00033
00034 Vector::Vector(double x, double y, double z)
00035 {
00036 this->x = x;
00037 this->y = y;
00038 this->z = z;
00039 }
00040
00041 void Vector::Set(double x, double y, double z)
00042 {
00043 this->x = x;
00044 this->y = y;
00045 this->z = z;
00046 }
00047
00048 double Vector::Length()
00049 {
00050 return(sqrt(x * x + y * y + z * z));
00051 }
00052
00053 double Vector::Sum()
00054 {
00055 return(x + y + z);
00056 }
00057
00058 double Vector::CrossSum()
00059 {
00060 return(x*y + x*z + y*z);
00061 }
00062
00063 Vector Vector::Cross()
00064 {
00065 return(Vector(x*y, x*z, y*z));
00066 }
00067
00068 Vector Vector::Pow(double exp)
00069 {
00070 return(exp == 0 ? Vector(1, 1, 1) : exp == 1 ? *this : Vector(pow(x, exp), pow(y, exp), pow(z, exp)));
00071 }
00072
00073 Vector Vector::Unit()
00074 {
00075 double l = Length();
00076 if(!l || l == 1) return(*this);
00077 return(*this * (1 / l));
00078 }
00079
00080 Vector& Vector::Unitalize()
00081 {
00082 return(*this = Unit());
00083 }
00084
00085 Vector Vector::Normal(Vector& a, Vector& b)
00086 {
00087 return((a - *this) % (b - a));
00088 }
00089
00090 double Vector::Angle(Vector& a, Vector& b)
00091 {
00092 return(((a - *this).Unit()).Angle((b - *this).Unit()));
00093 }
00094
00095 double Vector::Angle(Vector& a)
00096 {
00097 double angle = *this | a;
00098 return((angle > 1) ? 0 : (angle < -1) ? PI : acos(angle));
00099 }
00100
00101 void Vector::Angle(double& u, double& v)
00102 {
00103 Vector n = Unit();
00104
00105 u = asin(n.y);
00106
00107 if(IsZero(n.z)) v = PI/2 * Sgn(n.x);
00108 else if(n.z > 0) v = atan(n.x / n.z);
00109 else if(n.z < 0) v = IsZero(n.x) ? PI : (PI * Sgn(n.x) + atan(n.x / n.z));
00110 }
00111
00112 Vector Vector::Angle()
00113 {
00114 Vector ret;
00115 Angle(ret.x, ret.y);
00116 ret.z = 0;
00117 return(ret);
00118 }
00119
00120 Vector& Vector::Min(Vector& a)
00121 {
00122 x = (x < a.x) ? x : a.x;
00123 y = (y < a.y) ? y : a.y;
00124 z = (z < a.z) ? z : a.z;
00125 return(*this);
00126 }
00127
00128 Vector& Vector::Max(Vector& a)
00129 {
00130 x = (x > a.x) ? x : a.x;
00131 y = (y > a.y) ? y : a.y;
00132 z = (z > a.z) ? z : a.z;
00133 return(*this);
00134 }
00135
00136 Vector Vector::Abs()
00137 {
00138 return(Vector(fabs(x), fabs(y), fabs(z)));
00139 }
00140
00141 Vector Vector::Reflect(Vector& n)
00142 {
00143 return(n * ((-*this) | n) * 2 - (-*this));
00144 }
00145
00146 Vector Vector::Refract(Vector& N, double nFront, double nBack, double* nOut)
00147 {
00148 Vector D = -*this;
00149
00150 double N_dot_D = (N | D);
00151 double n = N_dot_D >= 0 ? (nFront / nBack) : (nBack / nFront);
00152
00153 Vector cos_D = N * N_dot_D;
00154 Vector sin_T = (cos_D - D) * n;
00155
00156 double len_sin_T = sin_T | sin_T;
00157
00158 if(len_sin_T > 1)
00159 {
00160 if(nOut) {*nOut = N_dot_D >= 0 ? nFront : nBack;}
00161 return((*this).Reflect(N));
00162 }
00163
00164 double N_dot_T = sqrt(1.0 - len_sin_T);
00165 if(N_dot_D < 0) N_dot_T = -N_dot_T;
00166
00167 if(nOut) {*nOut = N_dot_D >= 0 ? nBack : nFront;}
00168
00169 return(sin_T - (N * N_dot_T));
00170 }
00171
00172 Vector Vector::Refract2(Vector& N, double nFrom, double nTo, double* nOut)
00173 {
00174 Vector D = -*this;
00175
00176 double N_dot_D = (N | D);
00177 double n = nFrom / nTo;
00178
00179 Vector cos_D = N * N_dot_D;
00180 Vector sin_T = (cos_D - D) * n;
00181
00182 double len_sin_T = sin_T | sin_T;
00183
00184 if(len_sin_T > 1)
00185 {
00186 if(nOut) {*nOut = nFrom;}
00187 return((*this).Reflect(N));
00188 }
00189
00190 double N_dot_T = sqrt(1.0 - len_sin_T);
00191 if(N_dot_D < 0) N_dot_T = -N_dot_T;
00192
00193 if(nOut) {*nOut = nTo;}
00194
00195 return(sin_T - (N * N_dot_T));
00196 }
00197
00198 double Vector::operator | (Vector& v)
00199 {
00200 return(x * v.x + y * v.y + z * v.z);
00201 }
00202
00203 Vector Vector::operator % (Vector& v)
00204 {
00205 return(Vector(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x));
00206 }
00207
00208 double& Vector::operator [] (int i)
00209 {
00210 return(!i ? x : (i == 1) ? y : z);
00211 }
00212
00213 Vector Vector::operator - ()
00214 {
00215 return(Vector(-x, -y, -z));
00216 }
00217
00218 bool Vector::operator == (const Vector& v) const
00219 {
00220 if(IsZero(x - v.x) && IsZero(y - v.y) && IsZero(z - v.z)) return(true);
00221 return(false);
00222 }
00223
00224 bool Vector::operator != (const Vector& v) const
00225 {
00226 return((*this == v) ? false : true);
00227 }
00228
00229 Vector Vector::operator + (double d)
00230 {
00231 return(Vector(x + d, y + d, z + d));
00232 }
00233
00234 Vector Vector::operator + (Vector& v)
00235 {
00236 return(Vector(x + v.x, y + v.y, z + v.z));
00237 }
00238
00239 Vector Vector::operator - (double d)
00240 {
00241 return(Vector(x - d, y - d, z - d));
00242 }
00243
00244 Vector Vector::operator - (Vector& v)
00245 {
00246 return(Vector(x - v.x, y - v.y, z - v.z));
00247 }
00248
00249 Vector Vector::operator * (double d)
00250 {
00251 return(Vector(x * d, y * d, z * d));
00252 }
00253
00254 Vector Vector::operator * (Vector& v)
00255 {
00256 return(Vector(x * v.x, y * v.y, z * v.z));
00257 }
00258
00259 Vector Vector::operator / (double d)
00260 {
00261 return(Vector(x / d, y / d, z / d));
00262 }
00263
00264 Vector Vector::operator / (Vector& v)
00265 {
00266 return(Vector(x / v.x, y / v.y, z / v.z));
00267 }
00268
00269 Vector& Vector::operator += (double d)
00270 {
00271 x += d; y += d; z += d;
00272 return(*this);
00273 }
00274
00275 Vector& Vector::operator += (Vector& v)
00276 {
00277 x += v.x; y += v.y; z += v.z;
00278 return(*this);
00279 }
00280
00281 Vector& Vector::operator -= (double d)
00282 {
00283 x -= d; y -= d; z -= d;
00284 return(*this);
00285 }
00286
00287 Vector& Vector::operator -= (Vector& v)
00288 {
00289 x -= v.x; y -= v.y; z -= v.z;
00290 return(*this);
00291 }
00292
00293 Vector& Vector::operator *= (double d)
00294 {
00295 x *= d; y *= d; z *= d;
00296 return(*this);
00297 }
00298
00299 Vector& Vector::operator *= (Vector& v)
00300 {
00301 x *= v.x; y *= v.y; z *= v.z;
00302 return(*this);
00303 }
00304
00305 Vector& Vector::operator /= (double d)
00306 {
00307 x /= d; y /= d; z /= d;
00308 return(*this);
00309 }
00310
00311 Vector& Vector::operator /= (Vector& v)
00312 {
00313 x /= v.x; y /= v.y; z /= v.z;
00314 return(*this);
00315 }
00316
00317
00318
00319
00320
00321 Ray::Ray(Vector& p, Vector& d)
00322 {
00323 this->p = p;
00324 this->d = d;
00325 }
00326
00327 void Ray::Set(Vector& p, Vector& d)
00328 {
00329 this->p = p;
00330 this->d = d;
00331 }
00332
00333 double Ray::GetDistanceFrom(Ray& r)
00334 {
00335 double t = (d | r.d);
00336 if(IsZero(t)) return(-BIGNUMBER);
00337 return(((r.p - p) | r.d) / t);
00338 }
00339
00340 double Ray::GetDistanceFrom(Vector& v)
00341 {
00342 double t = ((v - p) | d) / (d | d);
00343 return(((p + d*t) - v).Length());
00344 }
00345
00346 Vector Ray::operator [] (double t)
00347 {
00348 return(p + d*t);
00349 }
00350
00351
00352
00353
00354
00355 XForm::XForm(Ray& r, Vector& s, bool isWorldToLocal)
00356 {
00357 Initalize(r, s, isWorldToLocal);
00358 }
00359
00360 void XForm::Initalize()
00361 {
00362 m.Initalize();
00363 }
00364
00365 void XForm::Initalize(Ray& r, Vector& s, bool isWorldToLocal)
00366 {
00367 Initalize();
00368
00369 if(m_isWorldToLocal = isWorldToLocal)
00370 {
00371 *this -= r.p;
00372 *this >>= r.d;
00373 *this /= s;
00374
00375 }
00376 else
00377 {
00378 *this *= s;
00379 *this <<= r.d;
00380 *this += r.p;
00381 }
00382 }
00383
00384 void XForm::operator *= (Vector& v)
00385 {
00386 Matrix s;
00387 s.mat[0][0] = v.x;
00388 s.mat[1][1] = v.y;
00389 s.mat[2][2] = v.z;
00390 m *= s;
00391 }
00392
00393 void XForm::operator += (Vector& v)
00394 {
00395 Matrix t;
00396 t.mat[3][0] = v.x;
00397 t.mat[3][1] = v.y;
00398 t.mat[3][2] = v.z;
00399 m *= t;
00400 }
00401
00402 void XForm::operator <<= (Vector& v)
00403 {
00404 Matrix x;
00405 x.mat[1][1] = cos(v.x); x.mat[1][2] = -sin(v.x);
00406 x.mat[2][1] = sin(v.x); x.mat[2][2] = cos(v.x);
00407
00408 Matrix y;
00409 y.mat[0][0] = cos(v.y); y.mat[0][2] = -sin(v.y);
00410 y.mat[2][0] = sin(v.y); y.mat[2][2] = cos(v.y);
00411
00412 Matrix z;
00413 z.mat[0][0] = cos(v.z); z.mat[0][1] = -sin(v.z);
00414 z.mat[1][0] = sin(v.z); z.mat[1][1] = cos(v.z);
00415
00416 m = m_isWorldToLocal ? (m * y * x * z) : (m * z * x * y);
00417 }
00418
00419 void XForm::operator /= (Vector& v)
00420 {
00421 Vector s;
00422 s.x = IsZero(v.x) ? 0 : 1 / v.x;
00423 s.y = IsZero(v.y) ? 0 : 1 / v.y;
00424 s.z = IsZero(v.z) ? 0 : 1 / v.z;
00425 *this *= s;
00426 }
00427
00428 void XForm::operator -= (Vector& v)
00429 {
00430 *this += -v;
00431 }
00432
00433 void XForm::operator >>= (Vector& v)
00434 {
00435 *this <<= -v;
00436 }
00437
00438 Vector XForm::operator < (Vector& n)
00439 {
00440 Vector ret;
00441
00442 ret.x = n.x * m.mat[0][0] +
00443 n.y * m.mat[1][0] +
00444 n.z * m.mat[2][0];
00445 ret.y = n.x * m.mat[0][1] +
00446 n.y * m.mat[1][1] +
00447 n.z * m.mat[2][1];
00448 ret.z = n.x * m.mat[0][2] +
00449 n.y * m.mat[1][2] +
00450 n.z * m.mat[2][2];
00451
00452 return(ret);
00453 }
00454
00455 Vector XForm::operator << (Vector& v)
00456 {
00457 Vector ret;
00458
00459 ret.x = v.x * m.mat[0][0] +
00460 v.y * m.mat[1][0] +
00461 v.z * m.mat[2][0] +
00462 m.mat[3][0];
00463 ret.y = v.x * m.mat[0][1] +
00464 v.y * m.mat[1][1] +
00465 v.z * m.mat[2][1] +
00466 m.mat[3][1];
00467 ret.z = v.x * m.mat[0][2] +
00468 v.y * m.mat[1][2] +
00469 v.z * m.mat[2][2] +
00470 m.mat[3][2];
00471
00472 return(ret);
00473 }
00474
00475 Ray XForm::operator << (Ray& r)
00476 {
00477 return(Ray(*this << r.p, *this < r.d));
00478 }
00479
00480
00481
00482
00483
00484 XForm::Matrix::Matrix()
00485 {
00486 Initalize();
00487 }
00488
00489 void XForm::Matrix::Initalize()
00490 {
00491 mat[0][0] = 1; mat[0][1] = 0; mat[0][2] = 0; mat[0][3] = 0;
00492 mat[1][0] = 0; mat[1][1] = 1; mat[1][2] = 0; mat[1][3] = 0;
00493 mat[2][0] = 0; mat[2][1] = 0; mat[2][2] = 1; mat[2][3] = 0;
00494 mat[3][0] = 0; mat[3][1] = 0; mat[3][2] = 0; mat[3][3] = 1;
00495 }
00496
00497 XForm::Matrix XForm::Matrix::operator * (Matrix& m)
00498 {
00499 Matrix ret;
00500
00501 for(int i = 0; i < 4; i++)
00502 {
00503 for(int j = 0; j < 4; j++)
00504 {
00505 ret.mat[i][j] = mat[i][0] * m.mat[0][j] +
00506 mat[i][1] * m.mat[1][j] +
00507 mat[i][2] * m.mat[2][j] +
00508 mat[i][3] * m.mat[3][j];
00509
00510 if(IsZero(ret.mat[i][j])) ret.mat[i][j] = 0;
00511 }
00512 }
00513
00514 return(ret);
00515 }
00516
00517 XForm::Matrix& XForm::Matrix::operator *= (XForm::Matrix& m)
00518 {
00519 return(*this = *this * m);
00520 }