Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: most important often used functions inlined

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*/
187Quaternion::Quaternion ()
188{
189        w = 1;
190        v = Vector(0,0,0);
191}
192
193/**
194        \brief turns a rotation along an axis into a Quaternion
195        \param angle: the amount of radians to rotate
196        \param axis: the axis to rotate around
197*/
198Quaternion::Quaternion (float angle, const Vector& axis)
199{
200        w = cos(angle/2);
201        v = axis * sin(angle/2);
202}
203
204/**
205   \brief calculates a lookAt rotation
206   \param dir: the direction you want to look
207   \param up: specify what direction up should be
208   
209   Mathematically this determines the rotation a (0,0,1)-Vector has to undergo to point
210   the same way as dir. If you want to use this with cameras, you'll have to reverse the
211   dir Vector (Vector(0,0,0) - your viewing direction) or you'll point the wrong way. You
212   can use this for meshes as well (then you do not have to reverse the vector), but keep
213   in mind that if you do that, the model's front has to point in +z direction, and left
214   and right should be -x or +x respectively or the mesh wont rotate correctly.
215*/
216Quaternion::Quaternion (const Vector& dir, const Vector& up)
217{
218  Vector z = dir;
219  z.normalize(); 
220  Vector x = up.cross(z);
221  x.normalize(); 
222  Vector y = z.cross(x);
223 
224  float m[4][4];
225  m[0][0] = x.x;
226  m[0][1] = x.y;
227  m[0][2] = x.z;
228  m[0][3] = 0;
229  m[1][0] = y.x;
230  m[1][1] = y.y;
231  m[1][2] = y.z;
232  m[1][3] = 0;
233  m[2][0] = z.x;
234  m[2][1] = z.y;
235  m[2][2] = z.z;
236  m[2][3] = 0;
237  m[3][0] = 0;
238  m[3][1] = 0;
239  m[3][2] = 0;
240  m[3][3] = 1;
241 
242  *this = Quaternion (m);
243}
244
245/**
246        \brief calculates a rotation from euler angles
247        \param roll: the roll in radians
248        \param pitch: the pitch in radians
249        \param yaw: the yaw in radians
250       
251        I DO HONESTLY NOT EXACTLY KNOW WHICH ANGLE REPRESENTS WHICH ROTATION. And I do not know
252        in what order they are applied, I just copy-pasted the code.
253*/
254Quaternion::Quaternion (float roll, float pitch, float yaw)
255{
256        float cr, cp, cy, sr, sp, sy, cpcy, spsy;
257       
258        // calculate trig identities
259        cr = cos(roll/2);
260        cp = cos(pitch/2);
261        cy = cos(yaw/2);
262       
263        sr = sin(roll/2);
264        sp = sin(pitch/2);
265        sy = sin(yaw/2);
266       
267        cpcy = cp * cy;
268        spsy = sp * sy;
269       
270        w = cr * cpcy + sr * spsy;
271        v.x = sr * cpcy - cr * spsy;
272        v.y = cr * sp * cy + sr * cp * sy;
273        v.z = cr * cp * sy - sr * sp * cy;
274}
275
276/**
277        \brief rotates one Quaternion by another
278        \param q: another Quaternion to rotate this by
279        \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))
280*/
281Quaternion Quaternion::operator*(const Quaternion& q) const
282{
283        float A, B, C, D, E, F, G, H;
284        Quaternion r;
285       
286        A = (w   + v.x)*(q.w   + q.v.x);
287        B = (v.z - v.y)*(q.v.y - q.v.z);
288        C = (w   - v.x)*(q.v.y + q.v.z); 
289        D = (v.y + v.z)*(q.w   - q.v.x);
290        E = (v.x + v.z)*(q.v.x + q.v.y);
291        F = (v.x - v.z)*(q.v.x - q.v.y);
292        G = (w   + v.y)*(q.w   - q.v.z);
293        H = (w   - v.y)*(q.w   + q.v.z);
294       
295        r.w = B +  (-E - F + G + H)/2;
296        r.v.x = A - (E + F + G + H)/2; 
297        r.v.y = C + (E - F + G - H)/2; 
298        r.v.z = D + (E - F - G + H)/2;
299       
300        return r;
301}
302
303/**
304        \brief add two Quaternions
305        \param q: another Quaternion
306        \return the sum of both Quaternions
307*/
308Quaternion Quaternion::operator+(const Quaternion& q) const
309{
310  Quaternion r(*this);
311  r.w = r.w + q.w;
312  r.v = r.v + q.v;
313  return r;
314}
315
316/**
317   \brief subtract two Quaternions
318   \param q: another Quaternion
319   \return the difference of both Quaternions
320*/
321Quaternion Quaternion::operator- (const Quaternion& q) const
322{
323  Quaternion r(*this);
324  r.w = r.w - q.w;
325  r.v = r.v - q.v;
326  return r;
327}
328
329/**
330   \brief rotate a Vector by a Quaternion
331   \param v: the Vector
332   \return a new Vector representing v rotated by the Quaternion
333*/
334Vector Quaternion::apply (Vector& v) const
335{
336  Quaternion q;
337  q.v = v;
338  q.w = 0;
339  q = *this * q * conjugate();
340  return q.v;
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*/
374Quaternion Quaternion::conjugate() const
375{
376  Quaternion r(*this);
377  r.v = Vector() - r.v;
378  return r;
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.