Increase ParseScript cache from 30 to 90 seconds
[xy_vsfilter.git] / src / subpic / CoordGeom.cpp
blob7df30f8c8aab2181dbcc7a9e3aa738388ff736eb
1 /*
2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
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 2, or (at your option)
8 * any later version.
9 *
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 GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "stdafx.h"
23 #include <math.h>
24 #include "CoordGeom.h"
26 #define EPSILON (1e-7)
27 #define BIGNUMBER (1e+9)
28 #define IsZero(d) (fabs(d) < EPSILON)
31 // Vector
34 Vector::Vector(float x, float y, float z)
36 this->x = x;
37 this->y = y;
38 this->z = z;
41 void Vector::Set(float x, float y, float z)
43 this->x = x;
44 this->y = y;
45 this->z = z;
48 float Vector::Length()
50 return(sqrt(x * x + y * y + z * z));
53 float Vector::Sum()
55 return(x + y + z);
58 float Vector::CrossSum()
60 return(x*y + x*z + y*z);
63 Vector Vector::Cross()
65 return(Vector(x*y, x*z, y*z));
68 Vector Vector::Pow(float exp)
70 return(exp == 0 ? Vector(1, 1, 1) : exp == 1 ? *this : Vector(pow(x, exp), pow(y, exp), pow(z, exp)));
73 Vector Vector::Unit()
75 float l = Length();
76 if(!l || l == 1) return(*this);
77 return(*this * (1 / l));
80 Vector& Vector::Unitalize()
82 return(*this = Unit());
85 Vector Vector::Normal(Vector& a, Vector& b)
87 return((a - *this) % (b - a));
90 float Vector::Angle(Vector& a, Vector& b)
92 return(((a - *this).Unit()).Angle((b - *this).Unit()));
95 float Vector::Angle(Vector& a)
97 float angle = *this | a;
98 return((angle > 1) ? 0 : (angle < -1) ? PI : acos(angle));
101 void Vector::Angle(float& u, float& v)
103 Vector n = Unit();
105 u = asin(n.y);
107 if(IsZero(n.z)) v = PI/2 * Sgn(n.x);
108 else if(n.z > 0) v = atan(n.x / n.z);
109 else if(n.z < 0) v = IsZero(n.x) ? PI : (PI * Sgn(n.x) + atan(n.x / n.z));
112 Vector Vector::Angle()
114 Vector ret;
115 Angle(ret.x, ret.y);
116 ret.z = 0;
117 return(ret);
120 Vector& Vector::Min(Vector& a)
122 x = (x < a.x) ? x : a.x;
123 y = (y < a.y) ? y : a.y;
124 z = (z < a.z) ? z : a.z;
125 return(*this);
128 Vector& Vector::Max(Vector& a)
130 x = (x > a.x) ? x : a.x;
131 y = (y > a.y) ? y : a.y;
132 z = (z > a.z) ? z : a.z;
133 return(*this);
136 Vector Vector::Abs()
138 return(Vector(fabs(x), fabs(y), fabs(z)));
141 Vector Vector::Reflect(Vector& n)
143 return(n * ((-*this) | n) * 2 - (-*this));
146 Vector Vector::Refract(Vector& N, float nFront, float nBack, float* nOut)
148 Vector D = -*this;
150 float N_dot_D = (N | D);
151 float n = N_dot_D >= 0 ? (nFront / nBack) : (nBack / nFront);
153 Vector cos_D = N * N_dot_D;
154 Vector sin_T = (cos_D - D) * n;
156 float len_sin_T = sin_T | sin_T;
158 if(len_sin_T > 1)
160 if(nOut) {*nOut = N_dot_D >= 0 ? nFront : nBack;}
161 return((*this).Reflect(N));
164 float N_dot_T = sqrt(1.0 - len_sin_T);
165 if(N_dot_D < 0) N_dot_T = -N_dot_T;
167 if(nOut) {*nOut = N_dot_D >= 0 ? nBack : nFront;}
169 return(sin_T - (N * N_dot_T));
172 Vector Vector::Refract2(Vector& N, float nFrom, float nTo, float* nOut)
174 Vector D = -*this;
176 float N_dot_D = (N | D);
177 float n = nFrom / nTo;
179 Vector cos_D = N * N_dot_D;
180 Vector sin_T = (cos_D - D) * n;
182 float len_sin_T = sin_T | sin_T;
184 if(len_sin_T > 1)
186 if(nOut) {*nOut = nFrom;}
187 return((*this).Reflect(N));
190 float N_dot_T = sqrt(1.0 - len_sin_T);
191 if(N_dot_D < 0) N_dot_T = -N_dot_T;
193 if(nOut) {*nOut = nTo;}
195 return(sin_T - (N * N_dot_T));
198 float Vector::operator | (Vector& v)
200 return(x * v.x + y * v.y + z * v.z);
203 Vector Vector::operator % (Vector& v)
205 return(Vector(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x));
208 float& Vector::operator [] (int i)
210 return(!i ? x : (i == 1) ? y : z);
213 Vector Vector::operator - ()
215 return(Vector(-x, -y, -z));
218 bool Vector::operator == (const Vector& v) const
220 if(IsZero(x - v.x) && IsZero(y - v.y) && IsZero(z - v.z)) return(true);
221 return(false);
224 bool Vector::operator != (const Vector& v) const
226 return((*this == v) ? false : true);
229 Vector Vector::operator + (float d)
231 return(Vector(x + d, y + d, z + d));
234 Vector Vector::operator + (Vector& v)
236 return(Vector(x + v.x, y + v.y, z + v.z));
239 Vector Vector::operator - (float d)
241 return(Vector(x - d, y - d, z - d));
244 Vector Vector::operator - (Vector& v)
246 return(Vector(x - v.x, y - v.y, z - v.z));
249 Vector Vector::operator * (float d)
251 return(Vector(x * d, y * d, z * d));
254 Vector Vector::operator * (Vector& v)
256 return(Vector(x * v.x, y * v.y, z * v.z));
259 Vector Vector::operator / (float d)
261 return(Vector(x / d, y / d, z / d));
264 Vector Vector::operator / (Vector& v)
266 return(Vector(x / v.x, y / v.y, z / v.z));
269 Vector& Vector::operator += (float d)
271 x += d; y += d; z += d;
272 return(*this);
275 Vector& Vector::operator += (Vector& v)
277 x += v.x; y += v.y; z += v.z;
278 return(*this);
281 Vector& Vector::operator -= (float d)
283 x -= d; y -= d; z -= d;
284 return(*this);
287 Vector& Vector::operator -= (Vector& v)
289 x -= v.x; y -= v.y; z -= v.z;
290 return(*this);
293 Vector& Vector::operator *= (float d)
295 x *= d; y *= d; z *= d;
296 return(*this);
299 Vector& Vector::operator *= (Vector& v)
301 x *= v.x; y *= v.y; z *= v.z;
302 return(*this);
305 Vector& Vector::operator /= (float d)
307 x /= d; y /= d; z /= d;
308 return(*this);
311 Vector& Vector::operator /= (Vector& v)
313 x /= v.x; y /= v.y; z /= v.z;
314 return(*this);
318 // Ray
321 Ray::Ray(Vector& p, Vector& d)
323 this->p = p;
324 this->d = d;
327 void Ray::Set(Vector& p, Vector& d)
329 this->p = p;
330 this->d = d;
333 float Ray::GetDistanceFrom(Ray& r)
335 float t = (d | r.d);
336 if(IsZero(t)) return(-BIGNUMBER); // plane is paralell to the ray, return -infinite
337 return(((r.p - p) | r.d) / t);
340 float Ray::GetDistanceFrom(Vector& v)
342 float t = ((v - p) | d) / (d | d);
343 return(((p + d*t) - v).Length());
346 Vector Ray::operator [] (float t)
348 return(p + d*t);
352 // XForm
355 XForm::XForm(Ray& r, Vector& s, bool isWorldToLocal)
357 Initalize(r, s, isWorldToLocal);
360 void XForm::Initalize()
362 m.Initalize();
365 void XForm::Initalize(Ray& r, Vector& s, bool isWorldToLocal)
367 Initalize();
369 if(m_isWorldToLocal = isWorldToLocal)
371 *this -= r.p;
372 *this >>= r.d;
373 *this /= s;
376 else
378 *this *= s;
379 *this <<= r.d;
380 *this += r.p;
384 void XForm::operator *= (Vector& v)
386 Matrix s;
387 s.mat[0][0] = v.x;
388 s.mat[1][1] = v.y;
389 s.mat[2][2] = v.z;
390 m *= s;
393 void XForm::operator += (Vector& v)
395 Matrix t;
396 t.mat[3][0] = v.x;
397 t.mat[3][1] = v.y;
398 t.mat[3][2] = v.z;
399 m *= t;
402 void XForm::operator <<= (Vector& v)
404 Matrix x;
405 x.mat[1][1] = cos(v.x); x.mat[1][2] = -sin(v.x);
406 x.mat[2][1] = sin(v.x); x.mat[2][2] = cos(v.x);
408 Matrix y;
409 y.mat[0][0] = cos(v.y); y.mat[0][2] = -sin(v.y);
410 y.mat[2][0] = sin(v.y); y.mat[2][2] = cos(v.y);
412 Matrix z;
413 z.mat[0][0] = cos(v.z); z.mat[0][1] = -sin(v.z);
414 z.mat[1][0] = sin(v.z); z.mat[1][1] = cos(v.z);
416 m = m_isWorldToLocal ? (m * y * x * z) : (m * z * x * y);
419 void XForm::operator /= (Vector& v)
421 Vector s;
422 s.x = IsZero(v.x) ? 0 : 1 / v.x;
423 s.y = IsZero(v.y) ? 0 : 1 / v.y;
424 s.z = IsZero(v.z) ? 0 : 1 / v.z;
425 *this *= s;
428 void XForm::operator -= (Vector& v)
430 *this += -v;
433 void XForm::operator >>= (Vector& v)
435 *this <<= -v;
438 Vector XForm::operator < (Vector& n)
440 Vector ret;
442 ret.x = n.x * m.mat[0][0] +
443 n.y * m.mat[1][0] +
444 n.z * m.mat[2][0];
445 ret.y = n.x * m.mat[0][1] +
446 n.y * m.mat[1][1] +
447 n.z * m.mat[2][1];
448 ret.z = n.x * m.mat[0][2] +
449 n.y * m.mat[1][2] +
450 n.z * m.mat[2][2];
452 return(ret);
455 Vector XForm::operator << (Vector& v)
457 Vector ret;
459 ret.x = v.x * m.mat[0][0] +
460 v.y * m.mat[1][0] +
461 v.z * m.mat[2][0] +
462 m.mat[3][0];
463 ret.y = v.x * m.mat[0][1] +
464 v.y * m.mat[1][1] +
465 v.z * m.mat[2][1] +
466 m.mat[3][1];
467 ret.z = v.x * m.mat[0][2] +
468 v.y * m.mat[1][2] +
469 v.z * m.mat[2][2] +
470 m.mat[3][2];
472 return(ret);
475 Ray XForm::operator << (Ray& r)
477 return(Ray(*this << r.p, *this < r.d));
481 // XForm::Matrix
484 XForm::Matrix::Matrix()
486 Initalize();
489 void XForm::Matrix::Initalize()
491 mat[0][0] = 1; mat[0][1] = 0; mat[0][2] = 0; mat[0][3] = 0;
492 mat[1][0] = 0; mat[1][1] = 1; mat[1][2] = 0; mat[1][3] = 0;
493 mat[2][0] = 0; mat[2][1] = 0; mat[2][2] = 1; mat[2][3] = 0;
494 mat[3][0] = 0; mat[3][1] = 0; mat[3][2] = 0; mat[3][3] = 1;
497 XForm::Matrix XForm::Matrix::operator * (Matrix& m)
499 Matrix ret;
501 for(int i = 0; i < 4; i++)
503 for(int j = 0; j < 4; j++)
505 ret.mat[i][j] = mat[i][0] * m.mat[0][j] +
506 mat[i][1] * m.mat[1][j] +
507 mat[i][2] * m.mat[2][j] +
508 mat[i][3] * m.mat[3][j];
510 if(IsZero(ret.mat[i][j])) ret.mat[i][j] = 0;
514 return(ret);
517 XForm::Matrix& XForm::Matrix::operator *= (XForm::Matrix& m)
519 return(*this = *this * m);