Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/math/vector.cc @ 3824

Last change on this file since 3824 was 3824, checked in by patrick, 19 years ago

orxonox/trunk: redefined quaternion multiplication. it was more efficient as it was. reverted.

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