

Hi guys, firsttime post here. Hello to everyone.
I'm using boost.geometry to implement a project. I need to calculate the intersection between a line and a polygon. I know there is no infinite line concept in boost.geometry. So I try to use the segment to intersect with a polygon, however, it seems not supported yet. Is there any other workaround that I can implement the intersection between a line and a polygon? The line is like y=mx+b or ax + by + c = 0.
Thanks. Ethan
_______________________________________________
Boostusers mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boostusers


Hi guys, firsttime post here. Hello to everyone.
I'm using boost.geometry to implement a project. I need to
calculate the intersection between a line and a polygon. I
know there is no infinite line concept in boost.geometry. So I
try to use the segment to intersect with a polygon, however,
it seems not supported yet. Is there any other workaround that
I can implement the intersection between a line and a polygon?
The line is like y=mx+b or ax + by + c = 0.
Indeed the intersection of segment and polygon does not compile even
though it should. Fortunately you can represent a segment as a
linestring with 2 points. Something like this:
namespace bg = boost::geometry;
typedef bg::model::point<double, 2,
bg::cs::cartesian> point;
typedef bg::model::box<point> box;
typedef bg::model::segment<point> segment;
typedef bg::model::linestring<point> linestring;
typedef bg::model::multi_linestring<linestring>
multi_linestring;
typedef bg::model::polygon<point> polygon;
// create some polygon, a circle
polygon poly;
for (double a = 0; a < 2 * 3.14; a += 0.1)
bg::append(poly, point(cos(a), sin(a)));
// correct data to match compiletime metadata
// (clockwise, closed polygon)
bg::correct(poly);
// calculate polygon's bounding box which could be used
with line
// equation to calculate segment's endpoints
box b = bg::return_envelope<box>(poly);
// here you could calculate a segment represented as
linestring
// using min and max coordinates of polygon's envelope
// and line's parameters
// but for now:
linestring ls;
bg::append(ls, point(1, 1));
bg::append(ls, point(1, 1));
// the result of the intersection of linear and areal
geometry
// is multilinestring
multi_linestring result;
bg::intersection(ls, poly, result);
std::cout << bg::wkt(ls) << std::endl;
std::cout << bg::wkt(poly) << std::endl;
std::cout << bg::wkt(result) << std::endl;
Regards,
Adam
_______________________________________________
Boostusers mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boostusers


Hi, Adam thanks for the reply and detailed code and explanation. Yes, it worked. I implemented as per your instructions but encountered a small problem. That is sometimes I realized the intersections points between the linestrings and the polygon are not in a "consistent" order, e.g. as shown in the below image, lingstring 1 has P1>P2; However, instead of P3>P4, linestring 2 is P4>P3. I actually expect linestring 2 is also along P3>P4 direction. Is this how it is supposed to be? Any workaround to solve this problem? Thanks.
On Fri, Nov 16, 2018 at 11:30 AM Adam Wulkiewicz < [hidden email]> wrote:
Hi guys, firsttime post here. Hello to everyone.
I'm using boost.geometry to implement a project. I need to
calculate the intersection between a line and a polygon. I
know there is no infinite line concept in boost.geometry. So I
try to use the segment to intersect with a polygon, however,
it seems not supported yet. Is there any other workaround that
I can implement the intersection between a line and a polygon?
The line is like y=mx+b or ax + by + c = 0.
Indeed the intersection of segment and polygon does not compile even
though it should. Fortunately you can represent a segment as a
linestring with 2 points. Something like this:
namespace bg = boost::geometry;
typedef bg::model::point<double, 2,
bg::cs::cartesian> point;
typedef bg::model::box<point> box;
typedef bg::model::segment<point> segment;
typedef bg::model::linestring<point> linestring;
typedef bg::model::multi_linestring<linestring>
multi_linestring;
typedef bg::model::polygon<point> polygon;
// create some polygon, a circle
polygon poly;
for (double a = 0; a < 2 * 3.14; a += 0.1)
bg::append(poly, point(cos(a), sin(a)));
// correct data to match compiletime metadata
// (clockwise, closed polygon)
bg::correct(poly);
// calculate polygon's bounding box which could be used
with line
// equation to calculate segment's endpoints
box b = bg::return_envelope<box>(poly);
// here you could calculate a segment represented as
linestring
// using min and max coordinates of polygon's envelope
// and line's parameters
// but for now:
linestring ls;
bg::append(ls, point(1, 1));
bg::append(ls, point(1, 1));
// the result of the intersection of linear and areal
geometry
// is multilinestring
multi_linestring result;
bg::intersection(ls, poly, result);
std::cout << bg::wkt(ls) << std::endl;
std::cout << bg::wkt(poly) << std::endl;
std::cout << bg::wkt(result) << std::endl;
Regards,
Adam
_______________________________________________
Boostusers mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boostusers


