Skip to content

intersection returns geometrically degenerate linestring (size < 2) for tangent line #1448

@nilsnolde

Description

@nilsnolde

With boost 1.89, consider the following program where we compute the intersection of a box and a tangent line:

code
  #include <boost/geometry.hpp>                                                                                                                                                                                   
  #include <boost/geometry/geometries/point_xy.hpp>                                                                                                                                                               
  #include <boost/geometry/geometries/linestring.hpp>                                                                                                                                                             
  #include <boost/geometry/geometries/box.hpp>                                                                                                                                                                    
  #include <boost/geometry/geometries/multi_linestring.hpp>                                                                                                                                                       
  #include <iostream>                                                                                                                                                                                             
                                                                                                                                                                                                                  
  namespace bg = boost::geometry;                                                                                                                                                                                 
                                                                                                                                                                                                                  
  int main() {                                                                                                                                                                                                    
      using point_t = bg::model::d2::point_xy<int32_t>;                                                                                                                                                               
      using linestring_t = bg::model::linestring<point_t>;                                                                                                                                                        
      using box_t = bg::model::box<point_t>;                                                                                                                                                                      
      using multi_linestring_t = bg::model::multi_linestring<linestring_t>;                                                                                                                                       
                                                                                                                                                                                                                  
      box_t clip_box{{0, 0}, {4096, 4096}};                                                                                                                                                                       
                                                                                                                                                                                                                  
      // Line with one point exactly on the box border (4096, 4000)                                                                                                                                               
      // and the other point outside the box (4100, 4010)                                                                                                                                                         
      linestring_t line{{4100, 4000}, {4100, 4010}};                                                                                                                                                              
                                                                                                                                                                                                                  
      multi_linestring_t result;                                                                                                                                                                                  
      bg::intersection(line, clip_box, result);                                                                                                                                                                   
                                                                                                                                                                                                                  
      std::cout << "Input line: " << bg::wkt(line) << "\n";                                                                                                                                                       
      std::cout << "Clip box: " << bg::wkt(clip_box) << "\n";                                                                                                                                                     
      std::cout << "Result size: " << result.size() << "\n";                                                                                                                                                      
                                                                                                                                                                                                                  
      for (size_t i = 0; i < result.size(); ++i) {                                                                                                                                                                
          std::cout << "Result[" << i << "]: " << bg::wkt(result[i])                                                                                                                                              
                    << " (num_points=" << result[i].size() << ")\n";                                                                                                                                              
      }                                                                                                                                                                                                                         
                                                                                                                                                                                                                  
      return 0;                                                                                                                                                                                                   
  }                                                                                                                                                                                                      

Compile with g++ -std=c++17 -o boost_intersection_bug boost_intersection_bug.cpp and run ./boost_intersection_bug.

The output would be

  Input line: LINESTRING(4096 4000,4100 4010)                                                                                                                                                                     
  Clip box: POLYGON((0 0,0 4096,4096 4096,4096 0,0 0))             
  Result size: 1                                                                                                                                                                                                  
  Result[0]: LINESTRING(4096 4000) (num_points=1)

I'd have hoped for Result size: 0 because there is actually no intersection for all practical purposes well, that's bit far.. I understand that it's geometrically correct that the intersection is a point, but type-wise it's more a bug IMHO to return an invalid linestring type.

Sorry if this is a duplicate, skimming the issues didn't surface anything like-wise.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions