Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
polygon.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
84# ifndef POLYGON_H
85# define POLYGON_H
86
87# include <dlink.H>
88# include <point.H>
89# include <ah-errors.H>
90# include <string>
91
92using namespace Aleph;
93
112class Vertex : public Point, public Dlink
113{
114public:
117 { /* empty */
118 }
119
122 Vertex(const Point & point) : Point(point)
123 { /* empty */
124 }
125
129 Vertex(const Vertex & vertex) : Point(vertex), Dlink()
130 { /* empty */
131 }
132
137 Vertex &operator=(const Vertex & vertex)
138 {
139 if (this != &vertex)
140 Point::operator=(vertex);
141 return *this;
142 }
143
149 {
150 return static_cast<Vertex *>(link);
151 }
152
156 [[nodiscard]] static const Vertex * dlink_to_vertex(const Dlink *link)
157 {
158 return static_cast<const Vertex *>(link);
159 }
160
165 [[nodiscard]] const Vertex &prev_vertex() const
166 {
167 assert(not this->is_empty());
168
170 << "There is an only vertex";
171
172 return *dlink_to_vertex(this->get_prev());
173 }
174
179 [[nodiscard]] const Vertex &next_vertex() const
180 {
181 assert(not this->is_empty());
182
184 << "There is an only vertex";
185
186 return *dlink_to_vertex(this->get_next());
187 }
188
189 // TODO: Implement next_segment() and prev_segment() methods
190};
191
192
193class Regular_Polygon;
194
232class Polygon : public Geom_Object
233{
235 size_t num_vertex;
237
238 Point lowest;
239 Point highest;
240 Point leftmost;
241 Point rightmost;
242
245 void update_extreme_points(const Point & point)
246 {
247 if (num_vertex == 0)
248 {
249 leftmost = rightmost = lowest = highest = point;
250 return;
251 }
252
253 if (point.get_x() < leftmost.get_x())
254 leftmost = point;
255
256 if (point.get_x() > rightmost.get_x())
257 rightmost = point;
258
259 if (point.get_y() < lowest.get_y())
260 lowest = point;
261
262 if (point.get_y() > highest.get_y())
263 highest = point;
264 }
265
268 {
269 while (not vertex_list.is_empty())
271
272 num_vertex = 0;
273 __is_closed = false;
274 }
275
278 void copy_points(const Polygon & poly)
279 {
280 Dlink *list = const_cast<Dlink *>(&poly.vertex_list);
281
282 for (Dlink::Iterator it(list); it.has_curr(); it.next_ne())
283 vertex_list.append(new Vertex(*Vertex::dlink_to_vertex(it.get_curr())));
284 }
285
288 void copy_regular_polygon(const Regular_Polygon & poly);
289
290public:
293 { /* empty */
294 }
295
298 {
300 }
301
304 Polygon(const Polygon & poly)
305 : Geom_Object(poly),
307 lowest(poly.lowest), highest(poly.highest),
309 {
310 copy_points(poly);
311 }
312
316 : Polygon()
317 {
318 vertex_list.swap(poly.vertex_list);
319 std::swap(num_vertex, poly.num_vertex);
320 std::swap(__is_closed, poly.__is_closed);
321 std::swap(lowest, poly.lowest);
322 std::swap(highest, poly.highest);
323 std::swap(leftmost, poly.leftmost);
324 std::swap(rightmost, poly.rightmost);
325 }
326
332 {
334 }
335
340 {
341 if (this == &poly)
342 return *this;
343
345
346 num_vertex = poly.num_vertex;
348 lowest = poly.lowest;
349 highest = poly.highest;
350 leftmost = poly.leftmost;
351 rightmost = poly.rightmost;
352
353 copy_points(poly);
354
355 return *this;
356 }
357
361 Polygon &operator =(Polygon && poly) noexcept
362 {
363 vertex_list.swap(poly.vertex_list);
364 std::swap(num_vertex, poly.num_vertex);
365 std::swap(__is_closed, poly.__is_closed);
366 std::swap(lowest, poly.lowest);
367 std::swap(highest, poly.highest);
368 std::swap(leftmost, poly.leftmost);
369 std::swap(rightmost, poly.rightmost);
370
371 return *this;
372 }
373
378 {
381
382 return *this;
383 }
384
387 [[nodiscard]] const Point &lowest_point() const { return lowest; }
388
391 [[nodiscard]] const Point &highest_point() const { return highest; }
392
395 [[nodiscard]] const Point &leftmost_point() const { return leftmost; }
396
399 [[nodiscard]] const Point &rightmost_point() const { return rightmost; }
400
403 [[nodiscard]] const bool &is_closed() const { return __is_closed; }
404
407 [[nodiscard]] const size_t &size() const { return num_vertex; }
408
419 {
423 Vertex_Iterator(const Polygon & poly) : Dlink::Iterator(poly.vertex_list)
424 {
426 << "Polygon has not any vertex";
427 }
428
435 };
436
451 {
453
454 public:
460 {
462 << "Polygon has less than two vertex";
463 }
464
468 [[nodiscard]] bool has_curr() const
469 {
470 if (this->is_in_last())
471 return poly.is_closed() ? true : false;
472
474 }
475
480 {
482 << "Segment iterator is in the last point and "
483 << "it is not closed";
484
486
487 // Determine target: if at last vertex, wrap to first; otherwise, next
488 const Vertex & tgt =
489 this->is_in_last() ? poly.get_first_vertex() : src->next_vertex();
490
491 return Segment(*src, tgt);
492 }
493 };
494
498 [[nodiscard]] bool vertex_belong_polygon(const Vertex & v) const
499 {
500 for (Vertex_Iterator it(*this); it.has_curr(); it.next_ne())
501 if (&it.get_current_vertex() == &v)
502 return true;
503
504 return false;
505 }
506
511 {
513 << "Polygon has not any vertex";
514
516 }
517
522 {
524 << "Polygon has not any vertex";
525
527 }
528
533 [[nodiscard]] const Vertex &get_next_vertex(const Vertex & v) const
534 {
535 // If v is the last vertex (next points to sentinel), wrap to first vertex
536 return (v.get_next() == &vertex_list) ?
538 v.next_vertex();
539 }
540
545 [[nodiscard]] const Vertex &get_prev_vertex(const Vertex & v) const
546 {
547 // If v is the first vertex (prev points to sentinel), wrap to last vertex
548 return (v.get_prev() == &vertex_list) ?
550 v.prev_vertex();
551 }
552
557 {
559 << "polygon has less than two vertex";
560
562
563 return Segment(first_vertex, first_vertex.next_vertex());
564 }
565
570 {
572 << "polygon has less than two vertex";
573
575
576 return Segment(last_vertex.prev_vertex(), last_vertex);
577 }
578
582 [[nodiscard]] bool intersects_with(const Segment & sg)
583 {
584 // Traverse all edges and check for intersection
585 for (Segment_Iterator it(*this); it.has_curr(); it.next_ne())
586 {
587 const Segment & curr_side = it.get_current_segment();
588 if (curr_side.intersects_with(sg))
589 return true;
590 }
591
592 return false;
593 }
594
610 void add_vertex(const Point & point)
611 {
613 << "Polygon is already closed";
614
615 // Check if the new point is colinear with the last segment
616 if (num_vertex > 1)
617 {
619 if (point.is_colinear_with(last_sg))
620 {
621 ah_domain_error_if(point.is_inside(last_sg))
622 << "new vertex is inside of last polygon's segment";
623
624 // Colinear point: replace the last vertex with this new one
625 Vertex & last_vertex = const_cast<Vertex &>(get_last_vertex());
626 Point & last_point = last_vertex;
627 last_point = point;
628
630
631 return;
632 }
633 }
634
635 // If we have at least 3 vertices, verify no self-intersection
636 if (num_vertex >= 3)
637 {
638 // New edge that would be formed by adding this point
639 const Segment new_side(get_last_vertex(), point);
640
641 // Check for intersection with all edges except the last one
642 // (which shares a vertex with the new edge)
643 for (Segment_Iterator it(*this); true; it.next_ne())
644 {
645 const Segment curr_side = it.get_current_segment();
646
648 break;
649
650 ah_domain_error_if(curr_side.intersects_with(new_side))
651 << "new side intersects";
652 }
653 }
654
655 // Insert new vertex
656 vertex_list.append(new Vertex(point));
658 ++num_vertex;
659 }
660
666 void add_vertex(const Geom_Number & x, const Geom_Number & y)
667 {
668 add_vertex(Point(x, y));
669 }
670
680 void remove_vertex(const Vertex & v)
681 {
682 Vertex *victim = nullptr;
683 for (Vertex_Iterator it(*this); it.has_curr(); it.next_ne())
684 if (&it.get_current_vertex() == &v)
685 {
686 victim = &const_cast<Vertex &>(it.get_current_vertex());
687 break;
688 }
689
690 ah_domain_error_if(victim == nullptr)
691 << "Vertex does not belong to polygon";
692
693 // TODO: Handle colinearity cases
694
695 victim->del();
696 --num_vertex;
697 delete victim;
698 }
699
710 void close()
711 {
713 << "Polygon is already closed";
714
715 if (num_vertex >= 4)
716 {
717 // Check for intersection with all edges except the first
718 // and last (which share endpoints with the closing edge)
720
721 Segment_Iterator it(*this);
722
723 for (it.next(); true; it.next_ne())
724 {
726
728 break;
729
730 ah_domain_error_if(curr_side.intersects_with(last_side))
731 << "closing causes an intersection";
732 }
733 }
734
735 __is_closed = true;
736 }
737
751 [[nodiscard]] bool contains_to(const Point & p)
752 {
754 << "Polygon is not closed";
755
756 Segment_Iterator it(*this);
757
758 bool test = p.is_to_left_from(it.get_current_segment());
759
760 it.next();
761
762 for (/* nothing */ ; it.has_curr(); it.next_ne())
763 if (p.is_to_left_from(it.get_current_segment()) != test)
764 return false;
765
766 return true;
767 }
768
777 {
778 add_vertex(tr.get_p1());
779 add_vertex(tr.get_p2());
780 add_vertex(tr.get_p3());
781
782 close();
783 }
784};
785
786
829{
830 Point center;
831 double side_size;
832 size_t num_vertex;
833 double angle;
834 double r;
835 double beta;
836
837public:
840 { /* empty */
841 }
842
851 Regular_Polygon(const Point & c,
852 const double & side_sz,
853 const size_t & n,
854 const double & ang = 0)
855 : center(c), side_size(side_sz), num_vertex(n), angle(ang), beta(2 * PI / n)
856 {
857 ah_domain_error_if(n < 3)
858 << "Polygon sides is less than 3";
859
860 // Calculate radius using law of sines with angles between vertices
861 // and the angle between radius and side
862 const double alpha = (PI - beta) / 2; // angle between radius and side
863 r = side_size * sin(alpha) / sin(beta);
864 }
865
868 [[nodiscard]] const double &get_side_size() const { return side_size; }
869
872 [[nodiscard]] const Point &get_center() const { return center; }
873
876 [[nodiscard]] const size_t &size() const { return num_vertex; }
877
880 [[nodiscard]] const double &radius() const { return r; }
881
884 [[nodiscard]] bool is_closed() const { return true; }
885
895 [[nodiscard]] const Point get_vertex(const size_t & i) const
896 {
898 << "vertex " << std::to_string(i) << " is greater than "
899 << std::to_string(num_vertex);
900
901 // First segment is the negative vertical from center
902 // Initial point is the target of this segment with origin at center
903 Segment sg(center, center - Point(0, r));
904
905 sg.rotate(i * beta + angle);
906
907 return sg.get_tgt_point();
908 }
909
912 [[nodiscard]] const Point get_first_vertex() const { return get_vertex(0); }
913
916 [[nodiscard]] const Point get_last_vertex() const { return get_vertex(num_vertex - 1); }
917
921 {
922 return Segment(get_vertex(0), get_vertex(1));
923 }
924
928 {
929 return Segment(get_vertex(0), get_vertex(num_vertex - 1));
930 }
931
944 {
946 size_t curr;
948
949 public:
953 : poly(__poly), curr(0)
954 {
955 // empty
956 }
957
960 [[nodiscard]] bool has_curr() const { return curr < poly.size(); }
961
966 {
968 << "Iterator has not current";
969
971
972 return vertex;
973 }
974
976 void next_ne() noexcept { ++curr; }
977
980 void next()
981 {
983 << "Iterator has not current";
984 next_ne();
985 }
986
989 void prev()
990 {
991 --curr;
992
994 << "Iterator has not current";
995 }
996 };
997
1010 {
1012 size_t curr;
1013
1014 public:
1018 : poly(__poly), curr(0)
1019 {
1020 // empty
1021 }
1022
1025 [[nodiscard]] bool has_curr() const { return curr < poly.size(); }
1026
1031 {
1033 << "Iterator has not current";
1034
1035 return Segment(poly.get_vertex(curr),
1036 poly.get_vertex((curr + 1) % poly.size()));
1037 }
1038
1040 void next_ne() noexcept { ++curr; }
1041
1044 void next()
1045 {
1047 << "Iterator has not current";
1048 next_ne();
1049 }
1050
1053 void prev()
1054 {
1055 --curr;
1056
1058 << "Iterator has not current";
1059 }
1060 };
1061
1066 [[nodiscard]] Point lowest_point() const { return center + Point(0, -r); }
1067
1070 [[nodiscard]] Point highest_point() const { return center + Point(0, r); }
1071
1074 [[nodiscard]] Point leftmost_point() const { return center + Point(-r, 0); }
1075
1078 [[nodiscard]] Point rightmost_point() const { return center + Point(r, 0); }
1079};
1080
1086{
1088
1089 for (size_t i = 0; i < poly.size(); ++i)
1090 add_vertex(poly.get_vertex(i));
1091
1092 close();
1093}
1094
1095#endif // POLYGON_H
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:579
#define ah_underflow_error_if(C)
Throws std::underflow_error if condition holds.
Definition ah-errors.H:368
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
Definition ah-errors.H:463
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Definition ah-errors.H:522
Iterator over the edges (segments) of a polygon.
Definition polygon.H:451
Segment_Iterator(const Polygon &__poly)
Construct segment iterator from a polygon.
Definition polygon.H:458
Segment get_current_segment() const
Get the current segment (edge).
Definition polygon.H:479
Polygon & poly
Reference to the polygon being iterated.
Definition polygon.H:452
bool has_curr() const
Check if there is a current segment.
Definition polygon.H:468
A general (irregular) 2D polygon defined by a sequence of vertices.
Definition polygon.H:233
Polygon(const Polygon &poly)
Copy constructor.
Definition polygon.H:304
Polygon(Polygon &&poly) noexcept
Move constructor.
Definition polygon.H:315
bool __is_closed
True if the polygon has been closed.
Definition polygon.H:236
Segment get_first_segment()
Get the first edge (segment) of the polygon.
Definition polygon.H:556
Dlink vertex_list
Doubly-linked list of vertices.
Definition polygon.H:234
void close()
Close the polygon.
Definition polygon.H:710
Polygon & operator=(const Polygon &poly)
Copy assignment operator.
Definition polygon.H:339
const Vertex & get_last_vertex() const
Get the last vertex of the polygon.
Definition polygon.H:521
const Point & rightmost_point() const
Get the vertex with the maximum x-coordinate.
Definition polygon.H:399
void copy_points(const Polygon &poly)
Copy all vertices from another polygon.
Definition polygon.H:278
size_t num_vertex
Number of vertices in the polygon.
Definition polygon.H:235
const bool & is_closed() const
Check if the polygon is closed.
Definition polygon.H:403
Segment get_last_segment()
Get the last edge (segment) of the polygon.
Definition polygon.H:569
void add_vertex(const Geom_Number &x, const Geom_Number &y)
Add a vertex using coordinates.
Definition polygon.H:666
Point rightmost
Vertex with maximum x-coordinate.
Definition polygon.H:241
void remove_vertex(const Vertex &v)
Remove a vertex from the polygon.
Definition polygon.H:680
const Vertex & get_next_vertex(const Vertex &v) const
Get the vertex after the given vertex.
Definition polygon.H:533
Point lowest
Vertex with minimum y-coordinate.
Definition polygon.H:238
const size_t & size() const
Get the number of vertices.
Definition polygon.H:407
Point highest
Vertex with maximum y-coordinate.
Definition polygon.H:239
const Point & leftmost_point() const
Get the vertex with the minimum x-coordinate.
Definition polygon.H:395
const Vertex & get_first_vertex() const
Get the first vertex of the polygon.
Definition polygon.H:510
void add_vertex(const Point &point)
Add a vertex to the polygon.
Definition polygon.H:610
Polygon()
Default constructor. Creates an empty, open polygon.
Definition polygon.H:292
const Vertex & get_prev_vertex(const Vertex &v) const
Get the vertex before the given vertex.
Definition polygon.H:545
~Polygon()
Destructor. Frees all vertices.
Definition polygon.H:297
void copy_regular_polygon(const Regular_Polygon &poly)
Copy vertices from a regular polygon.
Definition polygon.H:1085
const Point & highest_point() const
Get the vertex with the maximum y-coordinate.
Definition polygon.H:391
bool intersects_with(const Segment &sg)
Check if a segment intersects with any edge of the polygon.
Definition polygon.H:582
Point leftmost
Vertex with minimum x-coordinate.
Definition polygon.H:240
bool vertex_belong_polygon(const Vertex &v) const
Check if a vertex belongs to this polygon.
Definition polygon.H:498
Polygon(const Regular_Polygon &poly)
Construct from a Regular_Polygon.
Definition polygon.H:330
void delete_points()
Delete all vertices and reset the polygon state.
Definition polygon.H:267
bool contains_to(const Point &p)
Check if a point is inside the polygon.
Definition polygon.H:751
const Point & lowest_point() const
Get the vertex with the minimum y-coordinate.
Definition polygon.H:387
void update_extreme_points(const Point &point)
Update extreme points after adding a new vertex.
Definition polygon.H:245
Polygon(const Triangle &tr)
Construct a polygon from a Triangle.
Definition polygon.H:775
Iterator over the edges (segments) of a regular polygon.
Definition polygon.H:1010
void next_ne() noexcept
Advance to next segment (no exception on overflow).
Definition polygon.H:1040
const Regular_Polygon & poly
Reference to the polygon.
Definition polygon.H:1011
const Segment get_current_segment() const
Get the current segment (edge).
Definition polygon.H:1030
Segment_Iterator(const Regular_Polygon &__poly)
Construct segment iterator from a regular polygon.
Definition polygon.H:1017
size_t curr
Current segment index.
Definition polygon.H:1012
void next()
Advance to next segment.
Definition polygon.H:1044
bool has_curr() const
Check if there is a current segment.
Definition polygon.H:1025
void prev()
Move to previous segment.
Definition polygon.H:1053
Iterator over the vertices of a regular polygon.
Definition polygon.H:944
Vertex_Iterator(const Regular_Polygon &__poly)
Construct iterator from a regular polygon.
Definition polygon.H:952
void prev()
Move to previous vertex.
Definition polygon.H:989
bool has_curr() const
Check if there is a current vertex.
Definition polygon.H:960
const Regular_Polygon & poly
Reference to the polygon.
Definition polygon.H:945
void next_ne() noexcept
Advance to next vertex (no exception on overflow).
Definition polygon.H:976
Vertex & get_current_vertex()
Get the current vertex.
Definition polygon.H:965
void next()
Advance to next vertex.
Definition polygon.H:980
Vertex vertex
Cache for compatibility with Polygon::Vertex_Iterator.
Definition polygon.H:947
size_t curr
Current vertex index.
Definition polygon.H:946
A regular polygon defined by center, side length, and vertex count.
Definition polygon.H:829
const Point get_first_vertex() const
Get the first vertex (index 0).
Definition polygon.H:912
const Point & get_center() const
Get the center point.
Definition polygon.H:872
double beta
Central angle between adjacent vertices (2π/n)
Definition polygon.H:835
double side_size
Length of each side.
Definition polygon.H:831
Point highest_point() const
Get the highest point of the bounding circle.
Definition polygon.H:1070
Point leftmost_point() const
Get the leftmost point of the bounding circle.
Definition polygon.H:1074
Point rightmost_point() const
Get the rightmost point of the bounding circle.
Definition polygon.H:1078
double angle
Rotation angle in radians.
Definition polygon.H:833
const Point get_last_vertex() const
Get the last vertex (index size()-1).
Definition polygon.H:916
Point center
Center point of the polygon.
Definition polygon.H:830
const size_t & size() const
Get the number of vertices.
Definition polygon.H:876
Segment get_first_segment() const
Get the first segment (edge).
Definition polygon.H:920
const double & get_side_size() const
Get the side length.
Definition polygon.H:868
size_t num_vertex
Number of vertices (sides)
Definition polygon.H:832
Point lowest_point() const
Get the lowest point of the bounding circle.
Definition polygon.H:1066
Regular_Polygon(const Point &c, const double &side_sz, const size_t &n, const double &ang=0)
Construct a regular polygon.
Definition polygon.H:851
Segment get_last_segment() const
Get the last segment (closing edge).
Definition polygon.H:927
const Point get_vertex(const size_t &i) const
Get the i-th vertex of the polygon.
Definition polygon.H:895
Regular_Polygon()
Default constructor. Creates an invalid empty polygon.
Definition polygon.H:839
bool is_closed() const
Check if the polygon is closed.
Definition polygon.H:884
double r
Circumradius (distance from center to vertices)
Definition polygon.H:834
const double & radius() const
Get the circumradius.
Definition polygon.H:880
Fundamental segment defined by two points.
Definition point.H:417
const Point & get_tgt_point() const
Definition point.H:470
void rotate(const double &angle)
Rotate the segment by angle (radians) around the source point.
Definition point.H:820
A vertex in a polygon's doubly-linked vertex list.
Definition polygon.H:113
static Vertex * dlink_to_vertex(Dlink *link)
Convert a Dlink pointer to a Vertex pointer.
Definition polygon.H:148
Vertex(const Vertex &vertex)
Copy constructor.
Definition polygon.H:129
Vertex & operator=(const Vertex &vertex)
Copy assignment operator.
Definition polygon.H:137
Vertex()
Default constructor. Creates a vertex at origin (0, 0).
Definition polygon.H:116
const Vertex & next_vertex() const
Get the next vertex in the polygon.
Definition polygon.H:179
const Vertex & prev_vertex() const
Get the previous vertex in the polygon.
Definition polygon.H:165
Vertex(const Point &point)
Construct a vertex from a Point.
Definition polygon.H:122
static const Vertex * dlink_to_vertex(const Dlink *link)
Convert a const Dlink pointer to a const Vertex pointer.
Definition polygon.H:156
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_sin_function > > sin(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4070
static mpfr_t y
Definition mpfr_mul_d.c:3
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
auto get_curr() const
Return the current tuple (bounds-checked).
Definition ah-zip.H:149
DynList< T > maps(const C &c, Op op)
Classic map operation.
2D point and geometric utilities.
constexpr double PI
Definition point.H:85
Iterator over the vertices of a polygon.
Definition polygon.H:419
Vertex_Iterator(const Polygon &poly)
Construct iterator from a polygon.
Definition polygon.H:423
Vertex & get_current_vertex()
Get the current vertex.
Definition polygon.H:431
void test(unsigned long n, gsl_rng *r)