Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

trunk: merged the cd branche back to trunk

File size: 8.2 KB
Line 
1/*
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:
12   main-programmer: Christian Meyer
13   co-programmer: Patrick Boenzli
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
17
18#include "plane.h"
19#ifdef DEBUG
20  #include "debug.h"
21#else
22  #include <stdio.h>
23  #define PRINT(x) printf
24#endif
25
26using namespace std;
27
28/**
29 *  create a rotation from a vector
30 * @param v: a vector
31*/
32Rotation::Rotation (const Vector& v)
33{
34  Vector x = Vector( 1, 0, 0);
35  Vector axis = x.cross( v);
36  axis.normalize();
37  float angle = angleRad( x, v);
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/**
52 *  creates a rotation from an axis and an angle (radians!)
53 * @param axis: the rotational axis
54 * @param angle: the angle in radians
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/**
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)
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/**
99 *  creates a nullrotation (an identity rotation)
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/**
115 *  fills the specified buffer with a 4x4 glmatrix
116 * @param buffer: Pointer to an array of 16 floats
117
118   Use this to get the rotation in a gl-compatible format
119*/
120void Rotation::glmatrix (float* buffer)
121{
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];
138}
139
140/**
141 *  multiplies two rotational matrices
142 * @param r: another Rotation
143 * @return the matrix product of the Rotations
144
145   Use this to rotate one rotation by another
146*/
147Rotation Rotation::operator* (const Rotation& r)
148{
149        Rotation p;
150
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;
164}
165
166
167/**
168 *  rotates the vector by the given rotation
169 * @param v: a vector
170 * @param r: a rotation
171 * @return the rotated vector
172*/
173Vector rotateVector( const Vector& v, const Rotation& r)
174{
175  Vector t;
176
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/**
185 *  calculate the distance between two lines
186 * @param l: the other line
187 * @return the distance between the lines
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/**
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
203*/
204float Line::distancePoint (const Vector& v) const
205{
206  Vector d = v-r;
207  Vector u = a * d.dot( a);
208  return (d - u).len();
209}
210
211/**
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
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
224
225/**
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
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);
234  fp[1] = p.intersectLine (l);
235  p = Plane (fp[1], l.a);
236  fp[0] = p.intersectLine (*this);
237  return fp;
238}
239
240/**
241  \brief calculate the length of a line
242  \return the lenght of the line
243*/
244float Line::len() const
245{
246  return a.len();
247}
248
249/**
250 *  rotate the line by given rotation
251 * @param rot: a rotation
252*/
253void Line::rotate (const Rotation& rot)
254{
255  Vector t = a + r;
256  t = rotateVector( t, rot);
257  r = rotateVector( r, rot),
258  a = t - r;
259}
260
261/**
262 *  create a plane from three points
263 * @param a: first point
264 * @param b: second point
265 * @param c: third point
266*/
267Plane::Plane (const Vector& a, const Vector& b, const Vector& c)
268{
269  n = (a-b).cross(c-b);
270  k = n.dot(a) / n.len();
271}
272
273/**
274 *  create a plane from anchor point and normal
275 * @param norm: normal vector
276 * @param p: anchor point
277*/
278Plane::Plane (const Vector& norm, const Vector& p)
279{
280  n = norm;
281  k = n.dot(p) / n.len();
282}
283
284
285/**
286  *  create a plane from anchor point and normal
287  * @param norm: normal vector
288  * @param p: anchor point
289*/
290Plane::Plane (const Vector& norm, const sVec3D& g)
291{
292  Vector p(g[0], g[1], g[2]);
293  n = norm;
294  k = n.dot(p) / n.len();
295}
296
297
298/**
299 *  returns the intersection point between the plane and a line
300 * @param l: a line
301*/
302Vector Plane::intersectLine (const Line& l) const
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/**
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)
313*/
314float Plane::distancePoint (const Vector& p) const
315{
316  float l = n.len();
317  if( l == 0.0) return 0.0;
318  return (n.dot(p) / n.len() - k);
319}
320
321
322/**
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)
326 */
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
342{
343  Vector s(p[0], p[1], p[2]);
344
345  float l = n.len();
346  if( l == 0.0) return 0.0;
347  return (n.dot(s) / n.len() - k);
348}
349
350
351/**
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
355*/
356float Plane::locatePoint (const Vector& p) const
357{
358  return (n.dot(p) + k);
359}
360
Note: See TracBrowser for help on using the repository browser.