PCB Environment 2
Loading...
Searching...
No Matches
AShape.hpp
1
2#ifndef GYM_PCB_ASHAPE_H
3#define GYM_PCB_ASHAPE_H
4
5#include "Py.hpp"
6#include "Geometry.hpp"
7#include "Math/Misc.hpp"
8#include <cassert>
9#include <sstream>
10
11class CircleEx;
12class IsoRectEx;
13class TriangleEx;
14class PolygonEx;
15class WideSegment_25;
16
20class AShape
21{
22public:
23 virtual ~AShape() { }
24
25 template<typename T> T *as() { return dynamic_cast< T *>(this); }
26 template<typename T> const T *as() const { return dynamic_cast<const T *>(this); }
27
28 virtual AShape *clone() const = 0;
29
33 virtual uint vertexCount() const = 0;
34 virtual uint indexCountWithRestart() const { return vertexCount() + 1; }
35 virtual bool canDrawAsTriFan() const { return true; }
36
37 virtual bool isRound() const { return false; }
38
39 virtual Real unsignedArea() const = 0;
40
41 virtual Bbox_2 bbox() const = 0;
42
43 Real boundingRadius() const;
44
50 virtual bool transformPreservesType(const CGAL::Aff_transformation_2<Kernel>&) const { return true; }
51
55 virtual void transform(const CGAL::Aff_transformation_2<Kernel>&) = 0;
56 virtual void translate(const Vector_2&) = 0;
57
62 virtual AShape *transformType(const CGAL::Aff_transformation_2<Kernel>&);
63
64 virtual bool contains(const Point_2&) const = 0;
65
66 virtual Real squared_distance(const AShape&) const = 0;
67
68 virtual Real squared_distance(const ::Point_2&) const = 0;
69 virtual Real squared_distance(const Segment_2&) const = 0;
70 virtual Real squared_distance(const Circle_2&) const = 0;
71 virtual Real squared_distance(const Iso_rectangle_2&) const = 0;
72 Real squared_distance(const Bbox_2&) const;
73 virtual Real squared_distance(const Triangle_2&) const = 0;
74 virtual Real squared_distance(const Polygon_2&) const = 0;
75 virtual Real squared_distance(const WideSegment_25&) const = 0;
76
77 virtual bool intersects(const AShape&) const = 0;
78
79 virtual bool intersects(const Circle_2&) const = 0;
80 virtual bool intersects(const Iso_rectangle_2&) const = 0;
81 bool intersects(const Bbox_2&) const;
82 virtual bool intersects(const Triangle_2&) const = 0;
83 virtual bool intersects(const Polygon_2&) const = 0;
84 virtual bool intersects(const WideSegment_25&) const = 0;
85
86 virtual ::Point_2 centroid() const = 0;
87
88 virtual std::string str() const = 0;
89
99 virtual PyObject *getPy() const = 0;
100};
101
102inline Real AShape::boundingRadius() const
103{
104 const auto B = bbox();
105 return std::max(B.xmax() - B.xmin(), B.ymax() - B.ymin());
106}
107
108inline bool AShape::intersects(const Bbox_2 &bbox) const
109{
110 return intersects(Iso_rectangle_2(bbox));
111}
112inline Real AShape::squared_distance(const Bbox_2 &bbox) const
113{
114 return squared_distance(Iso_rectangle_2(bbox));
115}
116
117class CircleEx : public AShape, public Circle_2
118{
119public:
120 CircleEx(const Circle_2 &base) : Circle_2(base) { }
121
122 AShape *clone() const override { return new CircleEx(*this); }
123
124 CircleEx grown(Real) const;
125
126 uint vertexCount() const override { return 4; }
127 bool canDrawAsTriFan() const override { return true; }
128
129 bool isRound() const override { return true; }
130
131 Real unsignedArea() const override { return squared_radius() * M_PI; }
132
133 Bbox_2 bbox() const override { return Circle_2::bbox(); }
134
135 bool transformPreservesType(const CGAL::Aff_transformation_2<Kernel>&) const override;
136
137 void transform(const CGAL::Aff_transformation_2<Kernel>&) override;
138 void translate(const ::Vector_2&) override;
139
140 bool contains(const ::Point_2&) const override;
141
142 Real squared_distance(const AShape &S) const override { return S.squared_distance(*static_cast<const Circle_2 *>(this)); }
143
144 Real squared_distance(const ::Point_2&) const override;
145 Real squared_distance(const Segment_2&) const override;
146 Real squared_distance(const Circle_2&) const override;
147 Real squared_distance(const Iso_rectangle_2&) const override;
148 Real squared_distance(const Triangle_2&) const override;
149 Real squared_distance(const Polygon_2&) const override;
150 Real squared_distance(const WideSegment_25&) const override;
151
152 bool intersects(const AShape &S) const override { return S.intersects(*static_cast<const Circle_2 *>(this)); }
153
154 bool intersects(const Circle_2&) const override;
155 bool intersects(const Iso_rectangle_2&) const override;
156 bool intersects(const Triangle_2&) const override;
157 bool intersects(const Polygon_2&) const override;
158 bool intersects(const WideSegment_25&) const override;
159
160 ::Point_2 centroid() const override { return center(); }
161
162 std::string str() const override;
163 PyObject *getPy() const override;
164};
165inline CircleEx CircleEx::grown(Real dr) const
166{
167 return CircleEx(Circle_2(center(), math::squared(std::sqrt(squared_radius()) + dr)));
168}
169
170class TriangleEx : public AShape, public Triangle_2
171{
172public:
173 TriangleEx(const Triangle_2 &base) : Triangle_2(base) { }
174 TriangleEx(Triangle_2 &&base) : Triangle_2(base) { }
175
176 AShape *clone() const override { return new TriangleEx(*this); }
177
178 uint vertexCount() const override { return 3; }
179
180 Real unsignedArea() const override { return std::abs(area()); }
181
182 Bbox_2 bbox() const override { return Triangle_2::bbox(); }
183
184 void transform(const CGAL::Aff_transformation_2<Kernel>&) override;
185 void translate(const ::Vector_2&) override;
186
187 bool contains(const ::Point_2&) const override;
188
189 Real squared_distance(const AShape &S) const override { return S.squared_distance(*static_cast<const Triangle_2 *>(this)); }
190
191 Real squared_distance(const ::Point_2&) const override;
192 Real squared_distance(const Segment_2&) const override;
193 Real squared_distance(const Circle_2 &C) const override;
194 Real squared_distance(const Iso_rectangle_2&) const override;
195 Real squared_distance(const Triangle_2&) const override;
196 Real squared_distance(const Polygon_2&) const override;
197 Real squared_distance(const WideSegment_25&) const override;
198
199 bool intersects(const AShape &S) const override { return S.intersects(*static_cast<const Triangle_2 *>(this)); }
200
201 bool intersects(const Circle_2&) const override;
202 bool intersects(const Iso_rectangle_2&) const override;
203 bool intersects(const Triangle_2&) const override;
204 bool intersects(const Polygon_2&) const override;
205 bool intersects(const WideSegment_25&) const override;
206
207 ::Point_2 centroid() const override;
208
209 std::string str() const override;
210 PyObject *getPy() const override;
211};
212
213class IsoRectEx : public AShape, public Iso_rectangle_2
214{
215public:
216 IsoRectEx(const Iso_rectangle_2 &base) : Iso_rectangle_2(base) { }
217 IsoRectEx(Iso_rectangle_2 &&base) : Iso_rectangle_2(base) { }
218
219 IsoRectEx(const Bbox_2 &bbox) : Iso_rectangle_2(bbox) { }
220
221 AShape *clone() const override { return new IsoRectEx(*this); }
222
223 uint vertexCount() const override { return 4; }
224
225 Real unsignedArea() const override { return std::abs(area()); }
226
227 Bbox_2 bbox() const override { return Iso_rectangle_2::bbox(); }
228
229 bool transformPreservesType(const CGAL::Aff_transformation_2<Kernel>&) const override;
230
231 void transform(const CGAL::Aff_transformation_2<Kernel>&) override;
232 void translate(const ::Vector_2&) override;
233
234 AShape *transformType(const CGAL::Aff_transformation_2<Kernel>&) override;
235
236 bool contains(const ::Point_2&) const override;
237
238 Real squared_distance(const AShape &S) const override { return S.squared_distance(*static_cast<const Iso_rectangle_2 *>(this)); }
239
240 Real squared_distance(const ::Point_2&) const override;
241 Real squared_distance(const Segment_2&) const override;
242 Real squared_distance(const Circle_2 &C) const override;
243 Real squared_distance(const Triangle_2 &T) const override;
244 Real squared_distance(const Iso_rectangle_2&) const override;
245 Real squared_distance(const Polygon_2&) const override;
246 Real squared_distance(const WideSegment_25&) const override;
247
248 bool intersects(const AShape &S) const override { return S.intersects(*static_cast<const Iso_rectangle_2 *>(this)); }
249
250 bool intersects(const Circle_2 &C) const override;
251 bool intersects(const Triangle_2 &T) const override;
252 bool intersects(const Iso_rectangle_2&) const override;
253 bool intersects(const Polygon_2&) const override;
254 bool intersects(const WideSegment_25&) const override;
255
259 Real lengthOutside(const Segment_2&) const;
260
261 ::Point_2 centroid() const override;
262
263 std::string str() const override;
264 PyObject *getPy() const override;
265};
266
267class PolygonEx : public AShape, public Polygon_2
268{
269public:
270 PolygonEx(const Polygon_2 &base) : Polygon_2(base) { }
271 PolygonEx(Polygon_2 &&base) : Polygon_2(base) { }
272
273 AShape *clone() const override { return new PolygonEx(*this); }
274
275 PolygonEx grown(Real size, Real epsilon = 0.125) const;
276
283 static Polygon_2 grow(const Polygon_2&, Real size, Real epsilon = 0.125);
284
285 uint vertexCount() const override { return size(); }
286 uint indexCountWithRestart() const override { return is_convex() ? (vertexCount() + 1) : 0; }
287 bool canDrawAsTriFan() const override { return is_convex(); }
288
289 Real unsignedArea() const override { return std::abs(area()); }
290
291 Bbox_2 bbox() const override { return Polygon_2::bbox(); }
292
293 void transform(const CGAL::Aff_transformation_2<Kernel>&) override;
294 void translate(const ::Vector_2&) override;
295
296 bool contains(const ::Point_2&) const override;
297
298 Real squared_distance(const AShape &S) const override { return S.squared_distance(*static_cast<const Polygon_2 *>(this)); }
299
300 Real squared_distance(const ::Point_2&) const override;
301 Real squared_distance(const Segment_2&) const override;
302 Real squared_distance(const Circle_2 &C) const override;
303 Real squared_distance(const Iso_rectangle_2 &R) const override;
304 Real squared_distance(const Triangle_2 &T) const override;
305 Real squared_distance(const Polygon_2&) const override;
306 Real squared_distance(const WideSegment_25&) const override;
307
308 bool intersects(const AShape &S) const override { return S.intersects(*static_cast<const Polygon_2 *>(this)); }
309
310 bool intersects(const Circle_2 &C) const override;
311 bool intersects(const Iso_rectangle_2 &R) const override;
312 bool intersects(const Triangle_2 &T) const override;
313 bool intersects(const Polygon_2&) const override;
314 bool intersects(const WideSegment_25&) const override;
315
316 ::Point_2 centroid() const override;
317
318 std::string str() const override;
319 PyObject *getPy() const override;
320
321private:
322 static Polygon_2 _grow_offset(const Polygon_2&, Real size, Real epsilon = 0.125);
323 static Polygon_2 _grow_stupid(const Polygon_2&, Real size);
324};
325
331class WideSegment_25 : public AShape
332{
333public:
334 WideSegment_25(const Segment_25 &s, Real halfWidth) : mBase(s), mHW(halfWidth) { }
335 WideSegment_25(const Segment_2 &s, int z, Real halfWidth) : mBase(s, z), mHW(halfWidth) { }
336 WideSegment_25(const Point_2 &v0, const Point_2 &v1, int z, Real halfWidth) : mBase(v0, v1, z), mHW(halfWidth) { }
337
338 void _setBase(const Segment_25 &s) { mBase = s; }
339
340 Segment_25& _base() { return mBase; }
341 const Segment_25& base() const { return mBase; }
342
347 Segment_2 s2_extended(uint mask = 0x3) const;
348
349 Real halfWidth() const { return mHW; }
350 Real width() const { return mHW + mHW; }
351 Real squared_width() const { return width() * width(); }
352
353 int z() const { return mBase.z(); }
354 Point_25 source() const { return mBase.source(); }
355 Point_25 target() const { return mBase.target(); }
356 const Point_2& source_2() const { return mBase.source_2(); }
357 const Point_2& target_2() const { return mBase.target_2(); }
358
359 Circle_2 sourceCap() const { return Circle_2(source_2(), mHW * mHW); }
360 Circle_2 targetCap() const { return Circle_2(target_2(), mHW * mHW); }
361
367 int joins2D(const Point_2&, Real leewaySquared = -1.0) const;
368
369 bool widerThanBaseLen() const { return squared_width() > mBase.squared_length(); }
370
374 ::Vector_2 getHalfWidthSpan(Real delta = 0.0) const { return mBase.getPerpendicularCCW(mHW + delta); }
375
381 WideSegment_25 swapWL(Real deltaHW = 0.0, Real deltaL = 0.0) const;
382
383 WideSegment_25 opposite() const { return WideSegment_25(mBase.opposite(), halfWidth()); }
384 WideSegment_25 orderedX() const { return mBase.isXOrdered() ? *this : opposite(); }
385 WideSegment_25 orderedY() const { return mBase.isYOrdered() ? *this : opposite(); }
386
387 AShape *clone() const override { return new WideSegment_25(*this); }
388
389 uint vertexCount() const override { return 4; }
390 bool canDrawAsTriFan() const override { return true; }
391
392 bool isRound() const override { return true; }
393
394 Real unsignedArea() const override { return width() * mBase.length() + mHW * mHW * M_PI; }
395
396 Bbox_2 bbox() const override;
397
398 void transform(const CGAL::Aff_transformation_2<Kernel>&) override;
399 void translate(const ::Vector_2&) override;
400
404 void nudge(int s, int t);
405
409 WideSegment_25& rectify(Real angleTolerance) { mBase.rectify(angleTolerance); return *this; }
410
414 WideSegment_25 grown(Real) const;
415
416 bool contains(const ::Point_2&) const override;
417
418 Real squared_distance(const AShape &S) const override { return S.squared_distance(*static_cast<const WideSegment_25 *>(this)); }
419
420 Real squared_distance(const ::Point_2&) const override;
421 Real squared_distance(const Segment_2&) const override;
422 Real squared_distance(const Circle_2 &C) const override;
423 Real squared_distance(const Iso_rectangle_2 &R) const override;
424 Real squared_distance(const Triangle_2 &T) const override;
425 Real squared_distance(const Polygon_2 &P) const override;
426 Real squared_distance(const WideSegment_25&) const override;
427
428 bool intersects(const AShape &S) const override { return S.intersects(*static_cast<const WideSegment_25 *>(this)); }
429
430 bool intersects(const Circle_2 &C) const override;
431 bool intersects(const Iso_rectangle_2 &R) const override;
432 bool intersects(const Triangle_2 &T) const override;
433 bool intersects(const Polygon_2 &P) const override;
434 bool intersects(const WideSegment_25&) const override;
435
440 bool violatesClearance(const WideSegment_25&, Real clearance, Point_25 * = 0) const;
441 bool violatesClearance2D(const WideSegment_25&, Real clearance, Point_25 * = 0) const;
442
443 ::Point_2 centroid() const override { return source_2() + mBase.s2().to_vector() * 0.5; }
444
445 static WideSegment_25 fromPy(PyObject *);
446
447 std::string str() const override;
448 PyObject *getPy() const override;
449
450 PyObject *getShortPy() const;
451protected:
453 Real mHW;
454};
455inline WideSegment_25 WideSegment_25::swapWL(Real deltaHW, Real deltaL) const
456{
457 const auto M = mBase.source_2() + mBase.s2().to_vector() * 0.5;
458 const auto v = getHalfWidthSpan(deltaL * 0.5);
459 return WideSegment_25(M + v, M - v, z(), mBase.length() * 0.5 + deltaHW);
460}
461
462inline std::ostream& operator<<(std::ostream &os, const WideSegment_25 &s)
463{
464 return os << s.str();
465}
466
467#endif // GYM_PCB_ASHAPE_H
Definition AShape.hpp:21
virtual bool transformPreservesType(const CGAL::Aff_transformation_2< Kernel > &) const
Definition AShape.hpp:50
virtual void transform(const CGAL::Aff_transformation_2< Kernel > &)=0
virtual uint vertexCount() const =0
virtual AShape * transformType(const CGAL::Aff_transformation_2< Kernel > &)
virtual PyObject * getPy() const =0
Definition AShape.hpp:118
PyObject * getPy() const override
void transform(const CGAL::Aff_transformation_2< Kernel > &) override
uint vertexCount() const override
Definition AShape.hpp:126
bool transformPreservesType(const CGAL::Aff_transformation_2< Kernel > &) const override
Definition AShape.hpp:214
void transform(const CGAL::Aff_transformation_2< Kernel > &) override
Real lengthOutside(const Segment_2 &) const
AShape * transformType(const CGAL::Aff_transformation_2< Kernel > &) override
bool transformPreservesType(const CGAL::Aff_transformation_2< Kernel > &) const override
uint vertexCount() const override
Definition AShape.hpp:223
PyObject * getPy() const override
Definition Geometry.hpp:131
Definition AShape.hpp:268
PyObject * getPy() const override
uint vertexCount() const override
Definition AShape.hpp:285
void transform(const CGAL::Aff_transformation_2< Kernel > &) override
static Polygon_2 grow(const Polygon_2 &, Real size, Real epsilon=0.125)
Definition Geometry.hpp:155
Definition AShape.hpp:171
uint vertexCount() const override
Definition AShape.hpp:178
void transform(const CGAL::Aff_transformation_2< Kernel > &) override
PyObject * getPy() const override
Definition AShape.hpp:332
PyObject * getPy() const override
WideSegment_25 & rectify(Real angleTolerance)
Definition AShape.hpp:409
WideSegment_25 opposite() const
Definition AShape.hpp:383
void transform(const CGAL::Aff_transformation_2< Kernel > &) override
bool violatesClearance(const WideSegment_25 &, Real clearance, Point_25 *=0) const
Segment_2 s2_extended(uint mask=0x3) const
int joins2D(const Point_2 &, Real leewaySquared=-1.0) const
uint vertexCount() const override
Definition AShape.hpp:389
::Vector_2 getHalfWidthSpan(Real delta=0.0) const
Definition AShape.hpp:374
static WideSegment_25 fromPy(PyObject *)
void nudge(int s, int t)
Segment_25 mBase
Definition AShape.hpp:452
WideSegment_25 swapWL(Real deltaHW=0.0, Real deltaL=0.0) const
Definition AShape.hpp:455
WideSegment_25 grown(Real) const