DeSiGNAR  0.5a
Data Structures General Library
point2D.H
Go to the documentation of this file.
1 /*
2  This file is part of Designar.
3  Copyright (C) 2017 by Alejandro J. Mujica
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Any user request of this software, write to
19 
20  Alejandro Mujica
21 
22  aledrums@gmail.com
23 */
24 
25 # ifndef DSGPOINT_H
26 # define DSGPOINT_H
27 
28 # include <math.H>
29 
30 namespace Designar
31 {
32 
33  template <typename NumT>
34  class GenPoint2D
35  {
36  static_assert(std::is_arithmetic<NumT>::value,
37  "Template argument must be an arithmetic type");
38 
39  protected:
40  NumT x;
41  NumT y;
42 
43  public:
44  using ComponentType = NumT;
45  using NumberType = NumT;
46  using ValueType = NumT;
47 
49  : x(0), y(0)
50  {
51  // empty
52  }
53 
54  GenPoint2D(const NumT & _x, const NumT & _y)
55  : x(_x), y(_y)
56  {
57  // empty
58  }
59 
60  GenPoint2D(const NumT & _x, NumT && _y)
61  : x(_x), y(std::forward<NumT>(_y))
62  {
63  // empty
64  }
65 
66  GenPoint2D(NumT && _x, const NumT & _y)
67  : x(std::forward<NumT>(_x)), y(_y)
68  {
69  // empty
70  }
71 
72  GenPoint2D(NumT && _x, NumT && _y)
73  : x(std::forward<NumT>(_x)), y(std::forward<NumT>(_y))
74  {
75  // empty
76  }
77 
79  : x(p.x), y(p.y)
80  {
81  // empty
82  }
83 
85  : GenPoint2D()
86  {
87  swap(p);
88  }
89 
91  {
92  if (this == &p)
93  return *this;
94 
95  x = p.x;
96  y = p.y;
97 
98  return *this;
99  }
100 
102  {
103  swap(p);
104  return *this;
105  }
106 
107  void swap(GenPoint2D & p)
108  {
109  std::swap(x, p.x);
110  std::swap(y, p.y);
111  }
112 
113  const NumT & get_x() const
114  {
115  return x;
116  }
117 
118  const NumT & get_y() const
119  {
120  return y;
121  }
122 
123  void set_x(const NumT & _x)
124  {
125  x = _x;
126  }
127 
128  void set_x(NumT && _x)
129  {
130  x = std::move(_x);
131  }
132 
133  void set_y(const NumT & _y)
134  {
135  y = _y;
136  }
137 
138  void set_y(NumT && _y)
139  {
140  y = std::move(_y);
141  }
142 
143  void nullify()
144  {
145  x = y = NumT(0);
146  }
147 
148  bool is_null() const
149  {
150  return num_equal(x, NumT(0)) and num_equal(y, NumT(0));
151  }
152 
153  bool is_zero() const
154  {
155  return is_null();
156  }
157 
158  NumT square_distance_with(const GenPoint2D & p) const
159  {
160  NumT dx = p.x - x;
161  NumT dy = p.y - y;
162  return dx * dx + dy * dy;
163  }
164 
165  real_t distance_with(const GenPoint2D & p) const
166  {
167  return std::sqrt(square_distance_with(p));
168  }
169 
171  {
172  return x * x + y * y;
173  }
174 
175  NumT distance_to_origin() const
176  {
177  return std::sqrt(square_distance_to_origin());
178  }
179 
180  bool is_to_right_from(const GenPoint2D & p, const GenPoint2D & q) const
181  {
182  return area_of_parallelogram(p, q, *this) < NumT(0);
183  }
184 
185  bool is_to_right_on_from(const GenPoint2D & p, const GenPoint2D & q) const
186  {
187  return area_of_parallelogram(p, q, *this) <= NumT(0);
188  }
189 
190  bool is_to_left_from(const GenPoint2D & p, const GenPoint2D & q) const
191  {
192  return area_of_parallelogram(p, q, *this) > NumT(0);
193  }
194 
195  bool is_to_left_on_from(const GenPoint2D & p, const GenPoint2D & q) const
196  {
197  return area_of_parallelogram(p, q, *this) >= NumT(0);
198  }
199 
200  bool is_collinear_with(const GenPoint2D & p, const GenPoint2D & q) const
201  {
202  return num_equal(area_of_parallelogram(p, q, *this), NumT(0));
203  }
204 
205  bool is_between(const GenPoint2D & p, const GenPoint2D & q) const
206  {
207  if (not is_collinear_with(p, q))
208  return false;
209 
210  if (p.get_x() != q.get_x())
211  return ((p.get_x() <= this->get_x()) and (this->get_x() <= q.get_x()))
212  or ((p.get_x() >= this->get_x()) and (this->get_x() >= q.get_x()));
213  else
214  return ((p.get_y() <= this->get_y()) and (this->get_y() <= q.get_y()))
215  or ((p.get_y() >= this->get_y()) and (this->get_y() >= q.get_y()));
216  }
217 
218  explicit operator bool() const
219  {
220  return not is_null();
221  }
222 
223  bool operator == (const GenPoint2D & p) const
224  {
225  return num_equal(x, p.x) and num_equal(y, p.y);
226  }
227 
228  bool operator != (const GenPoint2D & p) const
229  {
230  return not (*this == p);
231  }
232 
233  std::string to_string() const
234  {
235  std::stringstream s;
236  s << '(' << x << ',' << y << ')';
237  return s.str();
238  }
239  };
240 
241  class PointInt2D : public GenPoint2D<lint_t>
242  {
243  using Base = GenPoint2D<lint_t>;
244  using Base::Base;
245  };
246 
247  class Point2D : public GenPoint2D<real_t>
248  {
249  using Base = GenPoint2D<real_t>;
250  using Base::Base;
251  };
252 
253 } // end namespace Designar
254 
255 # endif // DSGPOINT_H
GenPoint2D(const NumT &_x, const NumT &_y)
Definition: point2D.H:54
GenPoint2D(NumT &&_x, NumT &&_y)
Definition: point2D.H:72
lint_t ComponentType
Definition: point2D.H:44
bool is_null() const
Definition: point2D.H:148
lint_t ValueType
Definition: point2D.H:46
NumT distance_to_origin() const
Definition: point2D.H:175
bool operator==(const GenPoint2D &p) const
Definition: point2D.H:223
double real_t
Definition: types.H:51
bool num_equal(T, T)
Definition: math.H:99
GenPoint2D(const GenPoint2D &p)
Definition: point2D.H:78
void set_x(const NumT &_x)
Definition: point2D.H:123
bool is_zero() const
Definition: point2D.H:153
void set_y(NumT &&_y)
Definition: point2D.H:138
lint_t NumberType
Definition: point2D.H:45
NumT x
Definition: point2D.H:37
NumT square_distance_with(const GenPoint2D &p) const
Definition: point2D.H:158
bool operator!=(const GenPoint2D &p) const
Definition: point2D.H:228
GenPoint2D(const NumT &_x, NumT &&_y)
Definition: point2D.H:60
NumT y
Definition: point2D.H:41
void nullify()
Definition: point2D.H:143
bool is_between(const GenPoint2D &p, const GenPoint2D &q) const
Definition: point2D.H:205
GenPoint2D()
Definition: point2D.H:48
real_t distance_with(const GenPoint2D &p) const
Definition: point2D.H:165
bool is_collinear_with(const GenPoint2D &p, const GenPoint2D &q) const
Definition: point2D.H:200
void set_x(NumT &&_x)
Definition: point2D.H:128
bool is_to_left_on_from(const GenPoint2D &p, const GenPoint2D &q) const
Definition: point2D.H:195
const NumT & get_x() const
Definition: point2D.H:113
bool is_to_right_from(const GenPoint2D &p, const GenPoint2D &q) const
Definition: point2D.H:180
Definition: math.H:69
bool is_to_left_from(const GenPoint2D &p, const GenPoint2D &q) const
Definition: point2D.H:190
Definition: point2D.H:241
GenPoint2D(GenPoint2D &&p)
Definition: point2D.H:84
Definition: point2D.H:247
GenPoint2D & operator=(const GenPoint2D &p)
Definition: point2D.H:90
Definition: array.H:32
NumT square_distance_to_origin() const
Definition: point2D.H:170
std::string to_string() const
Definition: point2D.H:233
Value & value(MapKey< Key, Value > &item)
Definition: map.H:77
bool is_to_right_on_from(const GenPoint2D &p, const GenPoint2D &q) const
Definition: point2D.H:185
void set_y(const NumT &_y)
Definition: point2D.H:133
const NumT & get_y() const
Definition: point2D.H:118
GenPoint2D(NumT &&_x, const NumT &_y)
Definition: point2D.H:66
void swap(GenPoint2D &p)
Definition: point2D.H:107
real_t area_of_parallelogram(const GenPoint2D< NumberType > &, const GenPoint2D< NumberType > &, const GenPoint2D< NumberType > &)
Definition: math.H:129