Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/chris/src/vector.cc @ 2080

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

orxonox/branches/chris: Implemented basic track and spawning functionality. Added a function to convert a Rotation into a glmatrix. Implemented operator* in Rotation. Refined World, made World friend class of world_entity. Implemented camera functionality (can now be bound to the worldentity it should focus on).

File size: 9.4 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 fills the specified buffer with a 4x4 glmatrix
269   \param buffer: Pointer to an array of 16 floats
270   
271   Use this to get the rotation in a gl-compatible format
272*/
273void Rotation::glmatrix (float* buffer)
274{
275        buffer[0] = m[0];
276        buffer[1] = m[3];
277        buffer[2] = m[6];
278        buffer[3] = m[0];
279        buffer[4] = m[1];
280        buffer[5] = m[4];
281        buffer[6] = m[7];
282        buffer[7] = m[0];
283        buffer[8] = m[2];
284        buffer[9] = m[5];
285        buffer[10] = m[8];
286        buffer[11] = m[0];
287        buffer[12] = m[0];
288        buffer[13] = m[0];
289        buffer[14] = m[0];
290        buffer[15] = m[1];
291}
292
293/**
294   \brief multiplies two rotational matrices
295   \param r: another Rotation
296   \return the matrix product of the Rotations
297   
298   Use this to rotate one rotation by another
299*/
300Rotation Rotation::operator* (Rotation& r)
301{
302        Rotation p();
303       
304        p[0] = m[0]*r.m[0] + m[1]*r.m[3] + m[2]*r.m[6];
305        p[1] = m[0]*r.m[1] + m[1]*r.m[4] + m[2]*r.m[7];
306        p[2] = m[0]*r.m[2] + m[1]*r.m[5] + m[2]*r.m[8];
307       
308        p[3] = m[3]*r.m[0] + m[4]*r.m[3] + m[5]*r.m[6];
309        p[4] = m[3]*r.m[1] + m[4]*r.m[4] + m[5]*r.m[7];
310        p[5] = m[3]*r.m[2] + m[4]*r.m[5] + m[5]*r.m[8];
311
312        p[6] = m[6]*r.m[0] + m[7]*r.m[3] + m[8]*r.m[6];
313        p[7] = m[6]*r.m[1] + m[7]*r.m[4] + m[8]*r.m[7];
314        p[8] = m[6]*r.m[2] + m[7]*r.m[5] + m[8]*r.m[8];
315       
316        return p;
317}
318
319
320/**
321   \brief rotates the vector by the given rotation
322   \param v: a vector
323   \param r: a rotation
324   \return the rotated vector
325*/
326Vector rotate_vector( const Vector& v, const Rotation& r)
327{
328  Vector t;
329 
330  t.x = v.x * r.m[0] + v.y * r.m[1] + v.z * r.m[2];
331  t.y = v.x * r.m[3] + v.y * r.m[4] + v.z * r.m[5];
332  t.z = v.x * r.m[6] + v.y * r.m[7] + v.z * r.m[8];
333
334  return t;
335}
336
337/**
338   \brief calculate the distance between two lines
339   \param l: the other line
340   \return the distance between the lines
341*/
342float Line::distance (const Line& l) const
343{
344  float q, d;
345  Vector n = a.cross(l.a);
346  q = n.dot(r-l.r);
347  d = n.len();
348  if( d == 0.0) return 0.0;
349  return q/d;
350}
351
352/**
353   \brief calculate the distance between a line and a point
354   \param v: the point
355   \return the distance between the Line and the point
356*/
357float Line::distance_point (const Vector& v) const
358{
359  Vector d = v-r;
360  Vector u = a * d.dot( a);
361  return (d - u).len();
362}
363
364/**
365   \brief calculate the two points of minimal distance of two lines
366   \param l: the other line
367   \return a Vector[2] (!has to be deleted after use!) containing the two points of minimal distance
368*/
369Vector* Line::footpoints (const Line& l) const
370{
371  Vector* fp = new Vector[2];
372  Plane p = Plane (r + a.cross(l.a), r, r + a);
373  fp[1] = p.intersect_line (l);
374  p = Plane (fp[1], l.a);
375  fp[0] = p.intersect_line (*this);
376  return fp;
377}
378
379/**
380  \brief calculate the length of a line
381  \return the lenght of the line
382*/
383float Line::len() const
384{
385  return a.len();
386}
387
388/**
389   \brief rotate the line by given rotation
390   \param rot: a rotation
391*/
392void Line::rotate (const Rotation& rot)
393{
394  Vector t = a + r;
395  t = rotate_vector( t, rot);
396  r = rotate_vector( r, rot),
397  a = t - r;
398}
399
400/**
401   \brief create a plane from three points
402   \param a: first point
403   \param b: second point
404   \param c: third point
405*/
406Plane::Plane (Vector a, Vector b, Vector c)
407{
408  n = (a-b).cross(c-b);
409  k = -(n.x*b.x+n.y*b.y+n.z*b.z);
410}
411
412/**
413   \brief create a plane from anchor point and normal
414   \param n: normal vector
415   \param p: anchor point
416*/
417Plane::Plane (Vector norm, Vector p)
418{
419  n = norm;
420  k = -(n.x*p.x+n.y*p.y+n.z*p.z);
421}
422
423/**
424   \brief returns the intersection point between the plane and a line
425   \param l: a line
426*/
427Vector Plane::intersect_line (const Line& l) const
428{
429  if (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z == 0.0) return Vector(0,0,0);
430  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);
431  return l.r + (l.a * t);
432}
433
434/**
435   \brief returns the distance between the plane and a point
436   \param p: a Point
437   \return the distance between the plane and the point (can be negative)
438*/
439float Plane::distance_point (const Vector& p) const
440{
441  float l = n.len();
442  if( l == 0.0) return 0.0;
443  return (n.dot(p) + k) / n.len();
444}
445
446/**
447   \brief returns the side a point is located relative to a Plane
448   \param p: a Point
449   \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
450*/
451float Plane::locate_point (const Vector& p) const
452{
453  return (n.dot(p) + k);
454}
Note: See TracBrowser for help on using the repository browser.