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

Polygon.Intersects() not working #226

Closed
sreekanth-cb opened this issue Jan 11, 2022 · 6 comments
Closed

Polygon.Intersects() not working #226

sreekanth-cb opened this issue Jan 11, 2022 · 6 comments

Comments

@sreekanth-cb
Copy link

Not sure why the below polygon intersect unit test isn't working, it says the polygons intersect whereas the actual polygons aren't intersecting on the earth's surface.

Is there something the test does in the wrong way? Or
does anyone have any idea/clues as to what is going wrong here?

TEST(S2NonOverlapping, AllCases) {
  vector<S2Point> pts(7);
  S2LatLng latlng;
  
  pts[0] = latlng.FromDegrees(13.197164523281993, -282.9803466796875).ToPoint();
  pts[1] = latlng.FromDegrees(12.404388944669792, -282.919921875).ToPoint();
  pts[2] = latlng.FromDegrees(12.833226023521243, -282.1728515625).ToPoint();
  pts[3] = latlng.FromDegrees(12.95102921601837, -281.55761718749994).ToPoint();

  pts[4] = latlng.FromDegrees(13.443052132777558, -281.62353515625).ToPoint();
  pts[5] = latlng.FromDegrees(13.678013256725489, -282.19482421875).ToPoint();
  pts[6] = latlng.FromDegrees(13.720708401412068, -282.777099609375).ToPoint();
  
  vector<std::unique_ptr<S2Loop>> loops;
  loops.emplace_back(new S2Loop(pts));  
  S2Polygon polygon1 = S2Polygon(std::move(loops));

  pts.resize(19);
  pts[0] = latlng.FromDegrees(45.13745, -67.13734).ToPoint();
  pts[1] = latlng.FromDegrees(44.8097, -66.96466).ToPoint();
  pts[2] = latlng.FromDegrees(44.3252, -68.03252).ToPoint();
  pts[3] = latlng.FromDegrees(43.98, -69.06).ToPoint();

  pts[4] = latlng.FromDegrees(43.68405, -70.11617).ToPoint();
  pts[5] = latlng.FromDegrees(43.09008, -70.64573).ToPoint();
  pts[6] = latlng.FromDegrees(43.08003, -70.75102).ToPoint();
  pts[7] = latlng.FromDegrees(43.21973, -70.79761).ToPoint();

  pts[8] = latlng.FromDegrees(43.36789, -70.98176).ToPoint();
  pts[9] = latlng.FromDegrees(43.46633, -70.94416).ToPoint();
  pts[10] = latlng.FromDegrees(45.30524, -71.08482).ToPoint();
  pts[11] = latlng.FromDegrees(45.46022, -70.66002).ToPoint();

  pts[12] = latlng.FromDegrees(45.91479, -70.30495).ToPoint();
  pts[13] = latlng.FromDegrees(46.69317, -70.00014).ToPoint();
  pts[14] = latlng.FromDegrees(47.44777, -69.23708).ToPoint();
  pts[15] = latlng.FromDegrees(47.18479, -68.90478).ToPoint();

  pts[16] = latlng.FromDegrees(47.35462, -68.2343).ToPoint();
  pts[17] = latlng.FromDegrees(47.06624, -67.79035).ToPoint();
  pts[18] = latlng.FromDegrees(45.70258, -67.79035).ToPoint();
 
  loops.clear();
  loops.emplace_back(new S2Loop(pts));  

  auto polygon2 = S2Polygon(std::move(loops));

  bool intersection = polygon1.Intersects(&polygon2);
  EXPECT_EQ(false,intersection); 
 
}

@jmr
Copy link
Member

jmr commented Jan 11, 2022

Check the area of both polygons. If one is near 4π then it's backwards and encloses the whole sphere except what you probably intended.

// last. All loops are defined to have a CCW orientation, i.e. the interior of

@jmr jmr closed this as completed Jan 11, 2022
@sreekanth-cb
Copy link
Author

sreekanth-cb commented Jan 11, 2022

Really appreciate your quick response!! Thanks a lot!
@jmr , Aside from ensuring that the incoming edges of the polygon are in CCW order,
Is there anything the higher levels(calling app) can do to identify and avoid this before calling Intersect() method?

What is the recommended action to avoid this scenario?

EDIT - the area of the latter polygon is 4π. (12.564235290078345).
what would be the course of action for figuring out whether the polygons intersect or not here.

@jmr
Copy link
Member

jmr commented Jan 11, 2022

The edges are always CCW by definition, so you can't check that. You can check for suspiciously large loops/polygons, though.

You the conditions documented in the comments also need to be satisfied.

// Polygons have the following restrictions:

// last. All loops are defined to have a CCW orientation, i.e. the interior of

You can use the S2Debug::DISABLE constructor then IsValid to check whether you have something valid.

// With override == S2Debug::DISABLE, the automatic validity checking

Of course, in your example everything was valid AFAIK.

EDIT - the area of the latter polygon is 4π. (12.564235290078345).
what would be the course of action for figuring out whether the polygons intersect or not here.

They intersect. What are you asking?

@sreekanth-cb
Copy link
Author

Due to the whole sphere enclosure internal techniques as you hinted above,
polygon1.Intersects(&polygon2) is returning that the polygons intersect in the earlier test.

But the original polygons on the map don't intersect. (one is from US and the other is from india).
My query is - how can I detect and prevent/workaround the cases of backward sphere enclosure and successfully invoke intersect() or check whether the polygons intersect or not.

@jmr
Copy link
Member

jmr commented Jan 11, 2022

pts[0] = latlng.FromDegrees(13.197164523281993, -282.9803466796875).ToPoint();

I missed this before, but -282 is not a valid longitude.

But the original polygons on the map don't intersect. (one is from US and the other is from india).
My query is - how can I detect and prevent/workaround the cases of backward sphere enclosure and successfully invoke intersect() or check whether the polygons intersect or not.

Apparently you entered the complement of the second polygon. Reverse the vertices.

  pts[0] = latlng.FromDegrees(45.70258, -67.79035).ToPoint();
  pts[1] = latlng.FromDegrees(47.06624, -67.79035).ToPoint();
  ...

@sreekanth-cb
Copy link
Author

@jmr, my bad. It's all working fine!
thank you very much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants