LibreCAD
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
geocoordinate.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "cad/const.h"
4 #include <cmath>
5 #include <iostream>
6 
7 namespace lc {
8  namespace geo {
12  class Coordinate {
13  public:
14  explicit Coordinate() : _x(0.), _y(0.), _z(0.) {}
15  Coordinate(double x, double y, double z) : _x(x), _y(y), _z(z) {}
16  Coordinate(double x, double y) : _x(x), _y(y), _z(0.) {}
17  explicit Coordinate(double angle) : _x(std::cos(angle)), _y(std::sin(angle)), _z(0.) {}
18  Coordinate(Coordinate &&c) noexcept : _x(c._x), _y(c._y), _z(c._z) {}
19  Coordinate(const Coordinate &c) : _x(c._x), _y(c._y), _z(c._z) {}
20 
21 
26  inline double x() const {
27  return _x;
28  }
29 
34  inline double y() const {
35  return _y;
36  }
37 
42  inline double z() const {
43  return _z;
44  }
45 
46 
47  inline Coordinate& operator = (const Coordinate& coord) {
48  if (this != &coord) {
49  _x = coord._x;
50  _y = coord._y;
51  _z = coord._z;
52  }
53 
54  return *this;
55  }
56 
57  /*
58  void operator = (Coordinate&& coord) {
59  _x = coord._x;
60  _y = coord._y;
61  _z = coord._z;
62  }*/
63 
68  Coordinate flipXY() const {
69  return Coordinate(this->y(), this->x(), this->z());
70  }
71 
77  double angleTo(const Coordinate& v) const {
78  return (v - (*this)).angle();
79  }
80 
85  double angleBetween(const Coordinate& v1, const Coordinate& v2) const;
86 
92  inline bool operator==(const Coordinate& coord) const {
93  return this->_x == coord._x && this->_y == coord._y && this->_z == coord._z;
94  }
95 
96  inline bool operator!=(const Coordinate& coord) const {
97  return this->_x != coord._x || this->_y != coord._y || this->_z != coord._z;
98  }
99 
104  inline double distanceTo(const geo::Coordinate& c) const {
105  return (*this - c).magnitude();
106  }
107 
112  inline Coordinate operator + (const Coordinate& coord) const {
113  return Coordinate(_x + coord._x, _y + coord._y, _z + coord._z);
114  }
115 
121  inline Coordinate operator + (double d) const {
122  return Coordinate(_x + d, _y + d, _z + d);
123  }
124 
130  inline Coordinate operator - (double d) const {
131  return Coordinate(_x - d, _y - d, _z - d);
132  }
133 
139  inline Coordinate operator - () const {
140  return Coordinate(-_x, -_y, -_z);
141  }
142 
147  inline Coordinate operator - (const Coordinate& coord) const {
148  return Coordinate(_x - coord._x, _y - coord._y, _z - coord._z);
149  }
150 
157  inline Coordinate operator * (const Coordinate& coord) const {
158  return Coordinate(_x * coord._x, _y * coord._y, _z * coord._z);
159  }
160 
161  inline Coordinate operator * (double s) const {
162  return Coordinate(_x * s, _y * s, _z * s);
163  }
170  inline Coordinate operator / (double s) const {
171  return Coordinate(_x / s, _y / s, _z / s);
172  }
173 
179  inline double magnitude() const {
180  return std::sqrt(_x * _x + _y * _y + _z * _z);
181  }
182 
183  inline double angle() const {
184  return std::atan2(_y, _x);
185  }
186 
187 
193  inline double squared() const {
194  return _x * _x + _y * _y + _z * _z;
195  }
196 
203  inline double dot(const Coordinate& coord) const {
204  return _x * coord._x + _y * coord._y + _z * coord._z;
205  }
206 
207  inline double dot(const Coordinate& v1, const Coordinate& v2) const {
208  return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z();
209  }
210 
217  inline Coordinate rotate(const Coordinate& angleVector) const {
218  double x0 = _x * angleVector.x() - _y * angleVector.y();
219  double y0 = _x * angleVector.y() + _y * angleVector.x();
220  return Coordinate(x0, y0);
221  }
222 
229  inline Coordinate rotate(const double& angle) const {
230  return rotate(Coordinate(angle));
231  }
232 
240  inline Coordinate rotate(const geo::Coordinate& point, const Coordinate& angleVector) const {
241  return point + (*this - point).rotate(angleVector);
242  }
243 
251  inline Coordinate rotate(const geo::Coordinate& point, const double& angle) const {
252  return rotate(point, Coordinate(angle));
253  }
254 
263  inline Coordinate rotateByArcLength(const geo::Coordinate& point, double const length) const {
264  double const angle = (length / point.distanceTo(*this));
265  return rotate(point, Coordinate(angle));
266  }
267 
271  inline Coordinate scale(const double& scale_factor) const {
272  return Coordinate(_x * scale_factor, _y * scale_factor);
273  }
274 
278  inline Coordinate scale(const Coordinate& scale_factor) const {
279  return Coordinate(_x * scale_factor.x(), _y * scale_factor.y());
280  }
281 
285  inline Coordinate scale(const Coordinate& scale_center, const Coordinate& scale_factor) const {
286  return scale_center + ((*this - scale_center) * scale_factor);
287  }
288 
292  inline Coordinate mid(const Coordinate& other) const {
293  return (other - *this) / 2. + *this;
294  }
298  inline Coordinate norm() const {
299  auto m = magnitude();
300  return Coordinate(_x / m, _y / m, _z / m);
301  }
302 
307  inline Coordinate norm(const double f) const {
308  auto m = magnitude() / f;
309  return Coordinate(_x / m, _y / m, _z / m);
310  }
311 
315  inline Coordinate move(const Coordinate& direction, double d) const {
316  return direction.norm() * d + *this;
317  }
318 
322  inline Coordinate moveTo(const Coordinate& to, double d) const {
323  return (to - *this).norm() * d + *this;
324  }
325 
332  inline Coordinate transform2d(double xx, double yx, double xy, double yy, double x0, double y0) {
333  return Coordinate(xx * _x + xy * _y + x0, yx * _x + yy * _y + y0, _z);
334  }
335 
342  inline Coordinate mirror(const Coordinate& axis1, const Coordinate& axis2) const {
343  Coordinate dir(axis2 - axis1);
344  auto a= dir.squared();
345  auto ret= axis1 + dir* dot(*this- axis1, dir)/a; //projection point
346  return ret + ret - *this;
347  }
348 
349  private:
350  friend std::ostream& operator<<(std::ostream& os, const Coordinate& coordinate) {
351  os << "Coordinate(x=" << coordinate._x << " y=" << coordinate._y << " z=" << coordinate._z << ")";
352  return os;
353  }
354 
355  private:
356  double _x;
357  double _y;
358  double _z;
359  };
360 
375  CoordinateDistanceSort(const Coordinate& distanceFrom) : _distanceFrom(distanceFrom) {
376  }
377 
378  bool operator()(const Coordinate& left, const Coordinate& right) const {
379  return left.distanceTo(_distanceFrom) < right.distanceTo(_distanceFrom);
380  }
381 
383  };
384 
385  }
386 }
387 
double squared() const
Coordinate mirror(const Coordinate &axis1, const Coordinate &axis2) const
mirror a coordinate
Coordinate moveTo(const Coordinate &to, double d) const
Coordinate mid(const Coordinate &other) const
bool operator()(const Coordinate &left, const Coordinate &right) const
Coordinate scale(const Coordinate &scale_center, const Coordinate &scale_factor) const
bool operator!=(const Coordinate &coord) const
Definition: geocoordinate.h:96
double x() const
Returns x of Coordinate.
Definition: geocoordinate.h:26
Coordinate flipXY() const
flips the x and y of Coordinate
Definition: geocoordinate.h:68
double angleTo(const Coordinate &v) const
Returns angle To the coordinate.
Definition: geocoordinate.h:77
Coordinate rotate(const geo::Coordinate &point, const double &angle) const
rotate around a point with a angle
double y() const
Returns y of Coordinate.
Definition: geocoordinate.h:34
CoordinateDistanceSort(const Coordinate &distanceFrom)
Coordinate scale(const double &scale_factor) const
Coordinate(double x, double y)
Definition: geocoordinate.h:16
double magnitude() const
Coordinate(double angle)
Definition: geocoordinate.h:17
Coordinate operator/(double s) const
Definition: cadentity.h:12
double dot(const Coordinate &v1, const Coordinate &v2) const
double z() const
Returns z of Coordinate.
Definition: geocoordinate.h:42
Coordinate operator+(const Coordinate &coord) const
Coordinate transform2d(double xx, double yx, double xy, double yy, double x0, double y0)
Coordinate rotate(const Coordinate &angleVector) const
rotate around (0.,0.) with a given angle vector
Coordinate norm() const
friend std::ostream & operator<<(std::ostream &os, const Coordinate &coordinate)
Coordinate(double x, double y, double z)
Definition: geocoordinate.h:15
Coordinate move(const Coordinate &direction, double d) const
sort a Collection in order of distance to a specific coordinate
Coordinate rotate(const geo::Coordinate &point, const Coordinate &angleVector) const
rotate around a point with a angle vector
Coordinate rotateByArcLength(const geo::Coordinate &point, double const length) const
rotate around a point where the rotation described length is known Example
Coordinate norm(const double f) const
Coordinate rotate(const double &angle) const
rotate around (0.,0.) with a given angle
Coordinate(Coordinate &&c) noexcept
Definition: geocoordinate.h:18
Coordinate operator*(const Coordinate &coord) const
double dot(const Coordinate &coord) const
Coordinate & operator=(const Coordinate &coord)
Definition: geocoordinate.h:47
double distanceTo(const geo::Coordinate &c) const
Coordinate(const Coordinate &c)
Definition: geocoordinate.h:19
Coordinate scale(const Coordinate &scale_factor) const
bool operator==(const Coordinate &coord) const
checks for the equality of Coordinate
Definition: geocoordinate.h:92
double angle() const
Coordinate operator-() const
operator -
double angleBetween(const Coordinate &v1, const Coordinate &v2) const