MLIB
Loading...
Searching...
No Matches
point.h
Go to the documentation of this file.
1/*
2 Copyright (c) Mircea Neacsu (2014-2025) Licensed under MIT License.
3 This file is part of MLIB project. See LICENSE file for full license terms.
4*/
5
7
8#pragma once
9
10#if __has_include("defs.h")
11#include "defs.h"
12#endif
13
14#include <mlib/convert.h>
15
16#include <ostream>
17
18namespace mlib {
19
28
30template <typename T>
32{
33 static T tolerance ()
34 {
35 return 1e-7;
36 };
37};
38
40template <>
41struct point_traits<int>
42{
43 static int tolerance ()
44 {
45 return 0;
46 };
47};
48
50template <typename T>
51class Point
52{
53public:
54 typedef point_traits<T> traits;
55 T x, y;
56
57 Point (T a, T b);
59
61 double azimuth (const Point<T>& P2) const;
62
64 double angle (const Point<T>& P1, const Point<T>& P2) const;
65
66 Point<T> operator+ (const Point<T>& p) const;
67 Point<T> operator- (const Point<T>& p) const;
68 Point<T> operator* (double scalar) const;
69 Point<T> operator/ (double scalar) const;
70
73 {
74 return {-x, -y};
75 }
76
78 T operator* (const Point<T>& p) const
79 {
80 return x * p.x + y * p.y;
81 }
82
83 Point<T>& operator+= (const Point<T>& other)
84 {
85 x += other.x;
86 y += other.y;
87 return *this;
88 }
89 Point<T>& operator-= (const Point<T>& other)
90 {
91 x -= other.x;
92 y -= other.y;
93 return *this;
94 }
95 Point<T>& operator*= (double scalar)
96 {
97 x *= scalar;
98 y *= scalar;
99 return *this;
100 }
101 Point<T>& operator/= (double scalar)
102 {
103 x /= scalar;
104 y /= scalar;
105 return *this;
106 }
107
108 double distance (const Point<T>& P2) const;
109 double magnitude () const
110 {
111 return hypot (x, y);
112 }
113 int operator== (const Point<T>& p) const;
114 int operator!= (const Point<T>& p) const;
115
116 bool leftof (const Point<T>& a, const Point<T>& b) const;
117 bool collinear (const Point<T>& a, const Point<T>& b) const;
118 void rotate (double angle);
119};
120
122template <class T>
123Point<T> operator* (double scalar, const Point<T>& p)
124{
125 return {p.x * scalar, p.y * scalar};
126}
127
129template <class T>
130double abs (const Point<T>& p)
131{
132 return p.magnitude ();
133}
134
137template <class T>
138std::ostream& operator<< (std::ostream& s, const Point<T>& p)
139{
140 s << '(' << p.x << ',' << p.y << ')';
141 return s;
142}
143
146
147// Member functions templates --------------------------------------------------
148
150template <typename T>
152 : x (a)
153 , y (b)
154{}
155
157template <class T>
159 : x (0)
160 , y (0)
161{}
162
164template <typename T>
166{
167 return {x + p.x, y + p.y};
168}
169
171template <typename T>
173{
174 return {x - p.x, y - p.y};
175}
176
178template <typename T>
179Point<T> Point<T>::operator* (double scalar) const
180{
181 return {x * scalar, y * scalar};
182}
183
185template <typename T>
186Point<T> Point<T>::operator/ (double scalar) const
187{
188 return {x / scalar, y / scalar};
189}
190
191
196template <typename T>
197double Point<T>::azimuth (const Point<T>& P2) const
198{
199 if (P2 == *this)
200 return 0.;
201 else
202 {
203 double t = atan2 (P2.x - x, P2.y - y);
204 return (t > 0) ? t : 2 * M_PI + t;
205 }
206}
207
209template <typename T>
211{
212 return distance (p) < point_traits<T>::tolerance ();
213}
214
216template <typename T>
218{
219 return !(p == *this);
220}
221
223template <typename T>
224double Point<T>::distance (const Point<T>& P2) const
225{
226 return hypot (x - P2.x, y - P2.y);
227}
228
233template <typename T>
234double Point<T>::angle (const Point<T>& P1, const Point<T>& P2) const
235{
236 if (P1 == *this || P2 == *this)
237 return 0.;
238
239 double cang =
240 ((P1.x - x) * (P2.x - x) + (P1.y - y) * (P2.y - y)) / (distance (P1) * distance (P2));
241 return (cang <= -1) ? M_PI : (cang >= 1) ? 0. : acos (cang);
242}
243
245template <typename T>
246bool Point<T>::leftof (const Point<T>& a, const Point<T>& b) const
247{
248 return (a.x - x) * (b.y - y) - (a.y - y) * (b.x - x) > point_traits<T>::tolerance ();
249}
250
252template <typename T>
253bool Point<T>::collinear (const Point& a, const Point& b) const
254{
255 return ::abs ((a.x - x) * (b.y - y) - (a.y - y) * (b.x - x)) <= point_traits<T>::tolerance ();
256}
257
258template <typename T>
259void Point<T>::rotate (double angle)
260{
261 auto [s, c] = sincos (angle);
262 double x1 = x * c - y * s;
263 double y1 = x * s + y * c;
264 x = x1;
265 y = y1;
266}
267
268
269} // namespace mlib
Generic 2D point.
Definition point.h:52
Point< T > operator+(const Point< T > &p) const
Vector addition.
Definition point.h:165
Point< T > operator*(double scalar) const
Scalar multiplication.
Definition point.h:179
Point()
Default constructor.
Definition point.h:158
bool collinear(const Point< T > &a, const Point< T > &b) const
Return true if points a, this, b are collinear.
Definition point.h:253
int operator==(const Point< T > &p) const
Return TRUE if p and this are closer than tolerance.
Definition point.h:210
Point< T > operator-() const
unary minus operator
Definition point.h:72
double distance(const Point< T > &P2) const
Return distance between this and P2.
Definition point.h:224
Point< T > operator/(double scalar) const
Scalar division.
Definition point.h:186
Point(T a, T b)
Build a Point from a pair of values.
Definition point.h:151
bool leftof(const Point< T > &a, const Point< T > &b) const
Return true if this is left of the line (a,b)
Definition point.h:246
double azimuth(const Point< T > &P2) const
Return azimuth from North of line this-P2.
Definition point.h:197
double angle(const Point< T > &P1, const Point< T > &P2) const
Return inside angle P1-this-P2.
Definition point.h:234
int operator!=(const Point< T > &p) const
Return TRUE if p and this apart by more than tolerance.
Definition point.h:217
Conversion functions and frequently used constants.
std::pair< T, T > sincos(T val)
A handy template to get sin and cos in a single function call.
Definition convert.h:267
#define M_PI
Older name for std::numbers::pi
Definition convert.h:20
double abs(const Point< T > &p)
Alias for magnitude function.
Definition point.h:130
Point< double > dpoint
Specialization of Point using double as underlining type.
Definition point.h:145
Provides default tolerance value for Point class.
Definition point.h:32