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)
769#if __cplusplus >= 202002L
786#if __cplusplus >= 202002L && __has_include(<format>)
790# if defined(__cpp_lib_format)
795 auto s = std::format(
"{}",
Point(3, 4));
796 EXPECT_NE(s.find(
"Point("), std::string::npos);
797 EXPECT_NE(s.find(
"3"), std::string::npos);
798 EXPECT_NE(s.find(
"4"), std::string::npos);
805 EXPECT_NE(s.find(
"Segment("), std::string::npos);
812 EXPECT_NE(s.find(
"Triangle("), std::string::npos);
818 auto s = std::format(
"{}",
Rectangle(0, 0, 5, 5));
819 EXPECT_NE(s.find(
"Rectangle("), std::string::npos);
825 auto s = std::format(
"{}",
Point3D(1, 2, 3));
826 EXPECT_NE(s.find(
"Point3D("), std::string::npos);
832 EXPECT_NE(s.find(
"PolarPoint("), std::string::npos);
838 EXPECT_NE(s.find(
"Ellipse("), std::string::npos);
844 EXPECT_NE(s.find(
"RotatedEllipse("), std::string::npos);
850 EXPECT_NE(s.find(
"Segment3D("), std::string::npos);
858 EXPECT_NE(s.find(
"Triangle3D("), std::string::npos);
867 EXPECT_NE(s.find(
"Tetrahedron("), std::string::npos);
875 GTEST_SKIP() <<
"std::format header exists but __cpp_lib_format is not enabled.";
898 for (
const auto & pt : sq)
974 return p.get_x() == 1 && p.get_y() == 1;
978 return p.get_x() == 99;
993 return p.get_x() >= 0 && p.get_y() >= 0;
997 return p.get_x() > 0;
1093 L.add_vertex(
Point(6, 0));
1094 L.add_vertex(
Point(6, 3));
1095 L.add_vertex(
Point(3, 3));
1096 L.add_vertex(
Point(3, 6));
1097 L.add_vertex(
Point(0, 6));
1112 U.add_vertex(
Point(6, 0));
1113 U.add_vertex(
Point(6, 6));
1114 U.add_vertex(
Point(5, 6));
1115 U.add_vertex(
Point(5, 1));
1116 U.add_vertex(
Point(1, 1));
1117 U.add_vertex(
Point(1, 6));
1118 U.add_vertex(
Point(0, 6));
1132 for (
int i = 0; i <
N; ++i)
1227 EXPECT_EQ(result, InCircleResult::ON_CIRCLE);
1392 L.add_vertex(
Point(6, 0));
1393 L.add_vertex(
Point(6, 3));
1394 L.add_vertex(
Point(3, 3));
1395 L.add_vertex(
Point(3, 6));
1396 L.add_vertex(
Point(0, 6));
1412 for (
size_t i = 0; i < result.size(); ++i)
1421 <<
"Intersection area = " <<
total_area.get_d()
1422 <<
", expected 12 (concave polygon intersection bug?)";
1456 for (
size_t i = 0; i < result.size(); ++i)
1465 if (result.size() == 1)
1467 <<
"Union collapsed to convex hull — concave shape lost";
1498 for (
size_t i = 0; i < result.size(); ++i)
1542 auto result =
pd(sites);
1549 for (
size_t v = 0; v < result.vertices.size(); ++v)
1551 const Point &
pc = result.vertices(v);
1553 for (
size_t s = 0; s < result.sites.size(); ++s)
1554 pds.
append(
pc.distance_squared_to(result.sites(s).position)
1555 - result.sites(s).weight);
1565 <<
"Power vertex " << v <<
" is not equi-power-distant to any triple";
1590 if (
pr.vertices.size() >= 1
and vr.vertices.size() >= 1)
1597 <<
"Power vertex and Voronoi vertex differ";
1631 <<
") >= original area (" <<
orig_area.get_d()
1632 <<
") — collinear vertex bug in ConvexPolygonOffset";
1653 <<
"Inward offset of 6 on a 10x10 square should produce empty result, "
1654 <<
"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
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.
Dynamic singly linked list with functional programming support.
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.
bool all(Operation &operation) const
Check if all the elements of the container satisfy a condition.
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Aleph::DynList< __T > maps(Operation &op) const
Map the elements of the container.
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)
and
Check uniqueness with explicit hash + equality functors.
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
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.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
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.