MLIB
Loading...
Searching...
No Matches
point.h
Go to the documentation of this file.
1
7#pragma once
8
9#if __has_include("defs.h")
10#include "defs.h"
11#endif
12
13#include <mlib/convert.h>
14
15#include <ostream>
16
17namespace mlib {
18
27
29template <typename T>
31{
32 static T tolerance ()
33 {
34 return 1e-7;
35 };
36};
37
39template <>
40struct point_traits<int>
41{
42 static int tolerance ()
43 {
44 return 0;
45 };
46};
47
49template <typename T>
50class Point
51{
52public:
53 typedef point_traits<T> traits;
54 T x, y;
55
56 Point (T a, T b);
58
60 double azimuth (const Point<T>& P2) const;
61
63 double angle (const Point<T>& P1, const Point<T>& P2) const;
64
65 Point<T> operator+ (const Point<T>& p) const
66 {
67 return {x + p.x, y + p.y};
68 }
69 Point<T> operator- (const Point<T>& p) const
70 {
71 return {x - p.x, y - p.y};
72 }
73 Point<T> operator* (double scalar) const
74 {
75 return {x * scalar, y * scalar};
76 }
77 Point<T> operator/ (double scalar) const
78 {
79 return {x / scalar, y / scalar};
80 }
81
84 {
85 return {-x, -y};
86 }
87
89 T operator* (const Point<T>& p) const
90 {
91 return x * p.x + y * p.y;
92 }
93
94 Point<T>& operator+= (const Point<T>& other)
95 {
96 x += other.x;
97 y += other.y;
98 return *this;
99 }
100 Point<T>& operator-= (const Point<T>& other)
101 {
102 x -= other.x;
103 y -= other.y;
104 return *this;
105 }
106 Point<T>& operator*= (double scalar)
107 {
108 x *= scalar;
109 y *= scalar;
110 return *this;
111 }
112 Point<T>& operator/= (double scalar)
113 {
114 x /= scalar;
115 y /= scalar;
116 return *this;
117 }
118
119 double distance (const Point<T>& P2) const;
120 double magnitude () const
121 {
122 return hypot (x, y);
123 }
124 int operator== (const Point<T>& p) const;
125 int operator!= (const Point<T>& p) const;
126
127 bool leftof (const Point<T>& a, const Point<T>& b) const;
128 bool collinear (const Point<T>& a, const Point<T>& b) const;
129 void rotate (double angle);
130};
131
133template <class T>
134Point<T> operator* (double scalar, const Point<T>& p)
135{
136 return {p.x * scalar, p.y * scalar};
137}
138
140template <class T>
141double abs (const Point<T>& p)
142{
143 return p.magnitude ();
144}
145
148template <class T>
149std::ostream& operator<< (std::ostream& s, const Point<T>& p)
150{
151 s << '(' << p.x << ',' << p.y << ')';
152 return s;
153}
154
157
158// Member functions templates --------------------------------------------------
159
161template <class T>
163 : x (a)
164 , y (b)
165{}
166
168template <class T>
170 : x (0)
171 , y (0)
172{}
173
178template <class T>
179double Point<T>::azimuth (const Point<T>& P2) const
180{
181 if (P2 == *this)
182 return 0.;
183 else
184 {
185 double t = atan2 (P2.x - x, P2.y - y);
186 return (t > 0) ? t : 2 * M_PI + t;
187 }
188}
189
191template <class T>
193{
194 return distance (p) < point_traits<T>::tolerance ();
195}
196
198template <class T>
200{
201 return !(p == *this);
202}
203
205template <class T>
206double Point<T>::distance (const Point<T>& P2) const
207{
208 return hypot (x - P2.x, y - P2.y);
209}
210
215template <class T>
216double Point<T>::angle (const Point<T>& P1, const Point<T>& P2) const
217{
218 if (P1 == *this || P2 == *this)
219 return 0.;
220
221 double cang =
222 ((P1.x - x) * (P2.x - x) + (P1.y - y) * (P2.y - y)) / (distance (P1) * distance (P2));
223 return (cang <= -1) ? M_PI : (cang >= 1) ? 0. : acos (cang);
224}
225
227template <class T>
228bool Point<T>::leftof (const Point<T>& a, const Point<T>& b) const
229{
230 return (a.x - x) * (b.y - y) - (a.y - y) * (b.x - x) > point_traits<T>::tolerance ();
231}
232
234template <class T>
235bool Point<T>::collinear (const Point& a, const Point& b) const
236{
237 return ::abs ((a.x - x) * (b.y - y) - (a.y - y) * (b.x - x)) <= point_traits<T>::tolerance ();
238}
239
240template <class T>
241void Point<T>::rotate (double angle)
242{
243 auto [s, c] = sincos (angle);
244 double x1 = x * c - y * s;
245 double y1 = x * s + y * c;
246 x = x1;
247 y = y1;
248}
249
250} // namespace mlib
Generic 2D point.
Definition point.h:51
Point()
Default constructor.
Definition point.h:169
bool collinear(const Point< T > &a, const Point< T > &b) const
Return true if points a, this, b are collinear.
Definition point.h:235
int operator==(const Point< T > &p) const
Return TRUE if p and this are closer than tolerance.
Definition point.h:192
Point< T > operator-() const
unary minus operator
Definition point.h:83
double distance(const Point< T > &P2) const
Return distance between this and P2.
Definition point.h:206
Point(T a, T b)
Build a Point from a pair of T's.
Definition point.h:162
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:228
double azimuth(const Point< T > &P2) const
Return azimuth from North of line this-P2.
Definition point.h:179
double angle(const Point< T > &P1, const Point< T > &P2) const
Return inside angle P1-this-P2.
Definition point.h:216
int operator!=(const Point< T > &p) const
Return TRUE if p and this apart by more than tolerance.
Definition point.h:199
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:265
double abs(const Point< T > &p)
Alias for magnitude function.
Definition point.h:141
Point< double > dpoint
Specialization of Point using double as underlining type.
Definition point.h:156
Provides default tolerance value for Point class.
Definition point.h:31