Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: inlined more functions and fixed a compile error

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