Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/math/plane.cc @ 9027

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

trunk: merged the cd branche back to trunk

File size: 8.2 KB
RevLine 
[4578]1/*
[2043]2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
[4578]12   main-programmer: Christian Meyer
[6617]13   co-programmer: Patrick Boenzli
[2043]14*/
15
[3590]16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
[2043]17
[6617]18#include "plane.h"
[5662]19#ifdef DEBUG
[5672]20  #include "debug.h"
[5662]21#else
[5672]22  #include <stdio.h>
23  #define PRINT(x) printf
[5662]24#endif
[2043]25
26using namespace std;
27
28/**
[4836]29 *  create a rotation from a vector
30 * @param v: a vector
[2043]31*/
32Rotation::Rotation (const Vector& v)
33{
34  Vector x = Vector( 1, 0, 0);
35  Vector axis = x.cross( v);
36  axis.normalize();
[3234]37  float angle = angleRad( x, v);
[2043]38  float ca = cos(angle);
39  float sa = sin(angle);
40  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
41  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
42  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
43  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
44  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
45  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
46  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
47  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
48  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
49}
50
51/**
[4836]52 *  creates a rotation from an axis and an angle (radians!)
53 * @param axis: the rotational axis
54 * @param angle: the angle in radians
[2043]55*/
56Rotation::Rotation (const Vector& axis, float angle)
57{
58  float ca, sa;
59  ca = cos(angle);
60  sa = sin(angle);
61  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
62  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
63  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
64  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
65  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
66  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
67  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
68  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
69  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
70}
71
72/**
[4836]73 *  creates a rotation from euler angles (pitch/yaw/roll)
74 * @param pitch: rotation around z (in radians)
75 * @param yaw: rotation around y (in radians)
76 * @param roll: rotation around x (in radians)
[2043]77*/
78Rotation::Rotation ( float pitch, float yaw, float roll)
79{
80  float cy, sy, cr, sr, cp, sp;
81  cy = cos(yaw);
82  sy = sin(yaw);
83  cr = cos(roll);
84  sr = sin(roll);
85  cp = cos(pitch);
86  sp = sin(pitch);
87  m[0] = cy*cr;
88  m[1] = -cy*sr;
89  m[2] = sy;
90  m[3] = cp*sr+sp*sy*cr;
91  m[4] = cp*cr-sp*sr*sy;
92  m[5] = -sp*cy;
93  m[6] = sp*sr-cp*sy*cr;
94  m[7] = sp*cr+cp*sy*sr;
95  m[8] = cp*cy;
96}
97
98/**
[4836]99 *  creates a nullrotation (an identity rotation)
[2043]100*/
101Rotation::Rotation ()
102{
103  m[0] = 1.0f;
104  m[1] = 0.0f;
105  m[2] = 0.0f;
106  m[3] = 0.0f;
107  m[4] = 1.0f;
108  m[5] = 0.0f;
109  m[6] = 0.0f;
110  m[7] = 0.0f;
111  m[8] = 1.0f;
112}
113
114/**
[4836]115 *  fills the specified buffer with a 4x4 glmatrix
116 * @param buffer: Pointer to an array of 16 floats
[4578]117
[2190]118   Use this to get the rotation in a gl-compatible format
119*/
120void Rotation::glmatrix (float* buffer)
121{
[4578]122        buffer[0] = m[0];
123        buffer[1] = m[3];
124        buffer[2] = m[6];
125        buffer[3] = m[0];
126        buffer[4] = m[1];
127        buffer[5] = m[4];
128        buffer[6] = m[7];
129        buffer[7] = m[0];
130        buffer[8] = m[2];
131        buffer[9] = m[5];
132        buffer[10] = m[8];
133        buffer[11] = m[0];
134        buffer[12] = m[0];
135        buffer[13] = m[0];
136        buffer[14] = m[0];
137        buffer[15] = m[1];
[2190]138}
139
140/**
[4836]141 *  multiplies two rotational matrices
142 * @param r: another Rotation
143 * @return the matrix product of the Rotations
[4578]144
[2190]145   Use this to rotate one rotation by another
146*/
147Rotation Rotation::operator* (const Rotation& r)
148{
[4578]149        Rotation p;
[2190]150
[4578]151        p.m[0] = m[0]*r.m[0] + m[1]*r.m[3] + m[2]*r.m[6];
152        p.m[1] = m[0]*r.m[1] + m[1]*r.m[4] + m[2]*r.m[7];
153        p.m[2] = m[0]*r.m[2] + m[1]*r.m[5] + m[2]*r.m[8];
154
155        p.m[3] = m[3]*r.m[0] + m[4]*r.m[3] + m[5]*r.m[6];
156        p.m[4] = m[3]*r.m[1] + m[4]*r.m[4] + m[5]*r.m[7];
157        p.m[5] = m[3]*r.m[2] + m[4]*r.m[5] + m[5]*r.m[8];
158
159        p.m[6] = m[6]*r.m[0] + m[7]*r.m[3] + m[8]*r.m[6];
160        p.m[7] = m[6]*r.m[1] + m[7]*r.m[4] + m[8]*r.m[7];
161        p.m[8] = m[6]*r.m[2] + m[7]*r.m[5] + m[8]*r.m[8];
162
163        return p;
[2190]164}
165
166
167/**
[4836]168 *  rotates the vector by the given rotation
169 * @param v: a vector
170 * @param r: a rotation
171 * @return the rotated vector
[2043]172*/
[3228]173Vector rotateVector( const Vector& v, const Rotation& r)
[2043]174{
175  Vector t;
[4578]176
[2043]177  t.x = v.x * r.m[0] + v.y * r.m[1] + v.z * r.m[2];
178  t.y = v.x * r.m[3] + v.y * r.m[4] + v.z * r.m[5];
179  t.z = v.x * r.m[6] + v.y * r.m[7] + v.z * r.m[8];
180
181  return t;
182}
183
184/**
[4836]185 *  calculate the distance between two lines
186 * @param l: the other line
187 * @return the distance between the lines
[2043]188*/
189float Line::distance (const Line& l) const
190{
191  float q, d;
192  Vector n = a.cross(l.a);
193  q = n.dot(r-l.r);
194  d = n.len();
195  if( d == 0.0) return 0.0;
196  return q/d;
197}
198
199/**
[4836]200 *  calculate the distance between a line and a point
201 * @param v: the point
202 * @return the distance between the Line and the point
[2043]203*/
[3228]204float Line::distancePoint (const Vector& v) const
[2043]205{
206  Vector d = v-r;
207  Vector u = a * d.dot( a);
208  return (d - u).len();
209}
210
211/**
[4836]212 *  calculate the distance between a line and a point
213 * @param v: the point
214 * @return the distance between the Line and the point
[4578]215 */
216float Line::distancePoint (const sVec3D& v) const
217{
218  Vector s(v[0], v[1], v[2]);
219  Vector d = s - r;
220  Vector u = a * d.dot( a);
221  return (d - u).len();
222}
223
[7711]224
[4578]225/**
[4836]226 *  calculate the two points of minimal distance of two lines
227 * @param l: the other line
228 * @return a Vector[2] (!has to be deleted after use!) containing the two points of minimal distance
[2043]229*/
230Vector* Line::footpoints (const Line& l) const
231{
232  Vector* fp = new Vector[2];
233  Plane p = Plane (r + a.cross(l.a), r, r + a);
[3234]234  fp[1] = p.intersectLine (l);
[2043]235  p = Plane (fp[1], l.a);
[3234]236  fp[0] = p.intersectLine (*this);
[2043]237  return fp;
238}
239
240/**
241  \brief calculate the length of a line
[4578]242  \return the lenght of the line
[2043]243*/
244float Line::len() const
245{
246  return a.len();
247}
248
249/**
[4836]250 *  rotate the line by given rotation
251 * @param rot: a rotation
[2043]252*/
253void Line::rotate (const Rotation& rot)
254{
255  Vector t = a + r;
[3234]256  t = rotateVector( t, rot);
257  r = rotateVector( r, rot),
[2043]258  a = t - r;
259}
260
261/**
[4836]262 *  create a plane from three points
263 * @param a: first point
264 * @param b: second point
265 * @param c: third point
[2043]266*/
[5688]267Plane::Plane (const Vector& a, const Vector& b, const Vector& c)
[2043]268{
269  n = (a-b).cross(c-b);
[7711]270  k = n.dot(a) / n.len();
[2043]271}
272
273/**
[4836]274 *  create a plane from anchor point and normal
275 * @param norm: normal vector
276 * @param p: anchor point
[2043]277*/
[5688]278Plane::Plane (const Vector& norm, const Vector& p)
[2043]279{
280  n = norm;
[7711]281  k = n.dot(p) / n.len();
[2043]282}
283
[4611]284
[2043]285/**
[4836]286  *  create a plane from anchor point and normal
287  * @param norm: normal vector
288  * @param p: anchor point
[4611]289*/
[5688]290Plane::Plane (const Vector& norm, const sVec3D& g)
[4611]291{
292  Vector p(g[0], g[1], g[2]);
293  n = norm;
[7711]294  k = n.dot(p) / n.len();
[4611]295}
296
297
298/**
[4836]299 *  returns the intersection point between the plane and a line
300 * @param l: a line
[2043]301*/
[3228]302Vector Plane::intersectLine (const Line& l) const
[2043]303{
304  if (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z == 0.0) return Vector(0,0,0);
305  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);
306  return l.r + (l.a * t);
307}
308
309/**
[4836]310 *  returns the distance between the plane and a point
311 * @param p: a Point
312 * @return the distance between the plane and the point (can be negative)
[2043]313*/
[3228]314float Plane::distancePoint (const Vector& p) const
[2043]315{
316  float l = n.len();
317  if( l == 0.0) return 0.0;
[7711]318  return (n.dot(p) / n.len() - k);
[2043]319}
320
[4585]321
[2043]322/**
[4836]323 *  returns the distance between the plane and a point
324 * @param p: a Point
325 * @return the distance between the plane and the point (can be negative)
[4585]326 */
[7711]327// float Plane::distancePoint (const sVec3D& p) const
328// {
329//   Vector s(p[0], p[1], p[2]);
330//   float l = n.len();
331//   if( l == 0.0) return 0.0;
332//   return (n.dot(s) + k) / n.len();
333// }
334
335
336/**
337 *  returns the distance between the plane and a point
338 * @param p: a Point
339 * @return the distance between the plane and the point (can be negative)
340 */
341float Plane::distancePoint (const float* p) const
[4585]342{
343  Vector s(p[0], p[1], p[2]);
[7711]344
[4585]345  float l = n.len();
346  if( l == 0.0) return 0.0;
[7711]347  return (n.dot(s) / n.len() - k);
[4585]348}
349
350
351/**
[4836]352 *  returns the side a point is located relative to a Plane
353 * @param p: a Point
354 * @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
[2043]355*/
[3228]356float Plane::locatePoint (const Vector& p) const
[2043]357{
358  return (n.dot(p) + k);
359}
[3000]360
Note: See TracBrowser for help on using the repository browser.