CellModules
vector3D.h
Go to the documentation of this file.
1#ifndef MECACELL_VECTOR3D_H
2#define MECACELL_VECTOR3D_H
3
4#include <array>
5#include <cmath>
6#include <functional>
7#include <iostream>
8#include "../utilities/config.hpp"
9#include "../utilities/exportable.hpp"
10#include "../utilities/utils.hpp"
11#include "basis.hpp"
12#include "quaternion.h"
13#include "rotation.h"
14
15namespace MecaCell {
16
20class Vector3D {
21 public:
22 std::array<double, 3> coords;
23
24 static const int dimension = 3;
25 inline Vector3D(double a, double b, double c) : coords{{a, b, c}} {}
26 //template <typename T>
27 //Vector3D(const T &otherV) : coords{{otherV.x(), otherV.y(), otherV.z()}} {}
28 inline Vector3D() : coords{{0, 0, 0}} {}
29 inline explicit Vector3D(double a) : coords{{a, a, a}} {}
30 inline explicit Vector3D(std::array<double, 3> c) : coords(c) {}
31 inline Vector3D(const Vector3D &v) : coords(v.coords) {}
32 inline Vector3D(Vector3D &&v) : coords(std::move(v.coords)) {}
33
41 Vector3D &operator=(const Vector3D &other) {
42 if (&other == this) return *this;
43 coords = other.coords;
44 return *this;
45 }
46
54 inline double dot(const Vector3D &v) const {
55 return coords[0] * v.coords[0] + coords[1] * v.coords[1] + coords[2] * v.coords[2];
56 }
57
65 inline const Vector3D cross(const Vector3D &v) const {
66 return Vector3D(coords[1] * v.coords[2] - coords[2] * v.coords[1],
67 coords[2] * v.coords[0] - coords[0] * v.coords[2],
68 coords[0] * v.coords[1] - coords[1] * v.coords[0]);
69 }
70
76 inline double &xRef() { return coords[0]; }
82 inline double &yRef() { return coords[1]; }
88 inline double &zRef() { return coords[2]; }
94 inline double x() const { return coords[0]; }
100 inline double y() const { return coords[1]; }
106 inline double z() const { return coords[2]; }
107
113 inline void setX(const double f) { coords[0] = f; }
119 inline void setY(const double f) { coords[1] = f; }
125 inline void setZ(const double f) { coords[2] = f; }
126
131 void random() {
132 std::normal_distribution<double> nDist(0.0, 1.0);
133 coords = {{nDist(Config::globalRand()), nDist(Config::globalRand()),
134 nDist(Config::globalRand())}};
135 normalize();
136 }
137
144 static inline Vector3D randomUnit() {
145 Vector3D v;
146 v.random();
147 return v;
148 }
149
157 Vector3D deltaDirection(double amount) {
158 std::normal_distribution<double> nDist(0.0, amount);
159 return Vector3D(coords[0] + nDist(Config::globalRand()),
160 coords[1] + nDist(Config::globalRand()),
161 coords[2] + nDist(Config::globalRand()))
162 .normalized();
163 }
164
170 static inline Vector3D zero() { return Vector3D(0.0, 0.0, 0.0); }
171
177 inline bool isZero() const {
178 return (coords[0] == 0.0 && coords[1] == 0.0 && coords[2] == 0.0);
179 }
180
188 inline Vector3D &operator*=(double d) {
189 coords[0] *= d;
190 coords[1] *= d;
191 coords[2] *= d;
192 return *this;
193 };
194
202 inline Vector3D &operator/=(double d) {
203 coords[0] /= d;
204 coords[1] /= d;
205 coords[2] /= d;
206 return *this;
207 };
208
216 inline Vector3D &operator+=(const Vector3D &v) {
217 coords[0] += v.coords[0];
218 coords[1] += v.coords[1];
219 coords[2] += v.coords[2];
220 return *this;
221 }
222
230 inline Vector3D &operator-=(const Vector3D &v) {
231 coords[0] -= v.coords[0];
232 coords[1] -= v.coords[1];
233 coords[2] -= v.coords[2];
234 return *this;
235 }
236
237 friend inline bool operator==(const Vector3D &v1, const Vector3D &v2);
238 friend inline bool operator!=(const Vector3D &v1, const Vector3D &v2);
239 friend inline Vector3D operator+(const Vector3D &v1, const Vector3D &v2);
240 friend inline Vector3D operator+(const Vector3D &v1, double f);
241 friend inline Vector3D operator+(double f, const Vector3D &v1);
242 friend inline Vector3D operator-(const Vector3D &v1, const Vector3D &v2);
243 friend inline Vector3D operator-(const Vector3D &v1, double f);
244 friend inline Vector3D operator-(double f, const Vector3D &v1);
245 friend inline Vector3D operator*(double factor, const Vector3D &vector);
246 friend inline Vector3D operator*(const Vector3D &vector, double factor);
247 friend inline Vector3D operator*(const Vector3D &v1, const Vector3D &v2);
248 friend inline Vector3D operator-(const Vector3D &vector);
249 friend inline Vector3D operator/(const Vector3D &vector, double divisor);
250 friend inline ostream &operator<<(ostream &out, const Vector3D &v);
251
257 double length() const {
258 return sqrt(coords[0] * coords[0] + coords[1] * coords[1] + coords[2] * coords[2]);
259 }
265 double sqlength() const {
266 return coords[0] * coords[0] + coords[1] * coords[1] + coords[2] * coords[2];
267 }
268
277 Vector3D rotated(double angle, const Vector3D &vec) const {
278 double halfangle = angle * 0.5;
279 Vector3D v = vec * sin(halfangle);
280 Vector3D vcV = 2.0 * v.cross(*this);
281 return *this + cos(halfangle) * vcV + v.cross(vcV);
282 }
283
292 double halfangle = r.teta * 0.5;
293 Vector3D v = r.n * sin(halfangle);
294 Vector3D vcV = 2.0 * v.cross(*this);
295 return *this + cos(halfangle) * vcV + v.cross(vcV);
296 }
297
306 double dTeta = v.length();
307 Vector3D n0(0, 1, 0);
308 if (dTeta > 0) {
309 n0 = v / dTeta;
310 }
311 r = addRotations(r, Rotation<Vector3D>(n0, dTeta));
312 }
313
322 static Rotation<Vector3D> getRotation(const Vector3D &v0, const Vector3D &v1) {
324 res.teta = acos(min<double>(1.0, max<double>(-1.0, v0.dot(v1))));
325 Vector3D cross = v0.cross(v1);
326 if (cross.sqlength() == 0) {
327 cross = Vector3D(0, 1, 0);
328 }
329 res.n = cross.normalized();
330 return res;
331 }
332
346 static double rayCast(const Vector3D &o, const Vector3D &n, const Vector3D &p,
347 const Vector3D &r) {
348 double nr = n.dot(r);
349 return (nr == 0) ? 0 : n.dot(o - p) / nr;
350 }
351
363 const Vector3D &p) {
364 return p - (n.dot(p - o) * n);
365 }
366
376 const Rotation<Vector3D> &offset) {
377 return Rotation<Vector3D>(start.n.rotated(offset), start.teta);
378 }
388 const Rotation<Vector3D> &R1) {
389 auto q2 = Quaternion<Vector3D>(R1.teta, R1.n) * Quaternion<Vector3D>(R0.teta, R0.n);
390 q2.normalize();
391 return q2.toAxisAngle();
392 }
393
404 static Rotation<Vector3D> getRotation(const Vector3D &X0, const Vector3D &Y0,
405 const Vector3D &X1, const Vector3D &Y1) {
407 Vector3D Ytmp = q0 * Y0;
408 Ytmp.normalize();
409 auto qres = Quaternion<Vector3D>(Ytmp, Y1.normalized()) * q0;
410 qres.normalize();
411 return qres.toAxisAngle();
412 }
424 const Basis<Vector3D> &b1) {
425 return getRotation(b0.X, b0.Y, b1.X, b1.Y);
426 }
427
437 static Vector3D getProjection(const Vector3D &A, const Vector3D &B, const Vector3D &P) {
438 Vector3D a = B - A;
439 return A + a * (a.dot(P - A) / a.sqlength());
440 }
441
445 void normalize() { *this /= length(); }
446
452 inline Vector3D normalized() const {
453 double l = length();
454 return l > 0 ? *this / l : zero();
455 }
456
457 std::string toString() const {
458 std::stringstream s;
459 s.precision(500);
460 s << "(" << coords[0] << " , " << coords[1] << ", " << coords[2] << ")";
461 return s.str();
462 }
471 inline int getHash(const int a, const int b) const {
472 unsigned int A = (unsigned int)(a >= 0 ? 2 * a : -2 * a - 1);
473 unsigned int B = (unsigned int)(b >= 0 ? 2 * b : -2 * b - 1);
474 int C = ((A >= B ? A * A + A + B : A + B * B) / 2);
475 return (a < 0 && b < 0) || (a >= 0 && b >= 0) ? C : -C - 1;
476 }
477
483 int getHash() const {
484 return getHash(
485 static_cast<int>(floor(coords[0])),
486 getHash(static_cast<int>(floor(coords[1])), static_cast<int>(floor(coords[2]))));
487 }
488
498 inline void iterateTo(const Vector3D &v,
499 const std::function<void(const Vector3D &)> &fun,
500 const double inc = 1) const {
501 Vector3D base(floor(min(coords[0], v.coords[0])), floor(min(coords[1], v.coords[1])),
502 floor(min(coords[2], v.coords[2])));
503 Vector3D nxt(ceil(max(coords[0], v.coords[0])), ceil(max(coords[1], v.coords[1])),
504 ceil(max(coords[2], v.coords[2])));
505 for (auto i = base.x(); i <= nxt.x(); i += inc) {
506 for (auto j = base.y(); j <= nxt.y(); j += inc) {
507 for (auto k = base.z(); k <= nxt.z(); k += inc) {
508 fun(Vector3D(i, j, k));
509 }
510 }
511 }
512 }
513
519 Vector3D ortho() const {
520 if (coords[1] == 0 && coords[0] == 0) {
521 return Vector3D(0.0, 1.0, 0.0);
522 }
523 return Vector3D(-coords[1], coords[0], 0.0);
524 }
525
526 Vector3D ortho(const Vector3D &v) const {
527 if ((v - *this).sqlength() > 0.000000000001) {
528 Vector3D res = cross(v);
529 if (res.sqlength() > 0.0000000000001) return res;
530 }
531 return ortho();
532 }
533
535};
536
537inline bool operator==(const Vector3D &v1, const Vector3D &v2) {
538 return v1.coords[0] == v2.coords[0] && v1.coords[1] == v2.coords[1] &&
539 v1.coords[2] == v2.coords[2];
540}
541inline bool operator!=(const Vector3D &v1, const Vector3D &v2) {
542 return v1.coords[0] != v2.coords[0] && v1.coords[1] != v2.coords[1] &&
543 v1.coords[2] != v2.coords[2];
544}
545
546inline Vector3D operator+(const Vector3D &v1, const Vector3D &v2) {
547 return Vector3D(v1.coords[0] + v2.coords[0], v1.coords[1] + v2.coords[1],
548 v1.coords[2] + v2.coords[2]);
549}
550inline Vector3D operator+(const double f, const Vector3D &v) {
551 return Vector3D(v.coords[0] + f, v.coords[1] + f, v.coords[2] + f);
552}
553inline Vector3D operator+(const Vector3D &v, const double f) {
554 return Vector3D(v.coords[0] + f, v.coords[1] + f, v.coords[2] + f);
555}
556
557inline Vector3D operator-(const Vector3D &v1, const Vector3D &v2) {
558 return Vector3D(v1.coords[0] - v2.coords[0], v1.coords[1] - v2.coords[1],
559 v1.coords[2] - v2.coords[2]);
560}
561inline Vector3D operator*(const Vector3D &v1, const Vector3D &v2) {
562 return Vector3D(v1.coords[0] * v2.coords[0], v1.coords[1] * v2.coords[1],
563 v1.coords[2] * v2.coords[2]);
564}
565
566inline Vector3D operator*(const double f, const Vector3D &v) {
567 return Vector3D(v.coords[0] * f, v.coords[1] * f, v.coords[2] * f);
568}
569inline Vector3D operator*(const Vector3D &v, const double f) {
570 return Vector3D(v.coords[0] * f, v.coords[1] * f, v.coords[2] * f);
571}
572
573inline Vector3D operator-(const double f, const Vector3D &v) {
574 return Vector3D(v.coords[0] - f, v.coords[1] - f, v.coords[2] - f);
575}
576inline Vector3D operator-(const Vector3D &v, const double f) {
577 return Vector3D(v.coords[0] - f, v.coords[1] - f, v.coords[2] - f);
578}
579
580inline Vector3D operator-(const Vector3D &v) {
581 return Vector3D(-v.coords[0], -v.coords[1], -v.coords[2]);
582}
583
584inline Vector3D operator/(const Vector3D &v, const double f) {
585 return Vector3D(v.coords[0] / f, v.coords[1] / f, v.coords[2] / f);
586}
587inline ostream &operator<<(ostream &out, const Vector3D &v) {
588 out << "(" << v.coords[0] << ", " << v.coords[1] << ", " << v.coords[2] << ")";
589 return out;
590}
591} // namespace MecaCell
592namespace std {
593template <> struct hash<MecaCell::Vector3D> {
594 int operator()(const MecaCell::Vector3D &v) const { return v.getHash(); }
595};
596} // namespace std
597#endif // VECTOR3D_H
general purpose 3D vector/point class.
Definition: vector3D.h:20
void random()
sets the current vector as a random normalized one. Uniform direction distribution on all directions ...
Definition: vector3D.h:131
Vector3D & operator/=(double d)
scalar division operator
Definition: vector3D.h:202
Vector3D & operator*=(double d)
scalar multiplication operator
Definition: vector3D.h:188
double x() const
Definition: vector3D.h:94
static Vector3D getProjectionOnPlane(const Vector3D &o, const Vector3D &n, const Vector3D &p)
project a point on a plane
Definition: vector3D.h:362
double & yRef()
Definition: vector3D.h:82
double y() const
Definition: vector3D.h:100
Vector3D & operator=(const Vector3D &other)
assignment operator for copy constructing a vector
Definition: vector3D.h:41
static void addAsAngularVelocity(const Vector3D &v, Rotation< Vector3D > &r)
adds a vector representing an angular Velocity (or any rotation coded on only one vector) to an exist...
Definition: vector3D.h:305
double length() const
compute the length of the vector
Definition: vector3D.h:257
static Vector3D getProjection(const Vector3D &A, const Vector3D &B, const Vector3D &P)
computes the orthogonal projection of a point onto a segment AB
Definition: vector3D.h:437
static const int dimension
Definition: vector3D.h:24
static Rotation< Vector3D > getRotation(const Vector3D &v0, const Vector3D &v1)
computes the rotation from one vector to another
Definition: vector3D.h:322
std::array< double, 3 > coords
Definition: vector3D.h:22
Vector3D(std::array< double, 3 > c)
Definition: vector3D.h:30
Vector3D rotated(const Rotation< Vector3D > &r) const
gives a rotated copy of the current vector
Definition: vector3D.h:291
Vector3D(Vector3D &&v)
Definition: vector3D.h:32
Vector3D(const Vector3D &v)
Definition: vector3D.h:31
int getHash() const
fast hash method
Definition: vector3D.h:483
void setX(const double f)
setter for x coordinate
Definition: vector3D.h:113
double sqlength() const
compute the square length of the current vector (faster than length)
Definition: vector3D.h:265
static Vector3D zero()
constructs a zero vector
Definition: vector3D.h:170
Vector3D(double a)
Definition: vector3D.h:29
Vector3D ortho() const
deterministic generation of an orthogonal vector
Definition: vector3D.h:519
void setY(const double f)
setter for y coordinate
Definition: vector3D.h:119
Vector3D rotated(double angle, const Vector3D &vec) const
gives a rotated copy of the current vector
Definition: vector3D.h:277
Vector3D & operator-=(const Vector3D &v)
substract operator
Definition: vector3D.h:230
void setZ(const double f)
setter for z coordinate
Definition: vector3D.h:125
static Rotation< Vector3D > rotateRotation(const Rotation< Vector3D > &start, const Rotation< Vector3D > &offset)
rotates the axis of rotation of a rotation
Definition: vector3D.h:375
static Rotation< Vector3D > getRotation(const Vector3D &X0, const Vector3D &Y0, const Vector3D &X1, const Vector3D &Y1)
computes the rotation transform from basis X0,Y0 to X1,Y1
Definition: vector3D.h:404
static double rayCast(const Vector3D &o, const Vector3D &n, const Vector3D &p, const Vector3D &r)
simple raycasting on a plane
Definition: vector3D.h:346
Vector3D & operator+=(const Vector3D &v)
addition operator
Definition: vector3D.h:216
double z() const
Definition: vector3D.h:106
int getHash(const int a, const int b) const
fast hash for two ints
Definition: vector3D.h:471
const Vector3D cross(const Vector3D &v) const
cross product calculation
Definition: vector3D.h:65
Vector3D ortho(const Vector3D &v) const
Definition: vector3D.h:526
static Rotation< Vector3D > getRotation(const Basis< Vector3D > &b0, const Basis< Vector3D > &b1)
computes the rotation transform from basis b0 to b1
Definition: vector3D.h:423
double dot(const Vector3D &v) const
dot product calculation
Definition: vector3D.h:54
void normalize()
normalizes the vector
Definition: vector3D.h:445
static Vector3D randomUnit()
creates a random normalized vector. Uniform direction distribution on all directions of a sphere.
Definition: vector3D.h:144
double & zRef()
Definition: vector3D.h:88
Vector3D(double a, double b, double c)
Definition: vector3D.h:25
bool isZero() const
returns true if all vector coordinates are equal to zero
Definition: vector3D.h:177
EXPORTABLE(Vector3D, KV(coords))
Vector3D normalized() const
returns a normalized copy of the current vector
Definition: vector3D.h:452
double & xRef()
Definition: vector3D.h:76
std::string toString() const
Definition: vector3D.h:457
Vector3D deltaDirection(double amount)
returns a vector randomly tilted relatively to the original one
Definition: vector3D.h:157
static Rotation< Vector3D > addRotations(const Rotation< Vector3D > &R0, const Rotation< Vector3D > &R1)
adds two rotations
Definition: vector3D.h:387
void iterateTo(const Vector3D &v, const std::function< void(const Vector3D &)> &fun, const double inc=1) const
helper method to iterates over a 3D rectangular cuboid bounded by two corner vectors
Definition: vector3D.h:498
A simple vector class template.
Definition: std.hpp:324
#define KV(p)
Definition: exportable.hpp:30
this file contains various miscellanious utility functions & helpers *
Vector3D operator/(const Vector3D &v, const double f)
Definition: vector3D.h:584
bool operator!=(const Vector3D &v1, const Vector3D &v2)
Definition: vector3D.h:541
Vector3D operator*(const Vector3D &v, const double f)
Definition: vector3D.h:569
Vector3D operator-(const Vector3D &v)
Definition: vector3D.h:580
ostream & operator<<(ostream &out, const Vector3D &v)
Definition: vector3D.h:587
Vector3D operator+(const Vector3D &v, const double f)
Definition: vector3D.h:553
bool operator==(const Vector3D &v1, const Vector3D &v2)
Definition: vector3D.h:537
Provides common mathematical functions and vector operations.
Definition: std.hpp:4
double floor(double x)
Computes the floor of a number.
Definition: std.hpp:194
double acos(double x)
Computes the arc cosine of a number.
Definition: std.hpp:113
double sin(double x)
Computes the sine of a number.
Definition: std.hpp:53
double sqrt(double x)
Computes the square root of a number.
Definition: std.hpp:32
double max(double a, double b)
Computes the maximum of two numbers.
Definition: std.hpp:280
double min(double a, double b)
Computes the minimum of two numbers.
Definition: std.hpp:291
double ceil(double x)
Computes the ceiling of a number.
Definition: std.hpp:184
double cos(double x)
Computes the cosine of a number.
Definition: std.hpp:63
def normalize(text)
Definition: viewer.py:89
int operator()(const MecaCell::Vector3D &v) const
Definition: vector3D.h:594