Hi, Adam thanks for the reply and detailed code and
explanation. Yes, it worked.
I implemented as per your instructions but encountered a
small problem. That is sometimes I realized the intersections
points between the linestrings and the polygon are not in a
"consistent" order, e.g. as shown in the below image,
lingstring 1 has P1>P2; However, instead of P3>P4,
linestring 2 is P4>P3. I actually expect linestring 2 is
also along P3>P4 direction. Is this how it is supposed to
be? Any workaround to solve this problem? Thanks.
I don't know what happens in this case exactly because I don't know
the data but I would rather assume that Boost.Geometry doesn't care
about the order of linestring points (both directions represent the
same geometry). The simplest solution would be to check the
direction of the output and if needed reverse the linestrings
manually or with bg::reverse().
Adam
_______________________________________________
Boostusers mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boostusers


Thanks Adam. I did use bg::reverse to reverse when necessary.
Sorry that I still encounter a problem with the intesection() function. It got me weird results when the line just right across the vertices of the polygon.
Here is what I did, trying to make it clear.
1. In my program, the intersection between line and polygon is zero. So I print out the polygon and the linestring. (Actually from my visualization, it should has one intersection at (9.29497, 2.29204))
terminal printout:
Linestring: ((10, 3.43403), (8.4973, 1))
Polygon: (((7, 1.52705), (2.06343, 3.17257), (5.16667, 5.5), (7.69098, 5.5), (9.29497, 2.29204), (7, 1.52705)))
2. I reconstruct polygon and linestring using the above printout value, and redo the intersection(), weird thing happened, it got me two same intersection points.
terminal printout: Intersections: ((9.29497, 2.29204), (9.29497, 2.29204))
3. I compare the polygon/linestring in my program and the reconstructed polygon/linestring, it says these two are not even equal.
code:
std::cout << "Polygons are spatially " << (boost::geometry::equals(poly1, poly2) ? "equal" : "not equal") << std::endl; std::cout << "Lines are spatially " << (boost::geometry::equals(line1, line2) ? "equal" : "not equal") << std::endl;
terminal printout: Polygons are spatially not equal Lines are spatially not equal
It really got me here. How come the geometry I reconstructed from the printout is not equal to the original? The code I used to reconstruct is as follows:
bgPolygon poly2{{{7, 1.52705}, {2.06343, 3.17257}, {5.16667, 5.5}, {7.69098, 5.5}, {9.29497, 2.29204}, {7, 1.52705}}}; // C++11 initialization list support
bg::correct(poly2); // make it clockwise and closed polygon bgLinestring line2{{10, 3.43403}, {8.4973, 1.0}};
Could you help me on this issue?
Hi, Adam thanks for the reply and detailed code and
explanation. Yes, it worked.
I implemented as per your instructions but encountered a
small problem. That is sometimes I realized the intersections
points between the linestrings and the polygon are not in a
"consistent" order, e.g. as shown in the below image,
lingstring 1 has P1>P2; However, instead of P3>P4,
linestring 2 is P4>P3. I actually expect linestring 2 is
also along P3>P4 direction. Is this how it is supposed to
be? Any workaround to solve this problem? Thanks.
I don't know what happens in this case exactly because I don't know
the data but I would rather assume that Boost.Geometry doesn't care
about the order of linestring points (both directions represent the
same geometry). The simplest solution would be to check the
direction of the output and if needed reverse the linestrings
manually or with bg::reverse().
Adam
_______________________________________________
Boostusers mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boostusers


