Okay, buckle up.
Given a Linestring which is constructed from Point A and B and a polygon C how can I assure that A->B line does not intersect with any walls in C or resides inside the C?
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/linestring.hpp>
namespace bg = boost::geometry;
namespace bgm = boost::geometry::model;
typedef bgm::d2::point_xy<double> Point;
typedef bgm::polygon<Point> Polygon;
typedef boost::geometry::model::segment<Point> Segment;
Polygon wall;
Polygon passage;
boost::geometry::model::linestring<Point> AB{start, end}
bool isPassable = false;
bool intersecting = bg::intersects(AB, wall);
if (intersecting) {
for (int i = 0; i < passage.outer().size(); i += 2) {
Point p1 = passage.outer()[i];
Point p2 = passage.outer()[i + 1];
Segment passageSegment(p1, p2);
Segment testSegment(start, end);
if (bg::intersects(passageSegment, testSegment)) {
isPassable = true;
break;
}
}
} else {
isPassable = bg::relate(AB, wall, boost::geometry::de9im::mask("T*F**F***"));
}
Due to privacy reasons, I cant show the full code but this is the point of interest anyways.
Our polygon in question
POLYGON((2 2,2 3.5,4 3.5,4 2,2 3.5,2 5.5,5 5.5,5 3.5,4 2,4 3.5,5 3.5,5 5.5,7.5 5.5,7.5 2,2 2))
passages
Passage: POINT(2.5 3.5) POINT(3 3.5)
Passage: POINT(4.25 3.5) POINT(4.75 3.5)
Passage: POINT(4 2.5) POINT(4 3)
Passage: POINT(5 4) POINT(5 5)
looks like this:
Where the green line is:
POINT(2.5 3.25) POINT(3 3.625)
After running the two relate functions see if this line is related to any walls, if it is not related, check if it is breaching any holes in passages, this works, actually. For the green line, I can get a true. Problem starts at:
this green line. As you can see it lies in the polygon. So in the first relate to the wall it should return true. but as there is no relation between the line and walls/passages, this one returns false even through it shouldn't. How can I handle this?
In official Boost doc
I can see that
This method is actually used for the thing I want. See if the point of interest resides in the polygon. thanks for any help.



Your input polygon is invalid:
Prints Live On Coliru
You can attempt to fix it automatically with
bg::correctBut it doesn't work for these problems. I strongly suspect you really want the thing to be a (multi-)linestring, or even just a list of segments.
Then to get the "within" check you'd use
bg::withinagainst the convex hull¹.With those fixes I get:
Live On Coliru
Printing
I would really suggest to simplify it further by actually deleting the passages from the original "wall" string. This is especially important to make your check correct. After all, when there are multiple intersections one of them being in a passage really doesn't change anything, but your code assumes there is always only one intersection.
BONUS
This take (still assuming the convex hull) should be correct for multiple intersections. Note also that it is became considerably simpler. And we assert that the passages actually lie on the walls.
I've added more test-cases to showcase different edge cases.
Live On Coliru
Printing
¹ (If your shapes are more complex than depicted and can have concave edges, then you need to adapt for that still).