42 if (result.size() >= 1)
76 if (result.size() == 1)
133 if (result.size() == 1)
160 if (
inter.size() == 1)
221 auto kxi =
k.cross(i);
252 Point3D a(0, 0, 0), b(3, 4, 0);
405 auto c =
tet.centroid();
417 auto f =
tet.faces();
419 for (
int i = 0; i < 4; ++i)
447 std::ostringstream
os;
449 EXPECT_NE(
os.str().find(
"Point("), std::string::npos);
457 std::ostringstream
os;
459 EXPECT_NE(
os.str().find(
"Segment("), std::string::npos);
465 std::ostringstream
os;
467 EXPECT_NE(
os.str().find(
"Triangle("), std::string::npos);
473 std::ostringstream
os;
475 EXPECT_NE(
os.str().find(
"Rectangle("), std::string::npos);
481 std::ostringstream
os;
483 EXPECT_NE(
os.str().find(
"Ellipse("), std::string::npos);
489 std::ostringstream
os;
491 EXPECT_NE(
os.str().find(
"RotatedEllipse("), std::string::npos);
504 std::ostringstream
os;
506 EXPECT_NE(
os.str().find(
"Polygon("), std::string::npos);
507 EXPECT_NE(
os.str().find(
"n=4"), std::string::npos);
508 EXPECT_NE(
os.str().find(
"closed"), std::string::npos);
515 std::ostringstream
os;
517 EXPECT_NE(
os.str().find(
"Point3D("), std::string::npos);
520 std::ostringstream
os;
522 EXPECT_NE(
os.str().find(
"Segment3D("), std::string::npos);
525 std::ostringstream
os;
527 EXPECT_NE(
os.str().find(
"Triangle3D("), std::string::npos);
530 std::ostringstream
os;
533 EXPECT_NE(
os.str().find(
"Tetrahedron("), std::string::npos);
564 size_t pos = 0,
count = 0;
565 while ((pos =
wkt.find(
"0 0", pos)) != std::string::npos)
602 EXPECT_NE(json.find(
"\"type\":\"Point\""), std::string::npos);
603 EXPECT_NE(json.find(
"\"coordinates\":["), std::string::npos);
610 EXPECT_NE(json.find(
"\"type\":\"LineString\""), std::string::npos);
618 EXPECT_NE(json.find(
"\"type\":\"Polygon\""), std::string::npos);
632 EXPECT_NE(json.find(
"\"type\":\"Polygon\""), std::string::npos);
633 EXPECT_NE(json.find(
"\"coordinates\":[["), std::string::npos);
640 EXPECT_NE(json.find(
"\"type\":\"Point\""), std::string::npos);
758 for (
size_t i = 0; i <
snap.nodes.size(); ++i)
759 if (
snap.nodes(i).is_leaf)
772 const long x =
static_cast<long>(3 * i);
773 const long y =
static_cast<long>((41 * i) % 97);
783 for (
size_t i = 0; i <
snap.nodes.size(); ++i)
784 if (
snap.nodes(i).is_leaf)
800#if __cplusplus >= 202002L
817#if __cplusplus >= 202002L && __has_include(<format>)
821# if defined(__cpp_lib_format)
826 auto s = std::format(
"{}",
Point(3, 4));
827 EXPECT_NE(s.find(
"Point("), std::string::npos);
828 EXPECT_NE(s.find(
"3"), std::string::npos);
829 EXPECT_NE(s.find(
"4"), std::string::npos);
836 EXPECT_NE(s.find(
"Segment("), std::string::npos);
843 EXPECT_NE(s.find(
"Triangle("), std::string::npos);
849 auto s = std::format(
"{}",
Rectangle(0, 0, 5, 5));
850 EXPECT_NE(s.find(
"Rectangle("), std::string::npos);
856 auto s = std::format(
"{}",
Point3D(1, 2, 3));
857 EXPECT_NE(s.find(
"Point3D("), std::string::npos);
863 EXPECT_NE(s.find(
"PolarPoint("), std::string::npos);
869 EXPECT_NE(s.find(
"Ellipse("), std::string::npos);
875 EXPECT_NE(s.find(
"RotatedEllipse("), std::string::npos);
881 EXPECT_NE(s.find(
"Segment3D("), std::string::npos);
889 EXPECT_NE(s.find(
"Triangle3D("), std::string::npos);
898 EXPECT_NE(s.find(
"Tetrahedron("), std::string::npos);
906 GTEST_SKIP() <<
"std::format header exists but __cpp_lib_format is not enabled.";
929 for (
const auto & pt : sq)
1005 return p.get_x() == 1 && p.get_y() == 1;
1009 return p.get_x() == 99;
1024 return p.get_x() >= 0 && p.get_y() >= 0;
1028 return p.get_x() > 0;
1124 L.add_vertex(
Point(6, 0));
1125 L.add_vertex(
Point(6, 3));
1126 L.add_vertex(
Point(3, 3));
1127 L.add_vertex(
Point(3, 6));
1128 L.add_vertex(
Point(0, 6));
1143 U.add_vertex(
Point(6, 0));
1144 U.add_vertex(
Point(6, 6));
1145 U.add_vertex(
Point(5, 6));
1146 U.add_vertex(
Point(5, 1));
1147 U.add_vertex(
Point(1, 1));
1148 U.add_vertex(
Point(1, 6));
1149 U.add_vertex(
Point(0, 6));
1163 for (
int i = 0; i <
N; ++i)
1258 EXPECT_EQ(result, InCircleResult::ON_CIRCLE);
1423 L.add_vertex(
Point(6, 0));
1424 L.add_vertex(
Point(6, 3));
1425 L.add_vertex(
Point(3, 3));
1426 L.add_vertex(
Point(3, 6));
1427 L.add_vertex(
Point(0, 6));
1443 for (
size_t i = 0; i < result.size(); ++i)
1452 <<
"Intersection area = " <<
total_area.get_d()
1453 <<
", expected 12 (concave polygon intersection bug?)";
1487 for (
size_t i = 0; i < result.size(); ++i)
1496 if (result.size() == 1)
1498 <<
"Union collapsed to convex hull — concave shape lost";
1529 for (
size_t i = 0; i < result.size(); ++i)
1573 auto result =
pd(sites);
1580 for (
size_t v = 0; v < result.vertices.size(); ++v)
1582 const Point & pc = result.vertices(v);
1584 for (
size_t s = 0; s < result.sites.size(); ++s)
1586 - result.sites(s).weight);
1596 <<
"Power vertex " << v <<
" is not equi-power-distant to any triple";
1621 if (
pr.vertices.size() >= 1
and vr.vertices.size() >= 1)
1628 <<
"Power vertex and Voronoi vertex differ";
1662 <<
") >= original area (" <<
orig_area.get_d()
1663 <<
") — collinear vertex bug in ConvexPolygonOffset";
1684 <<
"Inward offset of 6 on a 10x10 square should produce empty result, "
1685 <<
"but got " << result.
size() <<
" vertices";
Axis-aligned bounding box tree for spatial queries.
Rectangle root_bbox() const
Return the root bounding box (union of all entries).
size_t build(Array< size_t > &idx, const size_t lo, const size_t hi)
bool is_empty() const
Whether the tree is empty.
size_t size() const
Number of entries.
DebugSnapshot debug_snapshot() const
Return the full tree structure for visualization/debug.
Array< size_t > query(const Rectangle &query) const
Find all entries whose bounding box overlaps the query rectangle.
Array< size_t > query_point(const Point &p) const
Find all entries whose bounding box contains the query point.
Simple dynamic array with automatic resizing and functional operations.
T & append(const T &data)
Append a copy of data
void reserve(size_t cap)
Reserves cap cells into the array.
Boolean operations on simple polygons (union, intersection, difference) using the Greiner-Hormann alg...
Array< Polygon > difference(const Polygon &a, const Polygon &b) const
Convenience: difference (a minus b).
Array< Polygon > polygon_union(const Polygon &a, const Polygon &b) const
Convenience: union.
Array< Polygon > intersection(const Polygon &a, const Polygon &b) const
Convenience: intersection.
static Polygon inward(const Polygon &convex_poly, const Geom_Number &distance)
Inward offset (erosion) of a convex polygon.
Polygon triangulation using the ear-cutting algorithm.
Doubly-linked list (defined in tpl_dynList.H).
T & append(const T &item)
const Geom_Number & get_vradius() const
Gets the vertical radius.
bool intersects_with(const Segment &s) const
Checks if a segment intersects the ellipse.
const Geom_Number & get_hradius() const
Gets the horizontal radius.
bool contains(const Point &p) const
Checks if a point lies inside or on the boundary of this ellipse.
static std::string to_geojson(const Point &p)
Converts a Point to a GeoJSON geometry object.
static std::string to_wkt(const Point &p)
Converts a Point to WKT format: "POINT (x y)".
Gift wrapping (Jarvis march) convex hull algorithm.
Graham scan convex hull algorithm.
Represents a point in 3D space with exact rational coordinates.
static Point3D from_2d(const Point &p)
Lifts a 2D point to 3D, setting its z-coordinate to 0.
Geom_Number distance_squared_to(const Point3D &p) const
Squared Euclidean distance to another point.
Point3D cross(const Point3D &p) const
Cross product.
Geom_Number norm_squared() const
Squared Euclidean norm (magnitude).
Point to_2d() const
Projects this 3D point to a 2D point by dropping the z-coordinate.
Geom_Number dot(const Point3D &p) const
Dot product.
Represents a point with rectangular coordinates in a 2D plane.
const Geom_Number & get_x() const noexcept
Gets the x-coordinate value.
Geom_Number distance_squared_to(const Point &that) const
Calculates the squared Euclidean distance to another point.
bool is_colinear_with(const Point &p1, const Point &p2) const
Checks if this point is collinear with two other points.
Polar representation of a 2D point.
STL/Aleph-compatible iterator over polygon vertices as Points.
const Point & get_curr() const
bool has_curr() const noexcept
A general (irregular) 2D polygon defined by a sequence of vertices.
void add_vertex(const Point &point)
Add a vertex to the polygon.
void close()
Close the polygon.
const bool & is_closed() const
Check if the polygon is closed.
const size_t & size() const
Get the number of vertices.
bool contains(const Point &p) const
Check if a point is inside the polygon (or on its boundary).
Power diagram (weighted Voronoi diagram).
QuickHull convex hull algorithm.
An axis-aligned rectangle.
const Geom_Number & get_xmin() const
Gets the minimum x-coordinate.
const Geom_Number & get_ymax() const
Gets the maximum y-coordinate.
const Geom_Number & get_ymin() const
Gets the minimum y-coordinate.
const Geom_Number & get_xmax() const
Gets the maximum x-coordinate.
An ellipse with arbitrary rotation.
bool contains(const Point &p) const
Checks if a point lies inside or on the ellipse.
const Geom_Number & get_sin() const
Gets the sine of the rotation angle.
bool on_boundary(const Point &p) const
Checks if a point lies exactly on the ellipse boundary.
const Geom_Number & get_cos() const
Gets the cosine of the rotation angle.
Represents a line segment in 3D space.
Point3D midpoint() const
Calculates the midpoint of the segment.
bool contains(const Point3D &p) const
Checks if a point lies on the segment.
const Point3D & get_src() const noexcept
Gets the source point of the segment.
Geom_Number distance_to(const Point3D &p) const
Calculates the shortest distance from a point to this segment.
const Point3D & get_tgt() const noexcept
Gets the target point of the segment.
Point3D at(const Geom_Number &t) const
Evaluates a point on the segment via linear interpolation.
Geom_Number length_squared() const
Calculates the squared length of the segment.
Geom_Number length() const
Calculates the length of the segment.
Represents a line segment between two points.
Point mid_point() const
Returns the midpoint of this segment.
void enlarge_src(const Geom_Number &dist)
Extends the segment by a given distance from the source endpoint.
void enlarge_tgt(const Geom_Number &dist)
Extends the segment by a given distance from the target endpoint.
bool contains(const Point &p) const
Checks if a point lies on this segment.
const Point & get_tgt_point() const noexcept
Gets the target point of the segment.
const Point & get_src_point() const noexcept
Gets the source point of the segment.
Geom_Number length() const
Returns the Euclidean length of the segment.
Represents a tetrahedron in 3D space defined by four points.
Represents a triangle in 3D space defined by three points.
BaryCoords barycentric(const Point3D &p) const
Computes the barycentric coordinates of a point p with respect to this triangle.
Point3D centroid() const
Computes the centroid (center of mass) of the triangle.
Point3D normal() const
Computes the normal vector of the triangle's plane.
Geom_Number double_area_squared() const
Calculates twice the squared area of the triangle.
bool is_degenerate() const
Checks if the triangle is degenerate (i.e., its vertices are collinear).
A non-degenerate triangle defined by three points.
bool contains(const Point &p) const
Checks if a point lies strictly inside this triangle.
Voronoi diagram derived as the dual of a Delaunay triangulation.
Aleph::DynList< T > filter(Operation &operation) const
Filter the elements of a container according to a matching criterion.
bool exists(Operation &op) const
Test for existence in the container of an element satisfying a criterion.
Aleph::DynList< __T > maps(Operation &op) const
Map the elements of the container.
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
bool all(Operation &operation) const
Check if all the elements of the container satisfy a condition.
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
TEST_F(GeomAlgorithmsTest, BooleanIntersectionConcaveLShapes)
__gmp_expr< T, __gmp_binary_expr< __gmp_expr< T, U >, unsigned long int, __gmp_root_function > > root(const __gmp_expr< T, U > &expr, unsigned long int l)
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Geom_Number scalar_triple_product(const Point3D &a, const Point3D &b, const Point3D &c)
Scalar triple product: a · (b × c).
bool completed() const noexcept
Return true if all underlying iterators are finished.
size_t size(Node *root) noexcept
and
Check uniqueness with explicit hash + equality functors.
InCircleResult in_circle(const Point &a, const Point &b, const Point &c, const Point &p)
Classify point p against circumcircle of triangle (a,b,c), exactly.
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
mpq_class Geom_Number
Numeric type used by the geometry module.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
static Geom_Number polygon_area(const Polygon &poly)
bool traverse(Operation &operation) noexcept(traverse_is_noexcept< Operation >())
Traverse the container via its iterator and performs a conditioned operation on each item.