Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/chris/core/vector.cc @ 1981

Last change on this file since 1981 was 1981, checked in by chris, 20 years ago

orxonox/branches/chris: added doxygen-optimized comments

File size: 8.2 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: ...
16*/
17
18
19#include "vector.h"
20
21
22using namespace std;
23
24/**
25   \brief add two vectors
26   \param v: the other vector
27   \return the sum of both vectors
28*/
29Vector Vector::operator+ (const Vector& v) const
30{
31  Vector r;
32 
33  r.x = x + v.x;
34  r.y = y + v.y;
35  r.z = z + v.z;
36 
37  return r;
38}
39
40/**
41   \brief subtract a vector from another
42   \param v: the other vector
43   \return the difference between the vectors
44*/
45Vector Vector::operator- (const Vector& v) const
46{
47  Vector r;
48 
49  r.x = x - v.x;
50  r.y = y - v.y;
51  r.z = z - v.z;
52 
53  return r;
54}
55
56/**
57   \brief calculate the dot product of two vectors
58   \param v: the other vector
59   \return the dot product of the vectors
60*/
61float Vector::operator* (const Vector& v) const
62{
63  return x*v.x+y*v.y+z*v.z;
64}
65
66/**
67   \brief multiply a vector with a float
68   \param f: the factor
69   \return the vector multipied by f
70*/
71Vector Vector::operator* (float f) const
72{ 
73  Vector r;
74 
75  r.x = x * f;
76  r.y = y * f;
77  r.z = z * f;
78 
79  return r;
80}
81
82/**
83   \brief divide a vector with a float
84   \param f: the divisor
85   \return the vector divided by f   
86*/
87Vector Vector::operator/ (float f) const
88{
89  Vector r;
90 
91  if( f == 0.0)
92  {
93    // Prevent divide by zero
94    return Vector (0,0,0);
95  }
96 
97  r.x = x / f;
98  r.y = y / f;
99  r.z = z / f;
100 
101  return r;
102}
103
104/**
105   \brief calculate the dot product of two vectors
106   \param v: the other vector
107   \return the dot product of the vectors
108*/
109float Vector::dot (const Vector& v) const
110{
111  return x*v.x+y*v.y+z*v.z;
112}
113
114/**
115  \brief calculate the cross product of two vectors
116  \param v: the other vector
117        \return the cross product of the vectors
118*/
119Vector Vector::cross (const Vector& v) const
120{
121  Vector r;
122 
123  r.x = y * v.z - z * v.y;
124  r.y = z * v.x - x * v.z;
125  r.z = x * v.y - y * v.x;
126 
127  return r;
128}
129 
130/**
131   \brief normalizes the vector to lenght 1.0
132*/
133void Vector::normalize ()
134{
135  float l = len();
136 
137  if( l == 0.0)
138  {
139    // Prevent divide by zero
140    return;
141  }
142 
143  x = x / l;
144  y = y / l;
145  z = z / l;
146}
147 
148/**
149   \brief calculates the lenght of the vector
150   \return the lenght of the vector
151*/
152float Vector::len () const
153{
154  return sqrt (x*x+y*y+z*z);
155}
156
157/**
158   \brief calculate the angle between two vectors in radiances
159   \param v1: a vector
160   \param v2: another vector
161   \return the angle between the vectors in radians
162*/
163float angle_rad (const Vector& v1, const Vector& v2)
164{
165  return acos( v1 * v2 / (v1.len() * v2.len()));
166}
167
168/**
169   \brief calculate the angle between two vectors in degrees
170   \param v1: a vector
171   \param v2: another vector
172   \return the angle between the vectors in degrees
173*/
174float angle_deg (const Vector& v1, const Vector& v2)
175{
176  float f;
177  f = acos( v1 * v2 / (v1.len() * v2.len()));
178  return f * 180 / PI;
179}
180
181/**
182   \brief create a rotation from a vector
183   \param v: a vector
184*/
185Rotation::Rotation (const Vector& v)
186{
187  Vector x = Vector( 1, 0, 0);
188  Vector axis = x.cross( v);
189  axis.normalize();
190  float angle = angle_rad( x, v);
191  float ca = cos(angle);
192  float sa = sin(angle);
193  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
194  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
195  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
196  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
197  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
198  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
199  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
200  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
201  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
202}
203
204/**
205   \brief creates a rotation from an axis and an angle (radians!)
206   \param axis: the rotational axis
207   \param angle: the angle in radians
208*/
209Rotation::Rotation (const Vector& axis, float angle)
210{
211  float ca, sa;
212  ca = cos(angle);
213  sa = sin(angle);
214  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
215  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
216  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
217  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
218  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
219  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
220  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
221  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
222  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
223}
224
225/**
226   \brief creates a rotation from euler angles (pitch/yaw/roll)
227   \param pitch: rotation around z (in radians)
228   \param yaw: rotation around y (in radians)
229   \param roll: rotation around x (in radians)
230*/
231Rotation::Rotation ( float pitch, float yaw, float roll)
232{
233  float cy, sy, cr, sr, cp, sp;
234  cy = cos(yaw);
235  sy = sin(yaw);
236  cr = cos(roll);
237  sr = sin(roll);
238  cp = cos(pitch);
239  sp = sin(pitch);
240  m[0] = cy*cr;
241  m[1] = -cy*sr;
242  m[2] = sy;
243  m[3] = cp*sr+sp*sy*cr;
244  m[4] = cp*cr-sp*sr*sy;
245  m[5] = -sp*cy;
246  m[6] = sp*sr-cp*sy*cr;
247  m[7] = sp*cr+cp*sy*sr;
248  m[8] = cp*cy;
249}
250
251/**
252   \brief creates a nullrotation (an identity rotation)
253*/
254Rotation::Rotation ()
255{
256  m[0] = 1.0f;
257  m[1] = 0.0f;
258  m[2] = 0.0f;
259  m[3] = 0.0f;
260  m[4] = 1.0f;
261  m[5] = 0.0f;
262  m[6] = 0.0f;
263  m[7] = 0.0f;
264  m[8] = 1.0f;
265}
266
267/**
268   \brief rotates the vector by the given rotation
269   \param v: a vector
270   \param r: a rotation
271   \return the rotated vector
272*/
273Vector rotate_vector( const Vector& v, const Rotation& r)
274{
275  Vector t;
276 
277  t.x = v.x * r.m[0] + v.y * r.m[1] + v.z * r.m[2];
278  t.y = v.x * r.m[3] + v.y * r.m[4] + v.z * r.m[5];
279  t.z = v.x * r.m[6] + v.y * r.m[7] + v.z * r.m[8];
280
281  return t;
282}
283
284/**
285   \brief calculate the distance between two lines
286   \param l: the other line
287   \return the distance between the lines
288*/
289float Line::distance (const Line& l) const
290{
291  float q, d;
292  Vector n = a.cross(l.a);
293  q = n.dot(r-l.r);
294  d = n.len();
295  if( d == 0.0) return 0.0;
296  return q/d;
297}
298
299/**
300   \brief calculate the distance between a line and a point
301   \param v: the point
302   \return the distance between the Line and the point
303*/
304float Line::distance_point (const Vector& v) const
305{
306  Vector d = v-r;
307  Vector u = a * d.dot( a);
308  return (d - u).len();
309}
310
311/**
312   \brief calculate the two points of minimal distance of two lines
313   \param l: the other line
314   \return a Vector[2] (!has to be deleted after use!) containing the two points of minimal distance
315*/
316Vector* Line::footpoints (const Line& l) const
317{
318  Vector* fp = new Vector[2];
319  Plane p = Plane (r + a.cross(l.a), r, r + a);
320  fp[1] = p.intersect_line (l);
321  p = Plane (fp[1], l.a);
322  fp[0] = p.intersect_line (*this);
323  return fp;
324}
325
326/**
327  \brief calculate the length of a line
328  \return the lenght of the line
329*/
330float Line::len() const
331{
332  return a.len();
333}
334
335/**
336   \brief rotate the line by given rotation
337   \param rot: a rotation
338*/
339void Line::rotate (const Rotation& rot)
340{
341  Vector t = a + r;
342  t = rotate_vector( t, rot);
343  r = rotate_vector( r, rot),
344  a = t - r;
345}
346
347/**
348   \brief create a plane from three points
349   \param a: first point
350   \param b: second point
351   \param c: third point
352*/
353Plane::Plane (Vector a, Vector b, Vector c)
354{
355  n = (a-b).cross(c-b);
356  k = -(n.x*b.x+n.y*b.y+n.z*b.z);
357}
358
359/**
360   \brief create a plane from anchor point and normal
361   \param n: normal vector
362   \param p: anchor point
363*/
364Plane::Plane (Vector norm, Vector p)
365{
366  n = norm;
367  k = -(n.x*p.x+n.y*p.y+n.z*p.z);
368}
369
370/**
371   \brief returns the intersection point between the plane and a line
372   \param l: a line
373*/
374Vector Plane::intersect_line (const Line& l) const
375{
376  if (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z == 0.0) return Vector(0,0,0);
377  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);
378  return l.r + (l.a * t);
379}
380
381/**
382   \brief returns the distance between the plane and a point
383   \param p: a Point
384   \return the distance between the plane and the point (can be negative)
385*/
386float Plane::distance_point (const Vector& p) const
387{
388  float l = n.len();
389  if( l == 0.0) return 0.0;
390  return (n.dot(p) + k) / n.len();
391}
392
393/**
394   \brief returns the side a point is located relative to a Plane
395   \param p: a Point
396   \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
397*/
398float Plane::locate_point (const Vector& p) const
399{
400  return (n.dot(p) + k);
401}
Note: See TracBrowser for help on using the repository browser.