Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: vector inline function definitions

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