Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

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

File size: 7.9 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
224/**
[4836]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
[2043]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);
[3234]233  fp[1] = p.intersectLine (l);
[2043]234  p = Plane (fp[1], l.a);
[3234]235  fp[0] = p.intersectLine (*this);
[2043]236  return fp;
237}
238
239/**
240  \brief calculate the length of a line
[4578]241  \return the lenght of the line
[2043]242*/
243float Line::len() const
244{
245  return a.len();
246}
247
248/**
[4836]249 *  rotate the line by given rotation
250 * @param rot: a rotation
[2043]251*/
252void Line::rotate (const Rotation& rot)
253{
254  Vector t = a + r;
[3234]255  t = rotateVector( t, rot);
256  r = rotateVector( r, rot),
[2043]257  a = t - r;
258}
259
260/**
[4836]261 *  create a plane from three points
262 * @param a: first point
263 * @param b: second point
264 * @param c: third point
[2043]265*/
[5688]266Plane::Plane (const Vector& a, const Vector& b, const Vector& c)
[2043]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/**
[4836]273 *  create a plane from anchor point and normal
274 * @param norm: normal vector
275 * @param p: anchor point
[2043]276*/
[5688]277Plane::Plane (const Vector& norm, const Vector& p)
[2043]278{
279  n = norm;
280  k = -(n.x*p.x+n.y*p.y+n.z*p.z);
281}
282
[4611]283
[2043]284/**
[4836]285  *  create a plane from anchor point and normal
286  * @param norm: normal vector
287  * @param p: anchor point
[4611]288*/
[5688]289Plane::Plane (const Vector& norm, const sVec3D& g)
[4611]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/**
[4836]298 *  returns the intersection point between the plane and a line
299 * @param l: a line
[2043]300*/
[3228]301Vector Plane::intersectLine (const Line& l) const
[2043]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/**
[4836]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)
[2043]312*/
[3228]313float Plane::distancePoint (const Vector& p) const
[2043]314{
315  float l = n.len();
316  if( l == 0.0) return 0.0;
317  return (n.dot(p) + k) / n.len();
318}
319
[4585]320
[2043]321/**
[4836]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)
[4585]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/**
[4836]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
[2043]339*/
[3228]340float Plane::locatePoint (const Vector& p) const
[2043]341{
342  return (n.dot(p) + k);
343}
[3000]344
Note: See TracBrowser for help on using the repository browser.