Kigs Framework  Doc version 0.8
Open source multi purpose Rapid Application Development framework
v3d.inl.h
1 #include <cmath>
2 
3 v3d::v3d()
4 {
5 }
6 
7 v3d::v3d( const double& x , const double& y , const double& z ) : x(x), y(y), z(z)
8 {
9 }
10 
11 v3d::v3d( const v3d& P ) : x(P.x), y(P.y), z(P.z)
12 {
13 }
14 
15 v3d::v3d( const v3d& A , const v3d& B ,const asVector& v) : v3d(B.x-A.x, B.y-A.y, B.z-A.z)
16 {
17 }
18 
19 
20 v3d::v3d(const v3d& A, const v3d& B, const asMiddle& v) : v3d((B.x + A.x)*0.5, (B.y + A.y)*0.5, (B.z + A.z)*0.5)
21 {
22 }
23 
24 
25 
26 // Set (constructors-like)
27 void v3d::Set( const double& fValue )
28 {
29  x = y = z = fValue;
30 }
31 void v3d::Set( const double& x , const double& y , const double& z )
32 {
33  this->x = x;
34  this->y = y;
35  this->z = z;
36 }
37 
38 void v3d::Set( const v3d& P )
39 {
40  x = P.x;
41  y = P.y;
42  z = P.z;
43 }
44 
45 void v3d::Set( const v3d& A, const v3d& B)
46 {
47  x = B.x - A.x;
48  y = B.y - A.y;
49  z = B.z - A.z;
50 }
51 
52 
53 // Assignement
54 v3d& v3d::operator =( const v3d& V )
55 {
56  x = V.x;
57  y = V.y;
58  z = V.z;
59 
60  return *this;
61 }
62 
63 // Assignement
64 v3d& v3d::operator =( const double& V )
65 {
66  x = V;
67  y = V;
68  z = V;
69  return *this;
70 }
71 
72 
73 
74 // ----------------------------------------------------------------------
75 // +---------
76 // | Addition/Substraction
77 // +---------
78 // With another vector (Internal laws)
79 
80 
81 v3d operator + ( const v3d& U , const v3d& V )
82 {
83  return v3d(U.x + V.x, U.y + V.y, U.z + V.z);
84 }
85 
86 
87 v3d operator - ( const v3d& U , const v3d& V )
88 {
89  return v3d(U.x - V.x, U.y - V.y, U.z - V.z);
90 }
91 
92 // With assignement
93 v3d& v3d::operator += ( const v3d& V )
94 {
95  x += V.x;
96  y += V.y;
97  z += V.z;
98 
99  return *this;
100 }
101 v3d& v3d::operator -= ( const v3d& V )
102 {
103  x -= V.x;
104  y -= V.y;
105  z -= V.z;
106 
107  return *this;
108 }
109 
110 // Unary
111 v3d operator - ( const v3d& V )
112 {
113  return v3d(-V.x, -V.y, -V.z);
114 }
115 
116 
117 // ----------------------------------------------------------------------
118 // +---------
119 // | Multiplication/Division
120 // +---------
121 // With a scalar (External laws)
122 v3d operator * ( const double& fValue , const v3d& V )
123 {
124  return v3d(fValue * V.x, fValue * V.y, fValue * V.z);
125 }
126 
127 v3d operator * ( const v3d& V , const double& fValue )
128 {
129  return v3d(V.x * fValue, V.y * fValue, V.z * fValue);
130 }
131 
132 v3d operator * ( v3d V , const v3d& W )
133 {
134  V *= W;
135  return V;
136 }
137 
138 v3d operator / ( const double& fValue , const v3d& V )
139 {
140  return v3d(fValue / V.x, fValue / V.y, fValue / V.z);
141 }
142 
143 v3d operator / ( const v3d& V , const double& fValue )
144 {
145  return v3d(V.x / fValue, V.y / fValue, V.z / fValue);
146 }
147 
148 v3d operator / ( v3d V , const v3d& W )
149 {
150  V /= W;
151  return V;
152 }
153 
154 
155 // With assignement
156 v3d& v3d::operator *= ( const double& fValue )
157 {
158  x *= fValue;
159  y *= fValue;
160  z *= fValue;
161 
162  return *this;
163 }
164 
165 v3d& v3d::operator /= ( const double& fValue )
166 {
167  const double invfValue = 1.0 / fValue;
168  x *= invfValue;
169  y *= invfValue;
170  z *= invfValue;
171 
172  return *this;
173 }
174 
175 
176 v3d& v3d::operator *= ( const v3d& p )
177 {
178  x *= p.x;
179  y *= p.y;
180  z *= p.z;
181  return *this;
182 }
183 
184 v3d& v3d::operator /= ( const v3d& p )
185 {
186  x /= p.x;
187  y /= p.y;
188  z /= p.z;
189  return *this;
190 }
191 
192 
193 v3d Hadamard(v3d a, const v3d& b)
194 {
195  a *= b;
196  return a;
197 }
198 
199 
200 
201 // ----------------------------------------------------------------------
202 // +---------
203 // | Euclidian operations
204 // +---------
205 double Norm( const v3d& P )
206 {
207  return sqrt( sqr(P.x) + sqr(P.y) + sqr(P.z) );
208 }
209 
210 double NormSquare( const v3d& P )
211 {
212  return sqr(P.x) + sqr(P.y) + sqr(P.z);
213 }
214 
215 double Dist( const v3d& P1, const v3d& P2 )
216 {
217  const double dx = P2.x - P1.x;
218  const double dy = P2.y - P1.y;
219  const double dz = P2.z - P1.z;
220  return sqrt(sqr(dx) + sqr(dy) + sqr(dz));
221 }
222 
223 double DistSquare( const v3d& P1, const v3d& P2 )
224 {
225  const double dx = P2.x - P1.x;
226  const double dy = P2.y - P1.y;
227  const double dz = P2.z - P1.z;
228  return sqr(dx) + sqr(dy) + sqr(dz);
229 }
230 
231 #define SMALL_NUM 0.001
232 
233 double SegmentDist(const v3d& Pt1, const v3d& Pt2,const v3d& Pt3, const v3d& Pt4)
234 {
235  v3d u = Pt2 - Pt1;
236  v3d v = Pt4 - Pt3;
237  v3d w = Pt1 - Pt3;
238  double a = Dot(u,u); // always >= 0
239  double b = Dot(u,v);
240  double c = Dot(v,v); // always >= 0
241  double d = Dot(u,w);
242  double e = Dot(v,w);
243  double D = a*c - b*b; // always >= 0
244  double sc, sN, sD = D; // sc = sN / sD, default sD = D >= 0
245  double tc, tN, tD = D; // tc = tN / tD, default tD = D >= 0
246 
247  // compute the line parameters of the two closest points
248  if (D < (SMALL_NUM)) { // the lines are almost parallel
249  sN = (0.0); // force using point P0 on segment S1
250  sD = (1.0); // to prevent possible division by 0.0 later
251  tN = e;
252  tD = c;
253  }
254  else { // get the closest points on the infinite lines
255  sN = (b*e - c*d);
256  tN = (a*e - b*d);
257  if (sN < (0.0)) { // sc < 0 => the s=0 edge is visible
258  sN = (0.0);
259  tN = e;
260  tD = c;
261  }
262  else if (sN > sD) { // sc > 1 => the s=1 edge is visible
263  sN = sD;
264  tN = e + b;
265  tD = c;
266  }
267  }
268 
269  if (tN < (0.0)) { // tc < 0 => the t=0 edge is visible
270  tN = (0.0);
271  // recompute sc for this edge
272  if (-d < (0.0))
273  sN = (0.0);
274  else if (-d > a)
275  sN = sD;
276  else {
277  sN = -d;
278  sD = a;
279  }
280  }
281  else if (tN > tD) { // tc > 1 => the t=1 edge is visible
282  tN = tD;
283  // recompute sc for this edge
284  if ((-d + b) < (0.0))
285  sN = (0.0);
286  else if ((-d + b) > a)
287  sN = sD;
288  else {
289  sN = (-d + b);
290  sD = a;
291  }
292  }
293  // finally do the division to get sc and tc
294  sc = (std::abs(sN) < SMALL_NUM ? 0.0 : sN / sD);
295  tc = (std::abs(tN) < SMALL_NUM ? 0.0 : tN / tD);
296 
297  // get the difference of the two closest points
298  v3d dP = w + (sc * u) - (tc * v); // = S1(sc) - S2(tc)
299 
300  return Norm(dP); // return the closest distance
301 
302 }
303 
304 double PointToSegmentDist(const v3d& Pt, const v3d& Pt1,const v3d& Pt2,v3d& nearest,bool& insideSegment)
305 {
306  v3d v = Pt2 - Pt1;
307  v3d w = Pt - Pt1;
308 
309  double c1 = Dot(w,v);
310  insideSegment=false;
311  if ( c1 <= (0.0) )
312  {
313  nearest=Pt1;
314  return Dist(Pt, Pt1);
315  }
316 
317  double c2 = Dot(v,v);
318  if ( c2 <= c1 )
319  {
320  nearest=Pt2;
321  return Dist(Pt, Pt2);
322  }
323 
324  insideSegment=true;
325  double b = c1 / c2;
326  v3d Pb = Pt1 + (v3d)((double)b * v);
327  nearest=Pb;
328  return Dist(Pt, Pb);
329 }
330 
331 
332 // ----------------------------------------------------------------------
333 // +---------
334 // | Affine operations
335 // +---------
336 v3d Mid( const v3d& P , const v3d& Q )
337 {
338  return v3d( (P.x + Q.x) * (0.5),
339  (P.y + Q.y) * (0.5),
340  (P.z + Q.z) * (0.5) );
341 }
342 
343 v3d Bary( const double& a , const v3d& P , const double& b , const v3d& Q )
344 {
345  return v3d( ((a * P.x) + (b * Q.x)) ,
346  ((a * P.y) + (b * Q.y)) ,
347  ((a * P.z) + (b * Q.z)) );
348 }
349 
350 
351 // ----------------------------------------------------------------------
352 // +---------
353 // | Utilities
354 // +---------
355 void v3d::Normalize( void )
356 {
357  double tmp = Norm( *this );
358  if (tmp != (0.0))
359  {
360  tmp = (1.0)/tmp;
361  x *= tmp;
362  y *= tmp;
363  z *= tmp;
364  }
365 }
366 
367 inline v3d v3d::Normalized( void ) const
368 {
369  v3d result = *this;
370  result.Normalize();
371  return result;
372 }
373 
374 
375 
376 inline v3d Lerp( const v3d& P , const v3d& Q, const double& t )
377 {
378  double s = (1.0) - t;
379  return v3d( (s * P.x) + (t * Q.x),
380  (s * P.y) + (t * Q.y),
381  (s * P.z) + (t * Q.z) );
382 }
383 
384 
385 inline v3d ProjectOnPlane(v3d q, v3d o, v3d n)
386 {
387  return q - (v3d)(Dot(q-o, n)*n);
388 }
389 
390 
391 
392 
393 bool operator<( const v3d& U , const v3d& V )
394 {
395  return (U.x < V.x && U.y < V.y && U.z < V.z);
396 }
397 
398 bool operator<=( const v3d& U , const v3d& V )
399 {
400  return (U.x <= V.x && U.y <= V.y && U.z <= V.z);
401 }
402 
403 bool operator>( const v3d& U , const v3d& V )
404 {
405  return (U.x > V.x && U.y > V.y && U.z > V.z);
406 }
407 
408 bool operator>=( const v3d& U , const v3d& V )
409 {
410  return (U.x >= V.x && U.y >= V.y && U.z >= V.z);
411 }
412 
413 bool operator==( const v3d& U , const v3d& V )
414 {
415  return (U.x == V.x && U.y == V.y && U.z == V.z);
416 }
417 
418 bool operator!=( const v3d& U , const v3d& V )
419 {
420  return (U.x != V.x || U.y != V.y || U.z != V.z);
421 }
422 
423 
424 
425 
426 
427 // +---------
428 // | Acces Operators
429 // +---------
430 const double& v3d::operator[](Int i) const
431 {
432  assert(i>=0 && i<3);
433  return *((&x)+i);
434 }
435 
436 double& v3d::operator[](Int i)
437 {
438  assert(i>=0 && i<3);
439  return *((&x)+i);
440 }
441 
442 
443 void v3d::ClampMax(const double v)
444 {
445  if (x>v)
446  x = v;
447  if (y>v)
448  y = v;
449  if (z>v)
450  z = v;
451 }
452 
453 void v3d::ClampMin(const double v)
454 {
455  if (x<v)
456  x = v;
457  if (y<v)
458  y = v;
459  if (z<v)
460  z = v;
461 }
462 
463 
464 
465 
466 
467 // ----------------------------------------------------------------------
468 // +---------
469 // | Cross product
470 // +---------
471 v3d operator ^ ( const v3d& U , const v3d& V )
472 {
473  return v3d((U.y * V.z) - (U.z * V.y),
474  (U.z * V.x) - (U.x * V.z),
475  (U.x * V.y) - (U.y * V.x));
476 }
477 
478 // With assignement
479 const v3d& v3d::operator ^= ( const v3d& V )
480 {
481  double _x = x, _y = y;
482  x = (_y * V.z) - (z * V.y);
483  y = (z * V.x) - (_x * V.z);
484  z = (_x * V.y) - (_y * V.x);
485 
486  return *this;
487 }
488 
489 void v3d::CrossProduct( const v3d& V, const v3d& W )
490 {
491  x = (V.y * W.z) - (V.z * W.y);
492  y = (V.z * W.x) - (V.x * W.z);
493  z = (V.x * W.y) - (V.y * W.x);
494 }
495 
496 // ----------------------------------------------------------------------
497 // +---------
498 // | Euclidian operations
499 // +---------
500 double Dot( const v3d& U , const v3d& V )
501 {
502  return ((U.x * V.x) + (U.y * V.y) + (U.z * V.z));
503 }
504 
505 
506 #undef SMALL_NUM
operator<
bool operator<(const DrawableSorterItem &Item1, const DrawableSorterItem &Item2)
overload < operator for comparison
Definition: DrawableSorter.h:30