Colobot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
vector.h
Go to the documentation of this file.
1 // * This file is part of the COLOBOT source code
2 // * Copyright (C) 2012, Polish Portal of Colobot (PPC)
3 // *
4 // * This program is free software: you can redistribute it and/or modify
5 // * it under the terms of the GNU General Public License as published by
6 // * the Free Software Foundation, either version 3 of the License, or
7 // * (at your option) any later version.
8 // *
9 // * This program is distributed in the hope that it will be useful,
10 // * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // * GNU General Public License for more details.
13 // *
14 // * You should have received a copy of the GNU General Public License
15 // * along with this program. If not, see http://www.gnu.org/licenses/.
16 
22 #pragma once
23 
24 
25 #include "math/const.h"
26 #include "math/func.h"
27 
28 
29 #include <cmath>
30 #include <sstream>
31 
32 
33 // Math module namespace
34 namespace Math {
35 
36 
49 struct Vector
50 {
52  float x;
54  float y;
56  float z;
57 
59  inline Vector()
60  : x(0.0f)
61  , y(0.0f)
62  , z(0.0f)
63  {}
64 
66  inline explicit Vector(float _x, float _y, float _z)
67  : x(_x)
68  , y(_y)
69  , z(_z)
70  {}
71 
73  inline void LoadZero()
74  {
75  x = y = z = 0.0f;
76  }
77 
79  inline float* Array()
80  {
81  return reinterpret_cast<float*>(this);
82  }
83 
85  inline const float* Array() const
86  {
87  return reinterpret_cast<const float*>(this);
88  }
89 
91  inline float Length() const
92  {
93  return sqrtf(x*x + y*y + z*z);
94  }
95 
97  inline void Normalize()
98  {
99  float l = Length();
100  if (IsZero(l))
101  return;
102 
103  x /= l;
104  y /= l;
105  z /= l;
106  }
107 
109 
113  inline Vector CrossMultiply(const Vector &right) const
114  {
115  float px = y * right.z - z * right.y;
116  float py = z * right.x - x * right.z;
117  float pz = x * right.y - y * right.x;
118  return Vector(px, py, pz);
119  }
120 
122 
126  inline float DotMultiply(const Vector &right) const
127  {
128  return x * right.x + y * right.y + z * right.z;
129  }
130 
132  inline float CosAngle(const Vector &right) const
133  {
134  return DotMultiply(right) / (Length() * right.Length());
135  }
136 
138  inline float Angle(const Vector &right) const
139  {
140  return acos(CosAngle(right));
141  }
142 
143 
144  /* Operators */
145 
147  inline Vector operator-() const
148  {
149  return Vector(-x, -y, -z);
150  }
151 
153  inline const Vector& operator+=(const Vector &right)
154  {
155  x += right.x;
156  y += right.y;
157  z += right.z;
158  return *this;
159  }
160 
162  inline friend const Vector operator+(const Vector &left, const Vector &right)
163  {
164  return Vector(left.x + right.x, left.y + right.y, left.z + right.z);
165  }
166 
168  inline const Vector& operator-=(const Vector &right)
169  {
170  x -= right.x;
171  y -= right.y;
172  z -= right.z;
173  return *this;
174  }
175 
177  inline friend const Vector operator-(const Vector &left, const Vector &right)
178  {
179  return Vector(left.x - right.x, left.y - right.y, left.z - right.z);
180  }
181 
183  inline const Vector& operator*=(const float &right)
184  {
185  x *= right;
186  y *= right;
187  z *= right;
188  return *this;
189  }
190 
192  inline friend const Vector operator*(const float &left, const Vector &right)
193  {
194  return Vector(left * right.x, left * right.y, left * right.z);
195  }
196 
198  inline friend const Vector operator*(const Vector &left, const float &right)
199  {
200  return Vector(left.x * right, left.y * right, left.z * right);
201  }
202 
204  inline const Vector& operator/=(const float &right)
205  {
206  x /= right;
207  y /= right;
208  z /= right;
209  return *this;
210  }
211 
213  inline friend const Vector operator/(const Vector &left, const float &right)
214  {
215  return Vector(left.x / right, left.y / right, left.z / right);
216  }
217 
218 
220  inline std::string ToString() const
221  {
222  std::stringstream s;
223  s.precision(3);
224  s << "[" << x << ", " << y << ", " << z << "]";
225  return s.str();
226  }
227 
228 }; // struct Vector
229 
231 inline bool VectorsEqual(const Math::Vector &a, const Math::Vector &b, float tolerance = TOLERANCE)
232 {
233  return IsEqual(a.x, b.x, tolerance)
234  && IsEqual(a.y, b.y, tolerance)
235  && IsEqual(a.z, b.z, tolerance);
236 }
237 
239 inline Vector Normalize(const Math::Vector &v)
240 {
241  Vector result = v;
242  result.Normalize();
243  return result;
244 }
245 
247 inline float DotProduct(const Math::Vector &left, const Math::Vector &right)
248 {
249  return left.DotMultiply(right);
250 }
251 
253 inline Vector CrossProduct(const Math::Vector &left, const Math::Vector &right)
254 {
255  return left.CrossMultiply(right);
256 }
257 
259 inline float Angle(const Math::Vector &a, const Math::Vector &b)
260 {
261  return a.Angle(b);
262 }
263 
265 inline float Distance(const Math::Vector &a, const Math::Vector &b)
266 {
267  return sqrtf( (a.x-b.x)*(a.x-b.x) +
268  (a.y-b.y)*(a.y-b.y) +
269  (a.z-b.z)*(a.z-b.z) );
270 }
271 
273 inline Vector Clamp(const Vector &vec, const Vector &min, const Vector &max)
274 {
275  Vector clamped;
276  clamped.x = Min(Max(min.x, vec.x), max.x);
277  clamped.y = Min(Max(min.y, vec.y), max.y);
278  clamped.z = Min(Max(min.z, vec.z), max.z);
279  return clamped;
280 }
281 
282 
283 } // namespace Math
284