Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/particleEngine/src/lib/math/vector.cc @ 3933

Last change on this file since 3933 was 3860, checked in by bensch, 20 years ago

orxonox/trunk: moved likely to compiler.h in defs
also reset all the UNLIKELY_IF functions to how they should look.

the old approach is still valid, but depricated.

@patrick: i hope this is ok for you, for it is LINUX-standard.
and i think windows is also able to handle likely/unlikely because it is a compiler issue not a system issue

File size: 17.9 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Christian Meyer
13   co-programmer: Patrick Boenzli : Vector::scale()
14                                    Vector::abs()
15   
16   Quaternion code borrowed from an Gamasutra article by Nick Bobick and Ken Shoemake
17*/
18
19#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
20
21#include "vector.h"
22#include "debug.h"
23
24using namespace std;
25
26/**
27   \brief add two vectors
28   \param v: the other vector
29   \return the sum of both vectors
30*/
31
32//Vector Vector::operator+ (const Vector& v) const
33
34
35/**
36   \brief subtract a vector from another
37   \param v: the other vector
38   \return the difference between the vectors
39*/
40//Vector Vector::operator- (const Vector& v) const
41
42
43/**
44   \brief calculate the dot product of two vectors
45   \param v: the other vector
46   \return the dot product of the vectors
47*/
48//float Vector::operator* (const Vector& v) const
49
50
51/**
52   \brief multiply a vector with a float
53   \param f: the factor
54   \return the vector multipied by f
55*/
56//Vector Vector::operator* (float f) const
57
58
59/**
60   \brief divide a vector with a float
61   \param f: the divisor
62   \return the vector divided by f   
63*/
64Vector Vector::operator/ (float f) const
65{
66  if( unlikely(f == 0.0))
67  {
68    // Prevent divide by zero
69    return Vector (0,0,0);
70  }
71  return Vector(x / f, y / f, z / f);
72}
73
74/**
75   \brief calculate the dot product of two vectors
76   \param v: the other vector
77   \return the dot product of the vectors
78*/
79float Vector::dot (const Vector& v) const
80{
81  return x*v.x+y*v.y+z*v.z;
82}
83
84/**
85  \brief calculate the cross product of two vectors
86  \param v: the other vector
87        \return the cross product of the vectors
88*/
89//Vector Vector::cross (const Vector& v) const
90
91 
92/**
93   \brief normalizes the vector to lenght 1.0
94*/
95//void Vector::normalize ()
96
97
98/**
99   \brief returns the voctor normalized to length 1.0
100*/
101
102Vector* Vector::getNormalized()
103{
104  float l = len();
105  if(unlikely(l != 1.0))
106    {
107      return this;
108    }
109  else if(unlikely(l == 0.0))
110    {
111      return 0;
112    }
113
114  return new Vector(x / l, y /l, z / l);
115}
116
117/**
118   \brief scales this Vector with Vector v.
119   \param v the vector to scale this vector with
120*/
121void Vector::scale(const Vector& v)
122{
123  x *= v.x;
124  y *= v.y;
125  z *= v.z;
126}
127
128 
129/**
130   \brief calculates the lenght of the vector
131   \return the lenght of the vector
132*/
133//float Vector::len () const
134
135
136/**
137   \brief Vector is looking in the positive direction on all axes after this
138*/
139Vector Vector::abs() 
140{
141  Vector v(fabs(x), fabs(y), fabs(z));
142  return v;
143}
144
145/**
146   \brief calculate the angle between two vectors in radiances
147   \param v1: a vector
148   \param v2: another vector
149   \return the angle between the vectors in radians
150*/
151float angleRad (const Vector& v1, const Vector& v2)
152{
153  return acos( v1 * v2 / (v1.len() * v2.len()));
154}
155
156
157/**
158   \brief calculate the angle between two vectors in degrees
159   \param v1: a vector
160   \param v2: another vector
161   \return the angle between the vectors in degrees
162*/
163float angleDeg (const Vector& v1, const Vector& v2)
164{
165  float f;
166  f = acos( v1 * v2 / (v1.len() * v2.len()));
167  return f * 180 / PI;
168}
169
170
171/**
172   \brief Outputs the values of the Vector
173*/
174void Vector::debug(void)
175{
176  PRINT(0)("Vector Debug information\n");
177  PRINT(0)("x: %f; y: %f; z: %f", x, y, z);
178  PRINT(3)(" lenght: %f", len());
179  PRINT(0)("\n");
180}
181
182/**
183        \brief creates a multiplicational identity Quaternion
184*/
185//Quaternion::Quaternion ()
186
187
188/**
189        \brief turns a rotation along an axis into a Quaternion
190        \param angle: the amount of radians to rotate
191        \param axis: the axis to rotate around
192*/
193//Quaternion::Quaternion (float angle, const Vector& axis)
194
195
196/**
197   \brief calculates a lookAt rotation
198   \param dir: the direction you want to look
199   \param up: specify what direction up should be
200   
201   Mathematically this determines the rotation a (0,0,1)-Vector has to undergo to point
202   the same way as dir. If you want to use this with cameras, you'll have to reverse the
203   dir Vector (Vector(0,0,0) - your viewing direction) or you'll point the wrong way. You
204   can use this for meshes as well (then you do not have to reverse the vector), but keep
205   in mind that if you do that, the model's front has to point in +z direction, and left
206   and right should be -x or +x respectively or the mesh wont rotate correctly.
207*/
208Quaternion::Quaternion (const Vector& dir, const Vector& up)
209{
210  Vector z = dir;
211  z.normalize(); 
212  Vector x = up.cross(z);
213  x.normalize(); 
214  Vector y = z.cross(x);
215 
216  float m[4][4];
217  m[0][0] = x.x;
218  m[0][1] = x.y;
219  m[0][2] = x.z;
220  m[0][3] = 0;
221  m[1][0] = y.x;
222  m[1][1] = y.y;
223  m[1][2] = y.z;
224  m[1][3] = 0;
225  m[2][0] = z.x;
226  m[2][1] = z.y;
227  m[2][2] = z.z;
228  m[2][3] = 0;
229  m[3][0] = 0;
230  m[3][1] = 0;
231  m[3][2] = 0;
232  m[3][3] = 1;
233 
234  *this = Quaternion (m);
235}
236
237/**
238        \brief calculates a rotation from euler angles
239        \param roll: the roll in radians
240        \param pitch: the pitch in radians
241        \param yaw: the yaw in radians
242       
243        I DO HONESTLY NOT EXACTLY KNOW WHICH ANGLE REPRESENTS WHICH ROTATION. And I do not know
244        in what order they are applied, I just copy-pasted the code.
245*/
246Quaternion::Quaternion (float roll, float pitch, float yaw)
247{
248        float cr, cp, cy, sr, sp, sy, cpcy, spsy;
249       
250        // calculate trig identities
251        cr = cos(roll/2);
252        cp = cos(pitch/2);
253        cy = cos(yaw/2);
254       
255        sr = sin(roll/2);
256        sp = sin(pitch/2);
257        sy = sin(yaw/2);
258       
259        cpcy = cp * cy;
260        spsy = sp * sy;
261       
262        w = cr * cpcy + sr * spsy;
263        v.x = sr * cpcy - cr * spsy;
264        v.y = cr * sp * cy + sr * cp * sy;
265        v.z = cr * cp * sy - sr * sp * cy;
266}
267
268/**
269        \brief rotates one Quaternion by another
270        \param q: another Quaternion to rotate this by
271        \return a quaternion that represents the first one rotated by the second one (WARUNING: this operation is not commutative! e.g. (A*B) != (B*A))
272*/
273Quaternion Quaternion::operator*(const Quaternion& q) const
274{
275  float A, B, C, D, E, F, G, H;
276 
277  A = (w   + v.x)*(q.w   + q.v.x);
278  B = (v.z - v.y)*(q.v.y - q.v.z);
279  C = (w   - v.x)*(q.v.y + q.v.z); 
280  D = (v.y + v.z)*(q.w   - q.v.x);
281  E = (v.x + v.z)*(q.v.x + q.v.y);
282  F = (v.x - v.z)*(q.v.x - q.v.y);
283  G = (w   + v.y)*(q.w   - q.v.z);
284  H = (w   - v.y)*(q.w   + q.v.z);
285 
286  Quaternion r;
287  r.v.x = A - (E + F + G + H)/2;
288  r.v.y = C + (E - F + G - H)/2;
289  r.v.z = D + (E - F - G + H)/2;
290  r.w = B +  (-E - F + G + H)/2;
291
292  return r;
293}
294
295/**
296   \brief add two Quaternions
297   \param q: another Quaternion
298   \return the sum of both Quaternions
299*/
300/*
301Quaternion Quaternion::operator+(const Quaternion& q) const
302{
303  Quaternion r(*this);
304  r.w = r.w + q.w;
305  r.v = r.v + q.v;
306  return r;
307}
308*/
309
310/**
311   \brief subtract two Quaternions
312   \param q: another Quaternion
313   \return the difference of both Quaternions
314*/
315/*
316Quaternion Quaternion::operator- (const Quaternion& q) const
317{
318  Quaternion r(*this);
319  r.w = r.w - q.w;
320  r.v = r.v - q.v;
321  return r;
322}
323*/
324
325/**
326   \brief rotate a Vector by a Quaternion
327   \param v: the Vector
328   \return a new Vector representing v rotated by the Quaternion
329*/
330
331Vector Quaternion::apply (Vector& v) const
332{
333  Quaternion q;
334  q.v = v;
335  q.w = 0;
336  q = *this * q * conjugate();
337  return q.v;
338}
339
340
341/**
342   \brief multiply a Quaternion with a real value
343   \param f: a real value
344   \return a new Quaternion containing the product
345*/
346Quaternion Quaternion::operator*(const float& f) const
347{
348  Quaternion r(*this);
349  r.w = r.w*f;
350  r.v = r.v*f;
351  return r;
352}
353
354/**
355   \brief divide a Quaternion by a real value
356   \param f: a real value
357   \return a new Quaternion containing the quotient
358*/
359Quaternion Quaternion::operator/(const float& f) const
360{
361  if( f == 0) return Quaternion();
362  Quaternion r(*this);
363  r.w = r.w/f;
364  r.v = r.v/f;
365  return r;
366}
367
368/**
369   \brief calculate the conjugate value of the Quaternion
370   \return the conjugate Quaternion
371*/
372/*
373Quaternion Quaternion::conjugate() const
374{
375  Quaternion r(*this);
376  r.v = Vector() - r.v;
377  return r;
378}
379*/
380
381/**
382   \brief calculate the norm of the Quaternion
383   \return the norm of The Quaternion
384*/
385float Quaternion::norm() const
386{
387  return w*w + v.x*v.x + v.y*v.y + v.z*v.z;
388}
389
390/**
391   \brief calculate the inverse value of the Quaternion
392   \return the inverse Quaternion
393   
394        Note that this is equal to conjugate() if the Quaternion's norm is 1
395*/
396Quaternion Quaternion::inverse() const
397{
398  float n = norm();
399  if (n != 0)
400    {
401      return conjugate() / norm();
402    }
403  else return Quaternion();
404}
405
406/**
407   \brief convert the Quaternion to a 4x4 rotational glMatrix
408   \param m: a buffer to store the Matrix in
409*/
410void Quaternion::matrix (float m[4][4]) const
411{
412  float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; 
413 
414  // calculate coefficients
415  x2 = v.x + v.x;
416  y2 = v.y + v.y; 
417  z2 = v.z + v.z;
418  xx = v.x * x2; xy = v.x * y2; xz = v.x * z2;
419  yy = v.y * y2; yz = v.y * z2; zz = v.z * z2;
420  wx = w * x2; wy = w * y2; wz = w * z2;
421 
422  m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz;
423  m[2][0] = xz + wy; m[3][0] = 0.0;
424       
425  m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz);
426  m[2][1] = yz - wx; m[3][1] = 0.0;
427 
428  m[0][2] = xz - wy; m[1][2] = yz + wx;
429  m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0;
430 
431  m[0][3] = 0; m[1][3] = 0;
432  m[2][3] = 0; m[3][3] = 1;
433}
434
435/**
436   \brief performs a smooth move.
437   \param from from where
438   \param to to where
439   \param t the time this transformation should take
440   \param res The approximation-density
441*/
442void Quaternion::quatSlerp(const Quaternion* from, const Quaternion* to, float t, Quaternion* res)
443{
444  float tol[4];
445  double omega, cosom, sinom, scale0, scale1;
446  DELTA = 0.2;
447
448  cosom = from->v.x * to->v.x + from->v.y * to->v.y + from->v.z * to->v.z + from->w * to->w;
449
450  if( cosom < 0.0 ) 
451    { 
452      cosom = -cosom; 
453      tol[0] = -to->v.x;
454      tol[1] = -to->v.y;
455      tol[2] = -to->v.z;
456      tol[3] = -to->w;
457    }
458  else
459    {
460      tol[0] = to->v.x;
461      tol[1] = to->v.y;
462      tol[2] = to->v.z;
463      tol[3] = to->w;
464    }
465 
466  //if( (1.0 - cosom) > DELTA )
467  //{
468      omega = acos(cosom);
469      sinom = sin(omega);
470      scale0 = sin((1.0 - t) * omega) / sinom;
471      scale1 = sin(t * omega) / sinom;
472      //}
473      /*
474  else
475    {
476      scale0 = 1.0 - t;
477      scale1 = t;
478    }
479      */
480  res->v.x = scale0 * from->v.x + scale1 * tol[0];
481  res->v.y = scale0 * from->v.y + scale1 * tol[1];
482  res->v.z = scale0 * from->v.z + scale1 * tol[2];
483  res->w = scale0 * from->w + scale1 * tol[3];
484}
485
486
487/**
488   \brief convert a rotational 4x4 glMatrix into a Quaternion
489   \param m: a 4x4 matrix in glMatrix order
490*/
491Quaternion::Quaternion (float m[4][4])
492{
493       
494  float  tr, s, q[4];
495  int    i, j, k;
496
497  int nxt[3] = {1, 2, 0};
498
499  tr = m[0][0] + m[1][1] + m[2][2];
500
501        // check the diagonal
502  if (tr > 0.0) 
503  {
504    s = sqrt (tr + 1.0);
505    w = s / 2.0;
506    s = 0.5 / s;
507    v.x = (m[1][2] - m[2][1]) * s;
508    v.y = (m[2][0] - m[0][2]) * s;
509    v.z = (m[0][1] - m[1][0]) * s;
510        } 
511        else 
512        {
513                // diagonal is negative
514        i = 0;
515        if (m[1][1] > m[0][0]) i = 1;
516    if (m[2][2] > m[i][i]) i = 2;
517    j = nxt[i];
518    k = nxt[j];
519
520    s = sqrt ((m[i][i] - (m[j][j] + m[k][k])) + 1.0);
521     
522    q[i] = s * 0.5;
523           
524    if (s != 0.0) s = 0.5 / s;
525       
526          q[3] = (m[j][k] - m[k][j]) * s;
527    q[j] = (m[i][j] + m[j][i]) * s;
528    q[k] = (m[i][k] + m[k][i]) * s;
529
530        v.x = q[0];
531        v.y = q[1];
532        v.z = q[2];
533        w = q[3];
534  }
535}
536
537/**
538   \brief outputs some nice formated debug information about this quaternion
539*/
540void Quaternion::debug(void)
541{
542  PRINT(0)("Quaternion Debug Information\n");
543  PRINT(0)("real a=%f; imag: x=%f y=%f z=%f\n", w, v.x, v.y, v.z);
544}
545
546/**
547   \brief create a rotation from a vector
548   \param v: a vector
549*/
550Rotation::Rotation (const Vector& v)
551{
552  Vector x = Vector( 1, 0, 0);
553  Vector axis = x.cross( v);
554  axis.normalize();
555  float angle = angleRad( x, v);
556  float ca = cos(angle);
557  float sa = sin(angle);
558  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
559  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
560  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
561  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
562  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
563  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
564  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
565  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
566  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
567}
568
569/**
570   \brief creates a rotation from an axis and an angle (radians!)
571   \param axis: the rotational axis
572   \param angle: the angle in radians
573*/
574Rotation::Rotation (const Vector& axis, float angle)
575{
576  float ca, sa;
577  ca = cos(angle);
578  sa = sin(angle);
579  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
580  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
581  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
582  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
583  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
584  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
585  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
586  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
587  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
588}
589
590/**
591   \brief creates a rotation from euler angles (pitch/yaw/roll)
592   \param pitch: rotation around z (in radians)
593   \param yaw: rotation around y (in radians)
594   \param roll: rotation around x (in radians)
595*/
596Rotation::Rotation ( float pitch, float yaw, float roll)
597{
598  float cy, sy, cr, sr, cp, sp;
599  cy = cos(yaw);
600  sy = sin(yaw);
601  cr = cos(roll);
602  sr = sin(roll);
603  cp = cos(pitch);
604  sp = sin(pitch);
605  m[0] = cy*cr;
606  m[1] = -cy*sr;
607  m[2] = sy;
608  m[3] = cp*sr+sp*sy*cr;
609  m[4] = cp*cr-sp*sr*sy;
610  m[5] = -sp*cy;
611  m[6] = sp*sr-cp*sy*cr;
612  m[7] = sp*cr+cp*sy*sr;
613  m[8] = cp*cy;
614}
615
616/**
617   \brief creates a nullrotation (an identity rotation)
618*/
619Rotation::Rotation ()
620{
621  m[0] = 1.0f;
622  m[1] = 0.0f;
623  m[2] = 0.0f;
624  m[3] = 0.0f;
625  m[4] = 1.0f;
626  m[5] = 0.0f;
627  m[6] = 0.0f;
628  m[7] = 0.0f;
629  m[8] = 1.0f;
630}
631
632/**
633   \brief fills the specified buffer with a 4x4 glmatrix
634   \param buffer: Pointer to an array of 16 floats
635   
636   Use this to get the rotation in a gl-compatible format
637*/
638void Rotation::glmatrix (float* buffer)
639{
640        buffer[0] = m[0];
641        buffer[1] = m[3];
642        buffer[2] = m[6];
643        buffer[3] = m[0];
644        buffer[4] = m[1];
645        buffer[5] = m[4];
646        buffer[6] = m[7];
647        buffer[7] = m[0];
648        buffer[8] = m[2];
649        buffer[9] = m[5];
650        buffer[10] = m[8];
651        buffer[11] = m[0];
652        buffer[12] = m[0];
653        buffer[13] = m[0];
654        buffer[14] = m[0];
655        buffer[15] = m[1];
656}
657
658/**
659   \brief multiplies two rotational matrices
660   \param r: another Rotation
661   \return the matrix product of the Rotations
662   
663   Use this to rotate one rotation by another
664*/
665Rotation Rotation::operator* (const Rotation& r)
666{
667        Rotation p;
668       
669        p.m[0] = m[0]*r.m[0] + m[1]*r.m[3] + m[2]*r.m[6];
670        p.m[1] = m[0]*r.m[1] + m[1]*r.m[4] + m[2]*r.m[7];
671        p.m[2] = m[0]*r.m[2] + m[1]*r.m[5] + m[2]*r.m[8];
672       
673        p.m[3] = m[3]*r.m[0] + m[4]*r.m[3] + m[5]*r.m[6];
674        p.m[4] = m[3]*r.m[1] + m[4]*r.m[4] + m[5]*r.m[7];
675        p.m[5] = m[3]*r.m[2] + m[4]*r.m[5] + m[5]*r.m[8];
676
677        p.m[6] = m[6]*r.m[0] + m[7]*r.m[3] + m[8]*r.m[6];
678        p.m[7] = m[6]*r.m[1] + m[7]*r.m[4] + m[8]*r.m[7];
679        p.m[8] = m[6]*r.m[2] + m[7]*r.m[5] + m[8]*r.m[8];
680       
681        return p;
682}
683
684
685/**
686   \brief rotates the vector by the given rotation
687   \param v: a vector
688   \param r: a rotation
689   \return the rotated vector
690*/
691Vector rotateVector( const Vector& v, const Rotation& r)
692{
693  Vector t;
694 
695  t.x = v.x * r.m[0] + v.y * r.m[1] + v.z * r.m[2];
696  t.y = v.x * r.m[3] + v.y * r.m[4] + v.z * r.m[5];
697  t.z = v.x * r.m[6] + v.y * r.m[7] + v.z * r.m[8];
698
699  return t;
700}
701
702/**
703   \brief calculate the distance between two lines
704   \param l: the other line
705   \return the distance between the lines
706*/
707float Line::distance (const Line& l) const
708{
709  float q, d;
710  Vector n = a.cross(l.a);
711  q = n.dot(r-l.r);
712  d = n.len();
713  if( d == 0.0) return 0.0;
714  return q/d;
715}
716
717/**
718   \brief calculate the distance between a line and a point
719   \param v: the point
720   \return the distance between the Line and the point
721*/
722float Line::distancePoint (const Vector& v) const
723{
724  Vector d = v-r;
725  Vector u = a * d.dot( a);
726  return (d - u).len();
727}
728
729/**
730   \brief calculate the two points of minimal distance of two lines
731   \param l: the other line
732   \return a Vector[2] (!has to be deleted after use!) containing the two points of minimal distance
733*/
734Vector* Line::footpoints (const Line& l) const
735{
736  Vector* fp = new Vector[2];
737  Plane p = Plane (r + a.cross(l.a), r, r + a);
738  fp[1] = p.intersectLine (l);
739  p = Plane (fp[1], l.a);
740  fp[0] = p.intersectLine (*this);
741  return fp;
742}
743
744/**
745  \brief calculate the length of a line
746  \return the lenght of the line
747*/
748float Line::len() const
749{
750  return a.len();
751}
752
753/**
754   \brief rotate the line by given rotation
755   \param rot: a rotation
756*/
757void Line::rotate (const Rotation& rot)
758{
759  Vector t = a + r;
760  t = rotateVector( t, rot);
761  r = rotateVector( r, rot),
762  a = t - r;
763}
764
765/**
766   \brief create a plane from three points
767   \param a: first point
768   \param b: second point
769   \param c: third point
770*/
771Plane::Plane (Vector a, Vector b, Vector c)
772{
773  n = (a-b).cross(c-b);
774  k = -(n.x*b.x+n.y*b.y+n.z*b.z);
775}
776
777/**
778   \brief create a plane from anchor point and normal
779   \param norm: normal vector
780   \param p: anchor point
781*/
782Plane::Plane (Vector norm, Vector p)
783{
784  n = norm;
785  k = -(n.x*p.x+n.y*p.y+n.z*p.z);
786}
787
788/**
789   \brief returns the intersection point between the plane and a line
790   \param l: a line
791*/
792Vector Plane::intersectLine (const Line& l) const
793{
794  if (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z == 0.0) return Vector(0,0,0);
795  float t = (n.x*l.r.x+n.y*l.r.y+n.z*l.r.z+k) / (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z);
796  return l.r + (l.a * t);
797}
798
799/**
800   \brief returns the distance between the plane and a point
801   \param p: a Point
802   \return the distance between the plane and the point (can be negative)
803*/
804float Plane::distancePoint (const Vector& p) const
805{
806  float l = n.len();
807  if( l == 0.0) return 0.0;
808  return (n.dot(p) + k) / n.len();
809}
810
811/**
812   \brief returns the side a point is located relative to a Plane
813   \param p: a Point
814   \return 0 if the point is contained within the Plane, positive(negative) if the point is in the positive(negative) semi-space of the Plane
815*/
816float Plane::locatePoint (const Vector& p) const
817{
818  return (n.dot(p) + k);
819}
820
Note: See TracBrowser for help on using the repository browser.