-
-
Notifications
You must be signed in to change notification settings - Fork 15
fix(Distace): use dichotomic method to compute segment segment distan… #1244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
75c892c
7499f7a
f3652c2
63b0c88
2e29255
8d22b35
b117e00
02c43f2
a5d0a1d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -476,81 +476,37 @@ namespace | |||||
| } | ||||||
| return std::make_tuple( min_distance, point0, point1 ); | ||||||
| } | ||||||
| } // namespace | ||||||
|
|
||||||
| namespace geode | ||||||
| { | ||||||
| template < index_t dimension > | ||||||
| double point_point_distance( | ||||||
| const Point< dimension >& point0, const Point< dimension >& point1 ) | ||||||
| { | ||||||
| double diff2{ 0 }; | ||||||
| for( const auto d : LRange{ dimension } ) | ||||||
| { | ||||||
| const auto diff = point0.value( d ) - point1.value( d ); | ||||||
| diff2 += diff * diff; | ||||||
| } | ||||||
| return std::sqrt( diff2 ); | ||||||
| } | ||||||
|
|
||||||
| template < index_t dimension > | ||||||
| double point_segment_distance( | ||||||
| const Point< dimension >& point, const Segment< dimension >& segment ) | ||||||
| { | ||||||
| const auto length = segment.length(); | ||||||
| const auto length0 = | ||||||
| point_point_distance( segment.vertices()[0].get(), point ); | ||||||
| if( length <= GLOBAL_EPSILON ) | ||||||
| { | ||||||
| return length0; | ||||||
| } | ||||||
| const auto length1 = | ||||||
| point_point_distance( segment.vertices()[1].get(), point ); | ||||||
| const auto sqr_length = length * length; | ||||||
| const auto sqr_length0 = length0 * length0; | ||||||
| const auto sqr_length1 = length1 * length1; | ||||||
| if( length0 >= length && length0 >= length1 | ||||||
| && sqr_length + sqr_length1 <= sqr_length0 ) | ||||||
| { // obtuse by vertex 1 | ||||||
| return length1; | ||||||
| } | ||||||
| if( length1 >= length && length1 >= length0 | ||||||
| && sqr_length + sqr_length0 <= sqr_length1 ) | ||||||
| { // obtuse by vertex 0 | ||||||
| return length0; | ||||||
| } | ||||||
| // acute angles | ||||||
| if( const auto distance = | ||||||
| compute_point_line_distance( length, length0, length1 ) ) | ||||||
| { | ||||||
| return distance.value(); | ||||||
| } | ||||||
| return std::get< 0 >( | ||||||
| point_segment_distance_using_projection( point, segment ) ); | ||||||
| } | ||||||
|
|
||||||
| template < index_t dimension > | ||||||
| std::tuple< double, Point< dimension >, Point< dimension > > | ||||||
| segment_segment_distance( const Segment< dimension >& segment0, | ||||||
| const Segment< dimension >& segment1 ) | ||||||
| template < geode::index_t dimension > | ||||||
| std::optional< std::tuple< double, | ||||||
| geode::Point< dimension >, | ||||||
| geode::Point< dimension > > > | ||||||
| approximate_segment_segment_distance( | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: function 'approximate_segment_segment_distance' is declared in an anonymous namespace; prefer using 'static' for restricting visibility [llvm-prefer-static-over-anonymous-namespace] approximate_segment_segment_distance(
^
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: function 'approximate_segment_segment_distance' has cognitive complexity of 99 (threshold 10) [readability-function-cognitive-complexity] approximate_segment_segment_distance(
^Additional contextsrc/geode/geometry/distance.cpp:502: +1, including nesting penalty of 0, nesting level increased to 1 if( ac > bb )
^src/geode/geometry/distance.cpp:504: +2, including nesting penalty of 1, nesting level increased to 2 if( std::log2( std::abs( ac ) / std::abs( ac - bb ) ) > 20 )
^src/geode/geometry/distance.cpp:511: +2, including nesting penalty of 1, nesting level increased to 2 if( bte <= ctd ) // s <= 0
^src/geode/geometry/distance.cpp:514: +3, including nesting penalty of 2, nesting level increased to 3 if( e <= 0 ) // t <= 0
^src/geode/geometry/distance.cpp:519: +4, including nesting penalty of 3, nesting level increased to 4 if( nd >= a )
^src/geode/geometry/distance.cpp:523: +1, nesting level increased to 4 else if( nd > 0 )
^src/geode/geometry/distance.cpp:529: +1, nesting level increased to 3 else if( e < c ) // 0 < t < 1
^src/geode/geometry/distance.cpp:534: +1, nesting level increased to 3 else // t >= 1
^src/geode/geometry/distance.cpp:539: +4, including nesting penalty of 3, nesting level increased to 4 if( bmd >= a )
^src/geode/geometry/distance.cpp:543: +1, nesting level increased to 4 else if( bmd > 0 )
^src/geode/geometry/distance.cpp:550: +1, nesting level increased to 2 else // s > 0
^src/geode/geometry/distance.cpp:552: +3, including nesting penalty of 2, nesting level increased to 3 if( std::log2( std::abs( bte ) / std::abs( bte - ctd ) ) > 20 )
^src/geode/geometry/distance.cpp:557: +3, including nesting penalty of 2, nesting level increased to 3 if( s >= det ) // s >= 1
^src/geode/geometry/distance.cpp:562: +4, including nesting penalty of 3, nesting level increased to 4 if( bpe <= 0 ) // t <= 0
^src/geode/geometry/distance.cpp:567: +5, including nesting penalty of 4, nesting level increased to 5 if( nd <= 0 )
^src/geode/geometry/distance.cpp:571: +1, nesting level increased to 5 else if( nd < a )
^src/geode/geometry/distance.cpp:577: +1, nesting level increased to 4 else if( bpe < c ) // 0 < t < 1
^src/geode/geometry/distance.cpp:582: +1, nesting level increased to 4 else // t >= 1
^src/geode/geometry/distance.cpp:587: +5, including nesting penalty of 4, nesting level increased to 5 if( bmd <= 0 )
^src/geode/geometry/distance.cpp:591: +1, nesting level increased to 5 else if( bmd < a )
^src/geode/geometry/distance.cpp:598: +1, nesting level increased to 3 else // 0 < s < 1
^src/geode/geometry/distance.cpp:602: +4, including nesting penalty of 3, nesting level increased to 4 if( ate <= btd ) // t <= 0
^src/geode/geometry/distance.cpp:607: +5, including nesting penalty of 4, nesting level increased to 5 if( nd <= 0 )
^src/geode/geometry/distance.cpp:611: +1, nesting level increased to 5 else if( nd >= a )
^src/geode/geometry/distance.cpp:615: +1, nesting level increased to 5 else
^src/geode/geometry/distance.cpp:620: +1, nesting level increased to 4 else // t > 0
^src/geode/geometry/distance.cpp:622: +5, including nesting penalty of 4, nesting level increased to 5 if( std::log2( std::abs( ate ) / std::abs( ate - btd ) )
^src/geode/geometry/distance.cpp:628: +5, including nesting penalty of 4, nesting level increased to 5 if( t >= det ) // t >= 1
^src/geode/geometry/distance.cpp:633: +6, including nesting penalty of 5, nesting level increased to 6 if( bmd <= 0 )
^src/geode/geometry/distance.cpp:637: +1, nesting level increased to 6 else if( bmd >= a )
^src/geode/geometry/distance.cpp:641: +1, nesting level increased to 6 else
^src/geode/geometry/distance.cpp:646: +1, nesting level increased to 5 else // 0 < t < 1
^src/geode/geometry/distance.cpp:656: +1, nesting level increased to 1 else
^src/geode/geometry/distance.cpp:676: +2, including nesting penalty of 1, nesting level increased to 2 if( e <= 0 ) // t <= 0
^src/geode/geometry/distance.cpp:681: +3, including nesting penalty of 2, nesting level increased to 3 if( nd <= 0 ) // s <= 0
^src/geode/geometry/distance.cpp:686: +1, nesting level increased to 3 else if( nd >= a ) // s >= 1
^src/geode/geometry/distance.cpp:691: +1, nesting level increased to 3 else // 0 < s < 1
^src/geode/geometry/distance.cpp:697: +1, nesting level increased to 2 else if( e >= c ) // t >= 1
^src/geode/geometry/distance.cpp:702: +3, including nesting penalty of 2, nesting level increased to 3 if( bmd <= 0 ) // s <= 0
^src/geode/geometry/distance.cpp:707: +1, nesting level increased to 3 else if( bmd >= a ) // s >= 1
^src/geode/geometry/distance.cpp:712: +1, nesting level increased to 3 else // 0 < s < 1
^src/geode/geometry/distance.cpp:718: +1, nesting level increased to 2 else // 0 < t < 1
^src/geode/geometry/distance.cpp:733: +1, including nesting penalty of 0, nesting level increased to 1 if( distance < geode::GLOBAL_EPSILON )
^src/geode/geometry/distance.cpp:740: +1, including nesting penalty of 0, nesting level increased to 1 if( distance_to_closest0 < geode::GLOBAL_EPSILON )
^src/geode/geometry/distance.cpp:747: +1, including nesting penalty of 0, nesting level increased to 1 if( distance_to_closest1 < geode::GLOBAL_EPSILON )
^src/geode/geometry/distance.cpp:753: +1, including nesting penalty of 0, nesting level increased to 1 if( distance_to_closest0 < distance )
^src/geode/geometry/distance.cpp:755: +2, including nesting penalty of 1, nesting level increased to 2 if( distance_to_closest1 < distance_to_closest0 )
^src/geode/geometry/distance.cpp:764: +1, including nesting penalty of 0, nesting level increased to 1 if( distance_to_closest1 < distance )
^
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: function 'approximate_segment_segment_distance' has cognitive complexity of 99 (threshold 10) [readability-function-cognitive-complexity] approximate_segment_segment_distance(
^Additional contextsrc/geode/geometry/distance.cpp:504: +1, including nesting penalty of 0, nesting level increased to 1 if( ac > bb )
^src/geode/geometry/distance.cpp:506: +2, including nesting penalty of 1, nesting level increased to 2 if( std::log2( std::abs( ac ) / std::abs( ac - bb ) ) > 20 )
^src/geode/geometry/distance.cpp:515: +2, including nesting penalty of 1, nesting level increased to 2 if( bte <= ctd ) // s <= 0
^src/geode/geometry/distance.cpp:518: +3, including nesting penalty of 2, nesting level increased to 3 if( e <= 0 ) // t <= 0
^src/geode/geometry/distance.cpp:523: +4, including nesting penalty of 3, nesting level increased to 4 if( nd >= a )
^src/geode/geometry/distance.cpp:527: +1, nesting level increased to 4 else if( nd > 0 )
^src/geode/geometry/distance.cpp:533: +1, nesting level increased to 3 else if( e < c ) // 0 < t < 1
^src/geode/geometry/distance.cpp:538: +1, nesting level increased to 3 else // t >= 1
^src/geode/geometry/distance.cpp:543: +4, including nesting penalty of 3, nesting level increased to 4 if( bmd >= a )
^src/geode/geometry/distance.cpp:547: +1, nesting level increased to 4 else if( bmd > 0 )
^src/geode/geometry/distance.cpp:554: +1, nesting level increased to 2 else // s > 0
^src/geode/geometry/distance.cpp:556: +3, including nesting penalty of 2, nesting level increased to 3 if( std::log2( std::abs( bte ) / std::abs( bte - ctd ) ) > 20 )
^src/geode/geometry/distance.cpp:563: +3, including nesting penalty of 2, nesting level increased to 3 if( s >= det ) // s >= 1
^src/geode/geometry/distance.cpp:568: +4, including nesting penalty of 3, nesting level increased to 4 if( bpe <= 0 ) // t <= 0
^src/geode/geometry/distance.cpp:573: +5, including nesting penalty of 4, nesting level increased to 5 if( nd <= 0 )
^src/geode/geometry/distance.cpp:577: +1, nesting level increased to 5 else if( nd < a )
^src/geode/geometry/distance.cpp:583: +1, nesting level increased to 4 else if( bpe < c ) // 0 < t < 1
^src/geode/geometry/distance.cpp:588: +1, nesting level increased to 4 else // t >= 1
^src/geode/geometry/distance.cpp:593: +5, including nesting penalty of 4, nesting level increased to 5 if( bmd <= 0 )
^src/geode/geometry/distance.cpp:597: +1, nesting level increased to 5 else if( bmd < a )
^src/geode/geometry/distance.cpp:604: +1, nesting level increased to 3 else // 0 < s < 1
^src/geode/geometry/distance.cpp:608: +4, including nesting penalty of 3, nesting level increased to 4 if( ate <= btd ) // t <= 0
^src/geode/geometry/distance.cpp:613: +5, including nesting penalty of 4, nesting level increased to 5 if( nd <= 0 )
^src/geode/geometry/distance.cpp:617: +1, nesting level increased to 5 else if( nd >= a )
^src/geode/geometry/distance.cpp:621: +1, nesting level increased to 5 else
^src/geode/geometry/distance.cpp:626: +1, nesting level increased to 4 else // t > 0
^src/geode/geometry/distance.cpp:628: +5, including nesting penalty of 4, nesting level increased to 5 if( std::log2( std::abs( ate ) / std::abs( ate - btd ) )
^src/geode/geometry/distance.cpp:636: +5, including nesting penalty of 4, nesting level increased to 5 if( t >= det ) // t >= 1
^src/geode/geometry/distance.cpp:641: +6, including nesting penalty of 5, nesting level increased to 6 if( bmd <= 0 )
^src/geode/geometry/distance.cpp:645: +1, nesting level increased to 6 else if( bmd >= a )
^src/geode/geometry/distance.cpp:649: +1, nesting level increased to 6 else
^src/geode/geometry/distance.cpp:654: +1, nesting level increased to 5 else // 0 < t < 1
^src/geode/geometry/distance.cpp:664: +1, nesting level increased to 1 else
^src/geode/geometry/distance.cpp:684: +2, including nesting penalty of 1, nesting level increased to 2 if( e <= 0 ) // t <= 0
^src/geode/geometry/distance.cpp:689: +3, including nesting penalty of 2, nesting level increased to 3 if( nd <= 0 ) // s <= 0
^src/geode/geometry/distance.cpp:694: +1, nesting level increased to 3 else if( nd >= a ) // s >= 1
^src/geode/geometry/distance.cpp:699: +1, nesting level increased to 3 else // 0 < s < 1
^src/geode/geometry/distance.cpp:705: +1, nesting level increased to 2 else if( e >= c ) // t >= 1
^src/geode/geometry/distance.cpp:710: +3, including nesting penalty of 2, nesting level increased to 3 if( bmd <= 0 ) // s <= 0
^src/geode/geometry/distance.cpp:715: +1, nesting level increased to 3 else if( bmd >= a ) // s >= 1
^src/geode/geometry/distance.cpp:720: +1, nesting level increased to 3 else // 0 < s < 1
^src/geode/geometry/distance.cpp:726: +1, nesting level increased to 2 else // 0 < t < 1
^src/geode/geometry/distance.cpp:741: +1, including nesting penalty of 0, nesting level increased to 1 if( distance < geode::GLOBAL_EPSILON )
^src/geode/geometry/distance.cpp:748: +1, including nesting penalty of 0, nesting level increased to 1 if( distance_to_closest0 < geode::GLOBAL_EPSILON )
^src/geode/geometry/distance.cpp:755: +1, including nesting penalty of 0, nesting level increased to 1 if( distance_to_closest1 < geode::GLOBAL_EPSILON )
^src/geode/geometry/distance.cpp:761: +1, including nesting penalty of 0, nesting level increased to 1 if( distance_to_closest0 < distance )
^src/geode/geometry/distance.cpp:763: +2, including nesting penalty of 1, nesting level increased to 2 if( distance_to_closest1 < distance_to_closest0 )
^src/geode/geometry/distance.cpp:772: +1, including nesting penalty of 0, nesting level increased to 1 if( distance_to_closest1 < distance )
^ |
||||||
| const geode::Segment< dimension >& segment0, | ||||||
| const geode::Segment< dimension >& segment1 ) | ||||||
| { | ||||||
| /* Algorithm and code found on | ||||||
| * https://github.com/davideberly/GeometricTools/blob/master/GTE/Mathematics/DistSegmentSegment.h | ||||||
| */ | ||||||
| const auto P1mP0 = segment0.direction(); | ||||||
| const auto Q1mQ0 = segment1.direction(); | ||||||
| const Vector< dimension > P0mQ0{ segment1.vertices()[0], | ||||||
| const geode::Vector< dimension > P0mQ0{ segment1.vertices()[0], | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: invalid case style for variable 'P0mQ0' [readability-identifier-naming]
Suggested change
src/geode/geometry/distance.cpp:497: - const auto d = P1mP0.dot( P0mQ0 );
- const auto e = Q1mQ0.dot( P0mQ0 );
+ const auto d = P1mP0.dot( p0m_q0 );
+ const auto e = Q1mQ0.dot( p0m_q0 ); |
||||||
| segment0.vertices()[0] }; | ||||||
| const auto a = P1mP0.dot( P1mP0 ); | ||||||
| const auto b = P1mP0.dot( Q1mQ0 ); | ||||||
| const auto c = Q1mQ0.dot( Q1mQ0 ); | ||||||
| const auto d = P1mP0.dot( P0mQ0 ); | ||||||
| const auto e = Q1mQ0.dot( P0mQ0 ); | ||||||
| const auto det = a * c - b * b; | ||||||
| const auto ac = a * c; | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: variable name 'ac' is too short, expected at least 3 characters [readability-identifier-length] const auto ac = a * c;
^ |
||||||
| const auto bb = b * b; | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: variable name 'bb' is too short, expected at least 3 characters [readability-identifier-length] const auto bb = b * b;
^ |
||||||
| double s, t, nd, bmd, bte, ctd, bpe, ate, btd; | ||||||
|
|
||||||
| if( det > 0 ) | ||||||
| if( ac > bb ) | ||||||
| { | ||||||
| if( std::log2( std::abs( ac ) / std::abs( ac - bb ) ) > 20 ) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: 20 is a magic number; consider replacing it with a named constant [cppcoreguidelines-avoid-magic-numbers] if( std::log2( std::abs( ac ) / std::abs( ac - bb ) ) > 20 )
^ |
||||||
| { | ||||||
| return std::nullopt; | ||||||
| } | ||||||
| const auto det = ac - bb; | ||||||
| bte = b * e; | ||||||
| ctd = c * d; | ||||||
| if( bte <= ctd ) // s <= 0 | ||||||
|
|
@@ -594,6 +550,10 @@ namespace geode | |||||
| } | ||||||
| else // s > 0 | ||||||
| { | ||||||
| if( std::log2( std::abs( bte ) / std::abs( bte - ctd ) ) > 20 ) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: 20 is a magic number; consider replacing it with a named constant [cppcoreguidelines-avoid-magic-numbers] if( std::log2( std::abs( bte ) / std::abs( bte - ctd ) ) > 20 )
^ |
||||||
| { | ||||||
| return std::nullopt; | ||||||
| } | ||||||
| s = bte - ctd; | ||||||
| if( s >= det ) // s >= 1 | ||||||
| { | ||||||
|
|
@@ -660,6 +620,11 @@ namespace geode | |||||
| } | ||||||
| else // t > 0 | ||||||
| { | ||||||
| if( std::log2( std::abs( ate ) / std::abs( ate - btd ) ) | ||||||
| > 20 ) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: 20 is a magic number; consider replacing it with a named constant [cppcoreguidelines-avoid-magic-numbers] > 20 )
^ |
||||||
| { | ||||||
| return std::nullopt; | ||||||
| } | ||||||
| t = ate - btd; | ||||||
| if( t >= det ) // t >= 1 | ||||||
| { | ||||||
|
|
@@ -766,21 +731,21 @@ namespace geode | |||||
| segment1.vertices()[0].get() + Q1mQ0 * t; | ||||||
| const auto distance = | ||||||
| point_point_distance( closest_on_segment0, closest_on_segment1 ); | ||||||
| if( distance < GLOBAL_EPSILON ) | ||||||
| if( distance < geode::GLOBAL_EPSILON ) | ||||||
| { | ||||||
| return std::make_tuple( | ||||||
| distance, closest_on_segment0, closest_on_segment1 ); | ||||||
| } | ||||||
| const auto distance_to_closest0 = | ||||||
| point_segment_distance( closest_on_segment0, segment1 ); | ||||||
| if( distance_to_closest0 < GLOBAL_EPSILON ) | ||||||
| if( distance_to_closest0 < geode::GLOBAL_EPSILON ) | ||||||
| { | ||||||
| return std::make_tuple( distance_to_closest0, closest_on_segment0, | ||||||
| point_segment_projection( closest_on_segment0, segment1 ) ); | ||||||
| } | ||||||
| const auto distance_to_closest1 = | ||||||
| point_segment_distance( closest_on_segment1, segment0 ); | ||||||
| if( distance_to_closest1 < GLOBAL_EPSILON ) | ||||||
| if( distance_to_closest1 < geode::GLOBAL_EPSILON ) | ||||||
| { | ||||||
| return std::make_tuple( distance_to_closest1, | ||||||
| point_segment_projection( closest_on_segment1, segment0 ), | ||||||
|
|
@@ -807,6 +772,121 @@ namespace geode | |||||
| distance, closest_on_segment0, closest_on_segment1 ); | ||||||
| } | ||||||
|
|
||||||
| template < geode::index_t dimension > | ||||||
| std::tuple< double, geode::Point< dimension >, geode::Point< dimension > > | ||||||
| dichotomic_segment_segment_distance( | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: function 'dichotomic_segment_segment_distance' is declared in an anonymous namespace; prefer using 'static' for restricting visibility [llvm-prefer-static-over-anonymous-namespace] dichotomic_segment_segment_distance(
^ |
||||||
| const geode::Segment< dimension >& segment0, | ||||||
| const geode::Segment< dimension >& segment1 ) | ||||||
| { | ||||||
| const auto longest_segment = | ||||||
| ( segment0.length() > segment1.length() ) ? segment0 : segment1; | ||||||
| const auto shortest_segment = | ||||||
| ( segment0.length() < segment1.length() ) ? segment0 : segment1; | ||||||
| auto current_point = | ||||||
| ( geode::point_segment_distance( | ||||||
| longest_segment.vertices()[0].get(), shortest_segment ) | ||||||
| < geode::point_segment_distance( | ||||||
| longest_segment.vertices()[1].get(), shortest_segment ) ) | ||||||
| ? longest_segment.vertices()[0].get() | ||||||
| : longest_segment.vertices()[1].get(); | ||||||
| auto step = longest_segment.length() / 2; | ||||||
| auto current_distance = | ||||||
| geode::point_segment_distance( current_point, shortest_segment ); | ||||||
| const auto segment_direction = longest_segment.normalized_direction(); | ||||||
| while( step > geode::GLOBAL_EPSILON ) | ||||||
| { | ||||||
| const auto point_at_step_plus = | ||||||
| current_point + segment_direction * step; | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
Suggested change
|
||||||
| const auto point_at_step_minus = | ||||||
| current_point - segment_direction * step; | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: '*' has higher precedence than '-'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
Suggested change
|
||||||
| const auto distance_plus = geode::point_segment_distance( | ||||||
| point_at_step_plus, shortest_segment ); | ||||||
| const auto distance_minus = geode::point_segment_distance( | ||||||
| point_at_step_minus, shortest_segment ); | ||||||
| if( distance_plus < current_distance | ||||||
| && current_point != longest_segment.vertices()[1].get() ) | ||||||
| { | ||||||
| current_distance = distance_plus; | ||||||
| current_point = point_at_step_plus; | ||||||
| } | ||||||
| if( distance_minus < current_distance | ||||||
| && current_point != longest_segment.vertices()[0].get() ) | ||||||
| { | ||||||
| current_distance = distance_minus; | ||||||
| current_point = point_at_step_minus; | ||||||
| } | ||||||
| step /= 2; | ||||||
| } | ||||||
| return std::make_tuple( | ||||||
| current_distance, current_point, current_point ); | ||||||
| } | ||||||
|
|
||||||
| } // namespace | ||||||
|
|
||||||
| namespace geode | ||||||
| { | ||||||
| template < index_t dimension > | ||||||
| double point_point_distance( | ||||||
| const Point< dimension >& point0, const Point< dimension >& point1 ) | ||||||
| { | ||||||
| double diff2{ 0 }; | ||||||
| for( const auto d : LRange{ dimension } ) | ||||||
| { | ||||||
| const auto diff = point0.value( d ) - point1.value( d ); | ||||||
| diff2 += diff * diff; | ||||||
| } | ||||||
| return std::sqrt( diff2 ); | ||||||
| } | ||||||
|
|
||||||
| template < index_t dimension > | ||||||
| double point_segment_distance( | ||||||
| const Point< dimension >& point, const Segment< dimension >& segment ) | ||||||
| { | ||||||
| const auto length = segment.length(); | ||||||
| const auto length0 = | ||||||
| point_point_distance( segment.vertices()[0].get(), point ); | ||||||
| if( length <= GLOBAL_EPSILON ) | ||||||
| { | ||||||
| return length0; | ||||||
| } | ||||||
| const auto length1 = | ||||||
| point_point_distance( segment.vertices()[1].get(), point ); | ||||||
| const auto sqr_length = length * length; | ||||||
| const auto sqr_length0 = length0 * length0; | ||||||
| const auto sqr_length1 = length1 * length1; | ||||||
| if( length0 >= length && length0 >= length1 | ||||||
| && sqr_length + sqr_length1 <= sqr_length0 ) | ||||||
| { // obtuse by vertex 1 | ||||||
| return length1; | ||||||
| } | ||||||
| if( length1 >= length && length1 >= length0 | ||||||
| && sqr_length + sqr_length0 <= sqr_length1 ) | ||||||
| { // obtuse by vertex 0 | ||||||
| return length0; | ||||||
| } | ||||||
| // acute angles | ||||||
| if( const auto distance = | ||||||
| compute_point_line_distance( length, length0, length1 ) ) | ||||||
| { | ||||||
| return distance.value(); | ||||||
| } | ||||||
| return std::get< 0 >( | ||||||
| point_segment_distance_using_projection( point, segment ) ); | ||||||
| } | ||||||
|
|
||||||
| template < index_t dimension > | ||||||
| std::tuple< double, Point< dimension >, Point< dimension > > | ||||||
| segment_segment_distance( const Segment< dimension >& segment0, | ||||||
| const Segment< dimension >& segment1 ) | ||||||
| { | ||||||
| if( const auto approximation = | ||||||
| approximate_segment_segment_distance( segment0, segment1 ) ) | ||||||
| { | ||||||
| return approximation.value(); | ||||||
| } | ||||||
| return dichotomic_segment_segment_distance( segment0, segment1 ); | ||||||
| } | ||||||
|
|
||||||
| template < index_t dimension > | ||||||
| std::tuple< double, Point< dimension >, Point< dimension > > | ||||||
| segment_line_distance( const Segment< dimension >& segment, | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: function 'approximate_segment_segment_distance' has cognitive complexity of 98 (threshold 10) [readability-function-cognitive-complexity]
approximate_segment_segment_distance( ^Additional context
src/geode/geometry/distance.cpp:501: +1, including nesting penalty of 0, nesting level increased to 1
src/geode/geometry/distance.cpp:507: +1, including nesting penalty of 0, nesting level increased to 1
src/geode/geometry/distance.cpp:511: +2, including nesting penalty of 1, nesting level increased to 2
src/geode/geometry/distance.cpp:514: +3, including nesting penalty of 2, nesting level increased to 3
src/geode/geometry/distance.cpp:519: +4, including nesting penalty of 3, nesting level increased to 4
if( nd >= a ) ^src/geode/geometry/distance.cpp:523: +1, nesting level increased to 4
src/geode/geometry/distance.cpp:529: +1, nesting level increased to 3
src/geode/geometry/distance.cpp:534: +1, nesting level increased to 3
src/geode/geometry/distance.cpp:539: +4, including nesting penalty of 3, nesting level increased to 4
if( bmd >= a ) ^src/geode/geometry/distance.cpp:543: +1, nesting level increased to 4
src/geode/geometry/distance.cpp:550: +1, nesting level increased to 2
src/geode/geometry/distance.cpp:552: +3, including nesting penalty of 2, nesting level increased to 3
src/geode/geometry/distance.cpp:557: +3, including nesting penalty of 2, nesting level increased to 3
src/geode/geometry/distance.cpp:562: +4, including nesting penalty of 3, nesting level increased to 4
src/geode/geometry/distance.cpp:567: +5, including nesting penalty of 4, nesting level increased to 5
src/geode/geometry/distance.cpp:571: +1, nesting level increased to 5
src/geode/geometry/distance.cpp:577: +1, nesting level increased to 4
src/geode/geometry/distance.cpp:582: +1, nesting level increased to 4
src/geode/geometry/distance.cpp:587: +5, including nesting penalty of 4, nesting level increased to 5
src/geode/geometry/distance.cpp:591: +1, nesting level increased to 5
src/geode/geometry/distance.cpp:598: +1, nesting level increased to 3
src/geode/geometry/distance.cpp:602: +4, including nesting penalty of 3, nesting level increased to 4
src/geode/geometry/distance.cpp:607: +5, including nesting penalty of 4, nesting level increased to 5
src/geode/geometry/distance.cpp:611: +1, nesting level increased to 5
src/geode/geometry/distance.cpp:615: +1, nesting level increased to 5
else ^src/geode/geometry/distance.cpp:620: +1, nesting level increased to 4
src/geode/geometry/distance.cpp:622: +5, including nesting penalty of 4, nesting level increased to 5
if( std::log2( std::abs( ate ) / std::abs( ate - btd ) ) ^src/geode/geometry/distance.cpp:628: +5, including nesting penalty of 4, nesting level increased to 5
src/geode/geometry/distance.cpp:633: +6, including nesting penalty of 5, nesting level increased to 6
src/geode/geometry/distance.cpp:637: +1, nesting level increased to 6
src/geode/geometry/distance.cpp:641: +1, nesting level increased to 6
else ^src/geode/geometry/distance.cpp:646: +1, nesting level increased to 5
src/geode/geometry/distance.cpp:656: +1, nesting level increased to 1
else ^src/geode/geometry/distance.cpp:676: +2, including nesting penalty of 1, nesting level increased to 2
src/geode/geometry/distance.cpp:681: +3, including nesting penalty of 2, nesting level increased to 3
src/geode/geometry/distance.cpp:686: +1, nesting level increased to 3
src/geode/geometry/distance.cpp:691: +1, nesting level increased to 3
src/geode/geometry/distance.cpp:697: +1, nesting level increased to 2
src/geode/geometry/distance.cpp:702: +3, including nesting penalty of 2, nesting level increased to 3
src/geode/geometry/distance.cpp:707: +1, nesting level increased to 3
src/geode/geometry/distance.cpp:712: +1, nesting level increased to 3
src/geode/geometry/distance.cpp:718: +1, nesting level increased to 2
src/geode/geometry/distance.cpp:733: +1, including nesting penalty of 0, nesting level increased to 1
if( distance < geode::GLOBAL_EPSILON ) ^src/geode/geometry/distance.cpp:740: +1, including nesting penalty of 0, nesting level increased to 1
if( distance_to_closest0 < geode::GLOBAL_EPSILON ) ^src/geode/geometry/distance.cpp:747: +1, including nesting penalty of 0, nesting level increased to 1
if( distance_to_closest1 < geode::GLOBAL_EPSILON ) ^src/geode/geometry/distance.cpp:753: +1, including nesting penalty of 0, nesting level increased to 1
if( distance_to_closest0 < distance ) ^src/geode/geometry/distance.cpp:755: +2, including nesting penalty of 1, nesting level increased to 2
if( distance_to_closest1 < distance_to_closest0 ) ^src/geode/geometry/distance.cpp:764: +1, including nesting penalty of 0, nesting level increased to 1
if( distance_to_closest1 < distance ) ^