From 1bc458d5b0dfb4efd97be490addd6522f13386a1 Mon Sep 17 00:00:00 2001 From: BenPinet Date: Mon, 2 Mar 2026 16:59:58 +0100 Subject: [PATCH 1/4] feat(IspointInside): check if a point is inside a polygon --- include/geode/geometry/is_point_inside.hpp | 42 +++++++++++ src/geode/geometry/CMakeLists.txt | 2 + src/geode/geometry/is_point_inside.cpp | 84 ++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 include/geode/geometry/is_point_inside.hpp create mode 100644 src/geode/geometry/is_point_inside.cpp diff --git a/include/geode/geometry/is_point_inside.hpp b/include/geode/geometry/is_point_inside.hpp new file mode 100644 index 000000000..6892b5163 --- /dev/null +++ b/include/geode/geometry/is_point_inside.hpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019 - 2026 Geode-solutions + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#pragma once + +#include +#include +#include + +namespace geode +{ + /*! + * Find if point is inside a polygon. + * @param[in] point The point to rotate. + * @param[in] axis Axis for the rotation (not null but not necessary + * normalized). + * @param[in] angle Rotation angle expresses in radians. + */ + [[nodiscard]] bool opengeode_geometry_api is_point_inside_polygon( + const Point2D& point, absl::Span< const Point2D > polygon_points ); + +} // namespace geode \ No newline at end of file diff --git a/src/geode/geometry/CMakeLists.txt b/src/geode/geometry/CMakeLists.txt index 973cc2456..b70775c6e 100644 --- a/src/geode/geometry/CMakeLists.txt +++ b/src/geode/geometry/CMakeLists.txt @@ -47,6 +47,7 @@ add_geode_library( "information.cpp" "intersection.cpp" "intersection_detection.cpp" + "is_point_inside.cpp" "mensuration.cpp" "nn_search.cpp" "normal_frame_transform.cpp" @@ -86,6 +87,7 @@ add_geode_library( "information.hpp" "intersection.hpp" "intersection_detection.hpp" + "is_point_inside.hpp" "mensuration.hpp" "nn_search.hpp" "normal_frame_transform.hpp" diff --git a/src/geode/geometry/is_point_inside.cpp b/src/geode/geometry/is_point_inside.cpp new file mode 100644 index 000000000..929e89eb9 --- /dev/null +++ b/src/geode/geometry/is_point_inside.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019 - 2026 Geode-solutions + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include + +#include + +namespace +{ + double is_left( const geode::Point2D& p0, + const geode::Point2D& p1, + const geode::Point2D& p2 ) + { + return ( p1.value( 0 ) - p0.value( 0 ) ) + * ( p2.value( 1 ) - p0.value( 1 ) ) + - ( p2.value( 0 ) - p0.value( 0 ) ) + * ( p1.value( 1 ) - p0.value( 1 ) ); + } +} // namespace + +namespace geode +{ + bool opengeode_geometry_api is_point_inside_polygon( + const Point2D& point, absl::Span< const Point2D > polygon_points ) + { + double widing_number{ 0 }; + DEBUG( "is_point_inside_polygon" ); + SDEBUG( point ); + for( const auto polygon_vertex : + geode::Range{ 0, polygon_points.size() } ) + { + const auto v0 = polygon_points[polygon_vertex]; + const auto next_polygon_vertex = + ( polygon_vertex + 1 ) % polygon_points.size(); + const auto v1 = polygon_points[next_polygon_vertex]; + SDEBUG( v0 ); + SDEBUG( v1 ); + if( v0.value( 1 ) <= point.value( 1 ) ) + { + if( v1.value( 1 ) > point.value( 1 ) ) + { + if( is_left( v0, v1, point ) > 0 ) + { + DEBUG( "widing_number++" ); + widing_number++; + } + } + } + else + { + if( v1.value( 1 ) <= point.value( 1 ) ) + { + if( is_left( v0, v1, point ) < 0 ) + { + DEBUG( "widing_number--" ); + widing_number--; + } + } + } + } + DEBUG( widing_number ); + return widing_number != 0; + } +} // namespace geode \ No newline at end of file From 15b4e2c0f8c1112faffde656c9d0223a322f878f Mon Sep 17 00:00:00 2001 From: Pierre Anquez Date: Mon, 2 Mar 2026 21:38:16 +0100 Subject: [PATCH 2/4] PR review --- include/geode/geometry/is_point_inside.hpp | 15 +++--- src/geode/geometry/is_point_inside.cpp | 53 ++++++++++------------ 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/include/geode/geometry/is_point_inside.hpp b/include/geode/geometry/is_point_inside.hpp index 6892b5163..a928e9a38 100644 --- a/include/geode/geometry/is_point_inside.hpp +++ b/include/geode/geometry/is_point_inside.hpp @@ -23,20 +23,23 @@ #pragma once -#include #include -#include + +namespace geode +{ + FORWARD_DECLARATION_DIMENSION_CLASS( Point ); + FORWARD_DECLARATION_DIMENSION_CLASS( Polygon ); + ALIAS_2D( Point ); + ALIAS_2D( Polygon ); +} // namespace geode namespace geode { /*! * Find if point is inside a polygon. * @param[in] point The point to rotate. - * @param[in] axis Axis for the rotation (not null but not necessary - * normalized). - * @param[in] angle Rotation angle expresses in radians. */ [[nodiscard]] bool opengeode_geometry_api is_point_inside_polygon( - const Point2D& point, absl::Span< const Point2D > polygon_points ); + const Point2D& point, const Polygon2D& polygon ); } // namespace geode \ No newline at end of file diff --git a/src/geode/geometry/is_point_inside.cpp b/src/geode/geometry/is_point_inside.cpp index 929e89eb9..ac9db7c91 100644 --- a/src/geode/geometry/is_point_inside.cpp +++ b/src/geode/geometry/is_point_inside.cpp @@ -23,62 +23,57 @@ #include -#include +#include +#include namespace { - double is_left( const geode::Point2D& p0, + bool is_left( const geode::Point2D& p0, const geode::Point2D& p1, const geode::Point2D& p2 ) { return ( p1.value( 0 ) - p0.value( 0 ) ) - * ( p2.value( 1 ) - p0.value( 1 ) ) - - ( p2.value( 0 ) - p0.value( 0 ) ) - * ( p1.value( 1 ) - p0.value( 1 ) ); + * ( p2.value( 1 ) - p0.value( 1 ) ) + - ( p2.value( 0 ) - p0.value( 0 ) ) + * ( p1.value( 1 ) - p0.value( 1 ) ) + > 0; } } // namespace namespace geode { - bool opengeode_geometry_api is_point_inside_polygon( - const Point2D& point, absl::Span< const Point2D > polygon_points ) + bool is_point_inside_polygon( + const Point2D& point, const Polygon2D& polygon ) { - double widing_number{ 0 }; - DEBUG( "is_point_inside_polygon" ); - SDEBUG( point ); - for( const auto polygon_vertex : - geode::Range{ 0, polygon_points.size() } ) + double winding_number{ 0 }; + const auto& vertices = polygon.vertices(); + for( const auto polygon_vertex : geode::Range{ polygon.nb_vertices() } ) { - const auto v0 = polygon_points[polygon_vertex]; - const auto next_polygon_vertex = - ( polygon_vertex + 1 ) % polygon_points.size(); - const auto v1 = polygon_points[next_polygon_vertex]; - SDEBUG( v0 ); - SDEBUG( v1 ); - if( v0.value( 1 ) <= point.value( 1 ) ) + const auto& v0 = vertices[polygon_vertex]; + const auto& next_polygon_vertex = + ( polygon_vertex + 1 ) % vertices.size(); + const auto& v1 = vertices[next_polygon_vertex]; + if( v0.get().value( 1 ) <= point.value( 1 ) ) { - if( v1.value( 1 ) > point.value( 1 ) ) + if( v1.get().value( 1 ) > point.value( 1 ) ) { - if( is_left( v0, v1, point ) > 0 ) + if( is_left( v0, v1, point ) ) { - DEBUG( "widing_number++" ); - widing_number++; + winding_number++; } } } else { - if( v1.value( 1 ) <= point.value( 1 ) ) + if( v1.get().value( 1 ) <= point.value( 1 ) ) { - if( is_left( v0, v1, point ) < 0 ) + if( !is_left( v0, v1, point ) ) { - DEBUG( "widing_number--" ); - widing_number--; + winding_number--; } } } } - DEBUG( widing_number ); - return widing_number != 0; + return winding_number != 0; } } // namespace geode \ No newline at end of file From 181a4edc0dfbc43140f55c94fca8d9ea0d0d2308 Mon Sep 17 00:00:00 2001 From: BenPinet <126688250+BenPinet@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:23:14 +0000 Subject: [PATCH 3/4] Apply prepare changes --- .clang-tidy | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index c5d55af02..20868d455 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -8,6 +8,7 @@ Checks: > -fuchsia*, -llvmlibc*, -llvm-header-guard, + -llvm-prefer-static-over-anonymous-namespace, -misc-no-recursion, -modernize-use-trailing-return-type, -readability-redundant-access-specifiers, @@ -15,19 +16,19 @@ Checks: > -cppcoreguidelines-avoid-const-or-ref-data-members CheckOptions: - - key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic - value: '1' + - key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic + value: "1" - key: readability-identifier-length.MinimumLoopCounterNameLength value: 1 - key: readability-identifier-length.IgnoredVariableNames - value: '^[defijkptuvw]$' + value: "^[defijkptuvw]$" # More options here: https://clang.llvm.org/extra/clang-tidy/checks/readability/identifier-naming.html - key: readability-identifier-naming.NamespaceCase value: lower_case - key: readability-identifier-naming.ClassCase - value: CamelCase + value: CamelCase - key: readability-identifier-naming.StructCase - value: CamelCase + value: CamelCase - key: readability-identifier-naming.FunctionCase value: lower_case - key: readability-identifier-naming.VariableCase @@ -51,14 +52,12 @@ CheckOptions: - key: readability-identifier-naming.GlobalFunctionCase value: lower_case - key: readability-identifier-naming.MemberConstantCase - value: CamelCase + value: CamelCase - key: readability-identifier-naming.StaticConstantCase - value: lower_case + value: lower_case - key: readability-function-cognitive-complexity.Threshold value: 10 - key: readability-function-size.ParameterThreshold value: 4 - key: misc-include-cleaner.IgnoreHeaders - value: utility;cstddef;geode/.*_export\.h;geode/.*/common\.h;geode/basic/types\.h;geode/basic/assert\.h; - - + value: utility;cstddef;geode/.*_export\.h;geode/.*/common\.h;geode/basic/types\.h;geode/basic/assert\.h; From 27303374918ad9f083cfa15cb12e734e664265a4 Mon Sep 17 00:00:00 2001 From: BenPinet Date: Fri, 6 Mar 2026 14:30:11 +0100 Subject: [PATCH 4/4] wip --- src/geode/geometry/distance.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/geode/geometry/distance.cpp b/src/geode/geometry/distance.cpp index a7a8cc0bf..f368f8e1c 100644 --- a/src/geode/geometry/distance.cpp +++ b/src/geode/geometry/distance.cpp @@ -500,14 +500,10 @@ namespace const auto ac = a * c; const auto bb = b * b; double s, t, nd, bmd, bte, ctd, bpe, ate, btd; - DEBUG( ac ); - DEBUG( bb ); if( ac > bb ) { if( std::log2( std::abs( ac ) / std::abs( ac - bb ) ) > 20 ) { - DEBUG( "DET" ); - DEBUG( std::log2( std::abs( ac ) / std::abs( ac - bb ) ) ); return std::nullopt; } const auto det = ac - bb; @@ -556,8 +552,6 @@ namespace { if( std::log2( std::abs( bte ) / std::abs( bte - ctd ) ) > 20 ) { - DEBUG( - std::log2( std::abs( bte ) / std::abs( bte - ctd ) ) ); return std::nullopt; } s = bte - ctd; @@ -629,8 +623,6 @@ namespace if( std::log2( std::abs( ate ) / std::abs( ate - btd ) ) > 20 ) { - DEBUG( std::log2( - std::abs( ate ) / std::abs( ate - btd ) ) ); return std::nullopt; } t = ate - btd;