Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/resources/src/lib/math/plane.cc @ 8091

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

trunk: split Rotation/Line/Quaternion/Plane(Rectangle) into seperate files

File size: 7.9 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 *  calculate the two points of minimal distance of two lines
226 * @param l: the other line
227 * @return a Vector[2] (!has to be deleted after use!) containing the two points of minimal distance
228*/
229Vector* Line::footpoints (const Line& l) const
230{
231  Vector* fp = new Vector[2];
232  Plane p = Plane (r + a.cross(l.a), r, r + a);
233  fp[1] = p.intersectLine (l);
234  p = Plane (fp[1], l.a);
235  fp[0] = p.intersectLine (*this);
236  return fp;
237}
238
239/**
240  \brief calculate the length of a line
241  \return the lenght of the line
242*/
243float Line::len() const
244{
245  return a.len();
246}
247
248/**
249 *  rotate the line by given rotation
250 * @param rot: a rotation
251*/
252void Line::rotate (const Rotation& rot)
253{
254  Vector t = a + r;
255  t = rotateVector( t, rot);
256  r = rotateVector( r, rot),
257  a = t - r;
258}
259
260/**
261 *  create a plane from three points
262 * @param a: first point
263 * @param b: second point
264 * @param c: third point
265*/
266Plane::Plane (const Vector& a, const Vector& b, const Vector& c)
267{
268  n = (a-b).cross(c-b);
269  k = -(n.x*b.x+n.y*b.y+n.z*b.z);
270}
271
272/**
273 *  create a plane from anchor point and normal
274 * @param norm: normal vector
275 * @param p: anchor point
276*/
277Plane::Plane (const Vector& norm, const Vector& p)
278{
279  n = norm;
280  k = -(n.x*p.x+n.y*p.y+n.z*p.z);
281}
282
283
284/**
285  *  create a plane from anchor point and normal
286  * @param norm: normal vector
287  * @param p: anchor point
288*/
289Plane::Plane (const Vector& norm, const sVec3D& g)
290{
291  Vector p(g[0], g[1], g[2]);
292  n = norm;
293  k = -(n.x*p.x+n.y*p.y+n.z*p.z);
294}
295
296
297/**
298 *  returns the intersection point between the plane and a line
299 * @param l: a line
300*/
301Vector Plane::intersectLine (const Line& l) const
302{
303  if (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z == 0.0) return Vector(0,0,0);
304  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);
305  return l.r + (l.a * t);
306}
307
308/**
309 *  returns the distance between the plane and a point
310 * @param p: a Point
311 * @return the distance between the plane and the point (can be negative)
312*/
313float Plane::distancePoint (const Vector& p) const
314{
315  float l = n.len();
316  if( l == 0.0) return 0.0;
317  return (n.dot(p) + k) / n.len();
318}
319
320
321/**
322 *  returns the distance between the plane and a point
323 * @param p: a Point
324 * @return the distance between the plane and the point (can be negative)
325 */
326float Plane::distancePoint (const sVec3D& p) const
327{
328  Vector s(p[0], p[1], p[2]);
329  float l = n.len();
330  if( l == 0.0) return 0.0;
331  return (n.dot(s) + k) / n.len();
332}
333
334
335/**
336 *  returns the side a point is located relative to a Plane
337 * @param p: a Point
338 * @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
339*/
340float Plane::locatePoint (const Vector& p) const
341{
342  return (n.dot(p) + k);
343}
344
Note: See TracBrowser for help on using the repository browser.