Jpp 19.3.0-rc.3
the software that should make you happy
Loading...
Searching...
No Matches
JCircle2D.hh
Go to the documentation of this file.
1#ifndef __JCIRCLE2D__
2#define __JCIRCLE2D__
3
4#include <istream>
5#include <ostream>
6#include <iterator>
7#include <cmath>
8#include <limits>
9
10#include "JLang/JManip.hh"
11#include "JLang/JVectorize.hh"
12#include "JIO/JSerialisable.hh"
14
15
16/**
17 * \author mdejong
18 */
19
20namespace JGEOMETRY2D {}
21namespace JPP { using namespace JGEOMETRY2D; }
22
23namespace JGEOMETRY2D {
24
26 using JIO::JReader;
27 using JIO::JWriter;
28
29
30 /**
31 * Data structure for circle in two dimensions.
32 */
33 class JCircle2D :
34 public JPosition2D
35 {
36 public:
37 /**
38 * Default constructor.
39 */
42 __r(0.0)
43 {}
44
45
46 /**
47 * Constructor.
48 *
49 * \param point point
50 * \param r radius
51 */
52 JCircle2D(const JVector2D& point,
53 const double r) :
54 JPosition2D(point),
55 __r(r)
56 {}
57
58
59 /**
60 * Constructor.
61 * Determines circle through two points.
62 *
63 * \param p0 first point
64 * \param p1 second point
65 */
67 const JVector2D& p1) :
69 __r(0.0)
70 {
71 set(p0, p1);
72 }
73
74
75 /**
76 * Constructor.
77 * Determines circle through three points.
78 *
79 * \param p0 first point
80 * \param p1 second point
81 * \param p2 third point
82 * \param precision precision
83 */
85 const JVector2D& p1,
86 const JVector2D& p2,
87 const double precision = std::numeric_limits<double>::epsilon()) :
89 __r(0.0)
90 {
91 set(p0, p1, p2, precision);
92 }
93
94
95 /**
96 * Constructor.
97 * Determines smallest enclosing circle around set of points.\n
98 * The type of data should have the following member methods:
99 * <pre>
100 * double getX(); // x coordinate
101 * double getY(); // y coordinate
102 * </pre>
103 *
104 * Reference:\n
105 * Computational Geometry
106 * Algorithms and Applications\n
107 * Authors: de Berg, M., Cheong, O., van Kreveld, M., Overmars, M.
108 *
109 * \param __begin begin of data
110 * \param __end end of data
111 * \param precision precision
112 */
113 template<class T>
114 JCircle2D(T __begin,
115 T __end,
116 const double precision = std::numeric_limits<double>::epsilon()) :
117 JPosition2D(),
118 __r(0.0)
119 {
120 set(__begin, __end, precision);
121 }
122
123
124 /**
125 * Constructor.
126 * \param buffer input data
127 * \param precision precision
128 */
129 template<class JElement_t, class JAllocator_t>
131 const double precision = std::numeric_limits<double>::epsilon()) :
132 JPosition2D(),
133 __r(0.0)
134 {
135 set(buffer.begin(), buffer.end(), precision);
136 }
137
138
139 /**
140 * Get radius.
141 *
142 * \return radius
143 */
144 double getRadius() const
145 {
146 return __r;
147 }
148
149
150 /**
151 * Set circle.
152 * Determines circle through two points.
153 *
154 * \param p0 first point
155 * \param p1 second point
156 */
157 void set(const JVector2D& p0,
158 const JVector2D& p1)
159 {
160 __x = 0.5 * (p0.getX() + p1.getX());
161 __y = 0.5 * (p0.getY() + p1.getY());
162 __r = this->getDistance(p0);
163 }
164
165
166 /**
167 * Set circle.
168 * Determines circle through three points.
169 *
170 * \param p0 first point
171 * \param p1 second point
172 * \param p2 third point
173 * \param precision precision
174 */
175 void set(const JVector2D& p0,
176 const JVector2D& p1,
177 const JVector2D& p2,
178 const double precision = std::numeric_limits<double>::epsilon())
179 {
180 const double x0 = p2.getX() - p1.getX();
181 const double x1 = p0.getX() - p2.getX();
182 const double x2 = p1.getX() - p0.getX();
183
184 const double y0 = p1.getY() - p2.getY();
185 const double y1 = p2.getY() - p0.getY();
186 const double y2 = p0.getY() - p1.getY();
187
188 const double D = 2.0 * (p0.getX()*y0 + p1.getX()*y1 + p2.getX()*y2);
189
190 if (fabs(D) > precision) {
191
192 const double a = p0.getLengthSquared();
193 const double b = p1.getLengthSquared();
194 const double c = p2.getLengthSquared();
195
196 __x = (a*y0 + b*y1 + c*y2) / D;
197 __y = (a*x0 + b*x1 + c*x2) / D;
198 __r = this->getDistance(p0);
199
200 } else {
201
202 set(p0, p1);
203
204 const JCircle2D c1(p1, p2);
205 const JCircle2D c2(p0, p2);
206
207 if (c1.getRadius() > this->getRadius()) { *this = c1; }
208 if (c2.getRadius() > this->getRadius()) { *this = c2; }
209 }
210 }
211
212
213 /**
214 * Set circle.
215 * Determines smallest enclosing circle around set of points.
216 * <pre>
217 * double getX(); // x coordinate
218 * double getY(); // y coordinate
219 * </pre>
220 *
221 * \param __begin begin of data
222 * \param __end end of data
223 * \param precision precision
224 */
225 template<class T>
226 void set(T __begin,
227 T __end,
228 const double precision = std::numeric_limits<double>::epsilon())
229 {
230 if (__begin != __end) {
231
232 __x = __begin->getX();
233 __y = __begin->getY();
234 __r = 0.0;
235
236 T i = __begin;
237
238 const JVector2D p0(i->getX(), i->getY());
239
240 while (++i != __end && p0.getDistance(JVector2D(i->getX(), i->getY())) <= precision) {}
241
242 if (i != __end) {
243
244 const JVector2D p1(i->getX(), i->getY());
245
246 set(p0, p1);
247
248 while (++i != __end) {
249
250 const JVector2D p2(i->getX(), i->getY());
251
252 if (this->getDistance(p2) > this->getRadius() + precision &&
253 p0.getDistance(p2) > precision &&
254 p1.getDistance(p2) > precision) {
255 configure(__begin, i, p2, precision);
256 }
257 }
258 }
259 }
260 }
261
262
263 /**
264 * Check whether given point is inside circle.
265 *
266 * \param pos position
267 * \param precision precision
268 * \return true if inside; else false
269 */
270 inline bool is_inside(const JVector2D& pos,
271 const double precision = std::numeric_limits<double>::min()) const
272 {
273 return (this->getDistance(pos) <= this->getRadius() + precision);
274 }
275
276
277 /**
278 * Read circle from input stream.
279 *
280 * \param in input stream
281 * \param circle circle
282 * \return input stream
283 */
284 friend inline std::istream& operator>>(std::istream& in, JCircle2D& circle)
285 {
286 in >> static_cast<JPosition2D&>(circle);
287 in >> circle.__r;
288
289 return in;
290 }
291
292
293 /**
294 * Write circle to output stream.
295 *
296 * \param out output stream
297 * \param circle circle
298 * \return output stream
299 */
300 friend inline std::ostream& operator<<(std::ostream& out, const JCircle2D& circle)
301 {
302 const JFormat format(out, getFormat<JPosition2D>(JFormat_t(9, 3, std::ios::fixed | std::ios::showpos)));
303
304 out << static_cast<const JPosition2D&>(circle);
305 out << ' ';
306 out << format << circle.getRadius();
307
308 return out;
309 }
310
311
312 /**
313 * Read circle from input.
314 *
315 * \param in reader
316 * \param circle circle
317 * \return reader
318 */
319 friend inline JReader& operator>>(JReader& in, JCircle2D& circle)
320 {
321 in >> static_cast<JPosition2D&>(circle);
322 in >> circle.__r;
323
324 return in;
325 }
326
327
328 /**
329 * Write circle to output.
330 *
331 * \param out writer
332 * \param circle circle
333 * \return writer
334 */
335 friend inline JWriter& operator<<(JWriter& out, const JCircle2D& circle)
336 {
337 out << static_cast<const JPosition2D&>(circle);
338 out << circle.__r;
339
340 return out;
341 }
342
343
344 protected:
345 double __r;
346
347
348 private:
349 /**
350 * Determine smallest enclosing circle.
351 *
352 * \param __begin begin of data
353 * \param __end end of data
354 * \param p0 point on circle
355 * \param precision precision
356 */
357 template<class T>
358 void configure(T __begin,
359 T __end,
360 const JVector2D& p0,
361 const double precision)
362 {
363 this->set(JVector2D(__begin->getX(), __begin->getY()), p0);
364
365 for (T i = __begin; ++i != __end; ) {
366
367 const JVector2D p1(i->getX(), i->getY());
368
369 if (this->getDistance(p1) > this->getRadius() + precision &&
370 p0.getDistanceSquared(p1) > precision) {
371 configure(__begin, i, p0, p1, precision);
372 }
373 }
374 }
375
376
377 /**
378 * Determine smallest enclosing circle.
379 *
380 * \param __begin begin of data
381 * \param __end end of data
382 * \param p0 point on circle
383 * \param p1 point on circle
384 * \param precision precision
385 */
386 template<class T>
387 void configure(T __begin,
388 T __end,
389 const JVector2D& p0,
390 const JVector2D& p1,
391 const double precision)
392 {
393 this->set(p0, p1);
394
395 for (T i = __begin; i != __end; ++i) {
396
397 const JVector2D p2(i->getX(), i->getY());
398
399 if (this->getDistance(p2) > this->getRadius() + precision &&
400 p0.getDistanceSquared(p2) > precision &&
401 p1.getDistanceSquared(p2) > precision) {
402 this->set(p0, p1, p2, precision);
403 }
404 }
405 }
406 };
407}
408
409#endif
TCanvas * c1
Global variables to handle mouse events.
TPaveText * p1
I/O manipulators.
JFormat_t & getFormat()
Get format for given type.
Definition JManip.hh:682
Auxiliary methods to convert data members or return values of member methods of a set of objects to a...
Data structure for circle in two dimensions.
Definition JCircle2D.hh:35
friend JReader & operator>>(JReader &in, JCircle2D &circle)
Read circle from input.
Definition JCircle2D.hh:319
void set(T __begin, T __end, const double precision=std::numeric_limits< double >::epsilon())
Set circle.
Definition JCircle2D.hh:226
bool is_inside(const JVector2D &pos, const double precision=std::numeric_limits< double >::min()) const
Check whether given point is inside circle.
Definition JCircle2D.hh:270
void set(const JVector2D &p0, const JVector2D &p1)
Set circle.
Definition JCircle2D.hh:157
friend std::istream & operator>>(std::istream &in, JCircle2D &circle)
Read circle from input stream.
Definition JCircle2D.hh:284
void configure(T __begin, T __end, const JVector2D &p0, const JVector2D &p1, const double precision)
Determine smallest enclosing circle.
Definition JCircle2D.hh:387
JCircle2D(const JVector2D &point, const double r)
Constructor.
Definition JCircle2D.hh:52
JCircle2D(const array_type< JElement_t, JAllocator_t > &buffer, const double precision=std::numeric_limits< double >::epsilon())
Constructor.
Definition JCircle2D.hh:130
void configure(T __begin, T __end, const JVector2D &p0, const double precision)
Determine smallest enclosing circle.
Definition JCircle2D.hh:358
JCircle2D(const JVector2D &p0, const JVector2D &p1)
Constructor.
Definition JCircle2D.hh:66
JCircle2D(T __begin, T __end, const double precision=std::numeric_limits< double >::epsilon())
Constructor.
Definition JCircle2D.hh:114
double getRadius() const
Get radius.
Definition JCircle2D.hh:144
JCircle2D()
Default constructor.
Definition JCircle2D.hh:40
void set(const JVector2D &p0, const JVector2D &p1, const JVector2D &p2, const double precision=std::numeric_limits< double >::epsilon())
Set circle.
Definition JCircle2D.hh:175
friend JWriter & operator<<(JWriter &out, const JCircle2D &circle)
Write circle to output.
Definition JCircle2D.hh:335
JCircle2D(const JVector2D &p0, const JVector2D &p1, const JVector2D &p2, const double precision=std::numeric_limits< double >::epsilon())
Constructor.
Definition JCircle2D.hh:84
friend std::ostream & operator<<(std::ostream &out, const JCircle2D &circle)
Write circle to output stream.
Definition JCircle2D.hh:300
Data structure for position in two dimensions.
Data structure for vector in two dimensions.
Definition JVector2D.hh:34
double getDistance(const JVector2D &point) const
Get distance to point.
Definition JVector2D.hh:223
double getY() const
Get y position.
Definition JVector2D.hh:74
double getDistanceSquared(const JVector2D &point) const
Get squared of distance to point.
Definition JVector2D.hh:211
double getX() const
Get x position.
Definition JVector2D.hh:63
JVector2D()
Default constructor.
Definition JVector2D.hh:39
double getLengthSquared() const
Get length squared.
Definition JVector2D.hh:188
Interface for binary input.
Interface for binary output.
Auxiliary classes and methods for 2D geometrical objects and operations.
Definition JAngle2D.hh:19
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Data structure for format specifications.
Definition JManip.hh:524
Auxiliary class to temporarily define format specifications.
Definition JManip.hh:636
Auxiliary data structure for return type of make methods.
Definition JVectorize.hh:28