Hi Adam I think I have figured it out. Because of the precision, the two polygons are not the same.
That also explains that why sometimes the intersection() gives me two intersection points looking "exactly" the same but if you look at the double precision, they are actually two different points. In reality, these two points can be safely considered the same point. I can solve this by comparing the two points distance. However, sometimes also because of the precision, the intersection() does not even give me any intersection points especially when the line is right across the vertex of the polygon. How do I solve this kind of problem?
Ethan
Thanks Adam. I did use bg::reverse to reverse when necessary.
Sorry that I still encounter a problem with the intesection() function. It got me weird results when the line just right across the vertices of the polygon.
Here is what I did, trying to make it clear.
1. In my program, the intersection between line and polygon is zero. So I print out the polygon and the linestring. (Actually from my visualization, it should has one intersection at (9.29497, 2.29204))
terminal printout:
Linestring: ((10, 3.43403), (8.4973, 1))
Polygon: (((7, 1.52705), (2.06343, 3.17257), (5.16667, 5.5), (7.69098, 5.5), (9.29497, 2.29204), (7, 1.52705)))
2. I reconstruct polygon and linestring using the above printout value, and redo the intersection(), weird thing happened, it got me two same intersection points.
terminal printout: Intersections: ((9.29497, 2.29204), (9.29497, 2.29204))
3. I compare the polygon/linestring in my program and the reconstructed polygon/linestring, it says these two are not even equal.
code:
std::cout << "Polygons are spatially " << (boost::geometry::equals(poly1, poly2) ? "equal" : "not equal") << std::endl; std::cout << "Lines are spatially " << (boost::geometry::equals(line1, line2) ? "equal" : "not equal") << std::endl;
terminal printout: Polygons are spatially not equal Lines are spatially not equal
It really got me here. How come the geometry I reconstructed from the printout is not equal to the original? The code I used to reconstruct is as follows:
bgPolygon poly2{{{7, 1.52705}, {2.06343, 3.17257}, {5.16667, 5.5}, {7.69098, 5.5}, {9.29497, 2.29204}, {7, 1.52705}}}; // C++11 initialization list support
bg::correct(poly2); // make it clockwise and closed polygon bgLinestring line2{{10, 3.43403}, {8.4973, 1.0}};
Could you help me on this issue?
Hi, Adam thanks for the reply and detailed code and
explanation. Yes, it worked.
I implemented as per your instructions but encountered a
small problem. That is sometimes I realized the intersections
points between the linestrings and the polygon are not in a
"consistent" order, e.g. as shown in the below image,
lingstring 1 has P1>P2; However, instead of P3>P4,
linestring 2 is P4>P3. I actually expect linestring 2 is
also along P3>P4 direction. Is this how it is supposed to
be? Any workaround to solve this problem? Thanks.
I don't know what happens in this case exactly because I don't know
the data but I would rather assume that Boost.Geometry doesn't care
about the order of linestring points (both directions represent the
same geometry). The simplest solution would be to check the
direction of the output and if needed reverse the linestrings
manually or with bg::reverse().
Adam
_______________________________________________
Boostusers mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boostusers


Hi Adam
I think I have figured it out. Because of the precision,
the two polygons are not the same.
That also explains that why sometimes the intersection()
gives me two intersection points looking "exactly" the same
but if you look at the double precision, they are actually two
different points. In reality, these two points can be safely
considered the same point. I can solve this by comparing the
two points distance. However, sometimes also because of the
precision, the intersection() does not even give me any
intersection points especially when the line is right across
the vertex of the polygon. How do I solve this kind of
problem?
Could you paste the WKTs of geometries (with sufficient precision)
[1] and say what do you get and what do you expect?
[1] e.g. std::cout << std::setprecision(20) <<
bg::wkt(polygon) << std::endl;
Adam
_______________________________________________
Boostusers mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boostusers

