Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3541 was 3541, checked in by bensch, 19 years ago

orxonox/trunk: debug information for class vector and quaternion

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