geometry icon indicating copy to clipboard operation
geometry copied to clipboard

Inconsistent Results from crosses() with Equivalent Geometries

Open uncleysh opened this issue 4 years ago • 4 comments

Input:

#include "boost/geometry.hpp"
#include <iostream>

namespace bg = boost::geometry;
typedef bg::model::d2::point_xy<float> Point;
typedef bg::model::linestring<Point> Linestring;
typedef bg::model::polygon<Point> Polygon;

int main() {
  Polygon poly;
  auto &o = poly.outer();
  o.push_back(Point(-41.72930145263671875f, -33.68047332763671875f));
  o.push_back(Point(-41.729339599609375f, -11.68046855926513671875f));
  o.push_back(Point(-47.73418426513671875f, -11.6804676055908203125f));
  o.push_back(Point(-47.73418426513671875f, 15.7195301055908203125f));
  o.push_back(Point(-36.33417510986328125f, 15.7195301055908203125f));
  o.push_back(Point(-36.334136962890625f, -6.28046894073486328125f));
  o.push_back(Point(-29.7302703857421875f, -6.28046894073486328125f));
  o.push_back(Point(-29.730274200439453125f, 15.7195301055908203125f));
  o.push_back(Point(-12.3253917694091796875f, 15.7195301055908203125f));
  o.push_back(Point(-12.3253936767578125f, -6.28046894073486328125f));
  o.push_back(Point(0.2726857662200927734375f, -6.28046894073486328125f));
  o.push_back(Point(0.2726562023162841796875f, 15.7195301055908203125f));
  o.push_back(Point(11.6726551055908203125f, 15.7195301055908203125f));
  o.push_back(Point(11.6726551055908203125f, -33.68047332763671875f));
  o.push_back(Point(-17.731250762939453125f, -33.68047332763671875f));
  o.push_back(Point(-17.7312469482421875f, -11.68046855926513671875f));
  o.push_back(Point(-24.3244171142578125f, -11.68046855926513671875f));
  o.push_back(Point(-24.324413299560546875f, -33.68047332763671875f));
  o.push_back(Point(-41.72930145263671875f, -33.68047332763671875f));

  Linestring line1(
      {Point(-65.7273406982421875f, -6.280469417572021484375f),
       Point(0.2726857662200927734375f, -6.28046894073486328125f)});
  Linestring line2({line1[1], line1[0]});

  std::cout << "Poly valid: " << bg::is_valid(poly) << std::endl;
  std::cout << "Line1 valid: " << bg::is_valid(line1) << std::endl;
  std::cout << "Line2 valid: " << bg::is_valid(line2) << std::endl;
  std::cout << "Lines equivalent: " << bg::equals(line1, line2) << std::endl;
  std::cout << std::endl;

  std::cout << "Line1 crosses: " << bg::crosses(line1, poly) << std::endl;
  std::cout << "Line2 crosses: " << bg::crosses(line2, poly) << std::endl;

  return 0;
}

Output:

Poly valid: 1
Line1 valid: 1
Line2 valid: 1
Lines equivalent: 1

Line1 crosses: 1
Line2 crosses: 0

The ordering of the points in the line segment affects the results of crosses(). In this particular case, I believe both tests should return true. I'm using g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 and boost geometry 1.75.0.

uncleysh avatar Mar 22 '21 15:03 uncleysh

I cannot reproduce the error mentioned by @uncleysh. The code mentioned above outputs,

Poly valid: 1
Line1 valid: 1
Line2 valid: 1
Lines equivalent: 1

Line1 crosses: 1
Line2 crosses: 1

This is the expected behavior and no longer an issue. Output generated by Visual Studio 2019 on Windows 10 using boost.geometry 1.76.0. @awulkiew @vissarion @mloskot, the issue can be closed.

ayushgupta138 avatar Apr 27 '21 12:04 ayushgupta138

I have retested using boost geometry 1.76.0, still using the above code and g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 and still receive the same (incorrect) output. Does boost geometry only support Windows?

uncleysh avatar Apr 27 '21 14:04 uncleysh

@uncleysh @ayushgupta138

Thanks for the report and trying to reproduce it.

Does boost geometry only support Windows?

No, with different compilers floating point operations can give different results. There are plenty cases like that. In some of them we can do something about it and in other not so much. We have to see what's really happening.

This is (...) no longer an issue.

I wouldn't be so sure about that. :)

awulkiew avatar May 06 '21 19:05 awulkiew

I will test the above code using the GNU compilers on Ubuntu 20.04 and try to find out the precision errors.

I wouldn't be so sure about that. :)

I apologize for jumping to conclusions without testing on other environments. I wasn't aware of such compiler dependent anomalies.

ayushgupta138 avatar May 07 '21 05:05 ayushgupta138