Skip to content
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

difference gives incorrect result for polygon and multi_polygon #1291

Closed
Age-123 opened this issue Jul 10, 2024 · 12 comments
Closed

difference gives incorrect result for polygon and multi_polygon #1291

Age-123 opened this issue Jul 10, 2024 · 12 comments
Labels
not a bug Not a bug or a bug fixed in the past

Comments

@Age-123
Copy link

Age-123 commented Jul 10, 2024

Program

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
namespace bg = boost::geometry;
namespace bm = boost::multiprecision;
typedef bm::cpp_dec_float_100 float_type;
typedef bg::model::d2::point_xy<float_type> point_type;
typedef bg::model::polygon<point_type, false, true> polygon_type;


typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;

int main() {
  polygon_type polygon_layer;
  bg::read_wkt("POLYGON((0 0, 2 0,2 2, 0 2, 0 0))", polygon_layer);
  boost::geometry::correct(polygon_layer);
  multi_polygon_type metal_layer;
  polygon_type metal_polygon1;
  bg::read_wkt( "POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))",metal_polygon1);
  boost::geometry::correct(metal_polygon1);
  metal_layer.push_back(metal_polygon1);
  polygon_type metal_polygon2;
  bg::read_wkt("POLYGON((0 1, 1 1,1 2, 0 2, 0 1))",metal_polygon2);
  boost::geometry::correct(metal_polygon2);
  metal_layer.push_back(metal_polygon2);
  multi_polygon_type result;
  bg::difference(polygon_layer, metal_layer, result);
  std::cout << "Difference Result:" << std::endl;
  for (const auto& poly : result) {
    std::cout << std::setprecision(10) << bg::wkt(poly) << std::endl;
  }
  return 0;
}

The answer is POLYGON((0 1,1 1,1 0,2 0,2 2,1 2,0 2,0 1))
but I think the answer should be POLYGON((1 0,2 0,2 2,1 2,1,0))
It seems like difference only used to calculate polygon_layer and metal_polygon1, the metal_polygon2 was ignored
I try to use correct function as you can see in the program, but it is useless
Look forward to your reply,thanks!

@vissarion
Copy link
Member

Thanks, I can reproduce it. If you reverse the order of the polygons in metal_layer the result is correct.
Looks similar to #1222 and #1221
It needs further investigation.

@Age-123
Copy link
Author

Age-123 commented Jul 25, 2024

Thanks, I can reproduce it. If you reverse the order of the polygons in metal_layer the result is correct.
Looks similar to #1222 and #1221
It needs further investigation.

thanks for your reply. Does that mean the different orders of adding polygon to multipolygon lead to different results?

@vissarion
Copy link
Member

Thanks, I can reproduce it. If you reverse the order of the polygons in metal_layer the result is correct.
Looks similar to #1222 and #1221
It needs further investigation.

thanks for your reply. Does that mean the different orders of adding polygon to multipolygon lead to different results?

Yes and this should not happen.

@barendgehrels
Copy link
Collaborator

Hi! The description is edited - how can I see the original (without Boost multi precision)? Or was that in the original description already?

@barendgehrels
Copy link
Collaborator

I can reproduce it as well and for me also the different in ordering helps.
It does not look like a floating point precision error.
It's not fixed by my concept fix for another issue.

@barendgehrels
Copy link
Collaborator

Additional testing shows that the second input geometry is invalid.
Ordering changes the result, but it does not give the correct result. The result is wrong in a different way.

bg::is_valid(poly2) is false, even after calling correct. They don't self overlap.

Can we close this as not-a-bug?

@barendgehrels barendgehrels added not a bug Not a bug or a bug fixed in the past and removed bug labels Jul 28, 2024
@barendgehrels
Copy link
Collaborator

BTW the reason that I checked it again is that I have a concept fix for another recent issue and wanted to check if it would fix this as well.

@Age-123
Copy link
Author

Age-123 commented Jul 28, 2024

Additional testing shows that the second input geometry is invalid. Ordering changes the result, but it does not give the correct result. The result is wrong in a different way.

bg::is_valid(poly2) is false, even after calling correct. They don't self overlap.

Can we close this as not-a-bug?

Thanks for your reply, but if I only add poly2 or poly1 to the multipolygon, the results both are true, so do you mean when I add poly1 and poly2 to the multipolygon, the poly2 will be invalid? I think poly1 and poly2 are similar

@Age-123
Copy link
Author

Age-123 commented Jul 28, 2024

Hi! The description is edited - how can I see the original (without Boost multi precision)? Or was that in the original description already?

The reason why I use Boost multi precision is the precision of double or float is not enough when I want to use intersection to calculate the intersecting linestring of two closed linestrings

@Age-123
Copy link
Author

Age-123 commented Jul 28, 2024

Additional testing shows that the second input geometry is invalid. Ordering changes the result, but it does not give the correct result. The result is wrong in a different way.

bg::is_valid(poly2) is false, even after calling correct. They don't self overlap.

Can we close this as not-a-bug?

I change the order of poly1 and poly2, the result is “POLYGON ((1 2,1 1,1 0,2 0,2 2,1 2))”, it seems like the top of poly1 and the bottom of poly2 are not completely overlapping(because the coordinates(1,1)), but I think they should be completely overlapping, and I use bg::is_valid(poly2),the result is true, maybe our poly2 is different, the boost version I use is 1.85

@barendgehrels
Copy link
Collaborator

Good point, I renamed them in my local verification. So then please apply:
std::cout << "Valid: " << std::boolalpha << bg::is_valid(metal_layer) << std::endl;
and it will show it is invalid (in either order).

@barendgehrels
Copy link
Collaborator

Thanks for your reply, but if I only add poly2 or poly1 to the multipolygon, the results both are true, so do you mean when I add poly1 and poly2 to the multipolygon, the poly2 will be invalid? I think poly1 and poly2 are similar

Yes but their combination is invalid

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
not a bug Not a bug or a bug fixed in the past
Projects
None yet
Development

No branches or pull requests

3 participants