0

I have a number of polygons in boost::geometry and want to find the specific neighbor from one polygon who has the longest common border with the first polygon. The polygons exactly touch each other so boost::geometry::disjoint returns false, but the following code always returns perimeter 0:

typedef boost::geometry::model::d2::point_xy<double>      boost_pnt;
typedef boost::geometry::model::polygon<boost_pnt>        boost_poly;

boost_poly otherPol = ...;
boost_poly thisPol  = ...;

if(! boost::geometry::intersection(thisPol, otherPol, out))
    return -1;

float perimeter = 0;
BOOST_FOREACH(boost_poly const& p, out)
{
    perimeter += boost::geometry::perimeter(p);
}
return perimeter;

How can i find the common "border", the touching length of both polygons?

RED SOFT ADAIR
  • 12,032
  • 10
  • 54
  • 92

2 Answers2

1

I'm not a mathemetician and I don't know the boost::geometry library, so I should give this one a shot. :-)

You need to compare each line segment in polygon 1 to each line segment in polygon 2. So in each comparison we have two line segments, A and B

First, I'd compare the unit vectors of the two line segments, if they are equal, or exactly opposite, the lines are parallel.

If the lines are parallel, I'd take the line segment defined by one of the points of A and one of the points of B (doesn't matter which in either case), and calculate its unit vector. If that unit vector equals (or is exactly opposite to) the unit vector above, the line segments are on the same infinite line.

If that's the case, we can find which (if any) end points of a line segment lie inside the other quite easily. ie: if A.point1 is up and to the left of B.point1 and B.point2 is up and to the left of A.point1, A.point1 lies on the line segment B. (Helps to draw it.)

Note that 1 of the line segments might lie entirely within the other - so if A is entirely within B, B will have neither end point lying within A.

In the case of A lying entirely within B, the shared border of those segments is of course the length of A.

Otherwise find the greatest length between a point in A and a point in B, and subtract that from the sum of the lengths of A and B.

Any features in boost::geomettry that help, you should use! :-)

(Note that I've said "equal to" a lot, we will of course be dealing with floating point arithmetic so equal is a slightly flexible term.)

Grimm The Opiner
  • 1,778
  • 11
  • 29
0

I believe in the case the polygons touch but not overlap the operation geometry::intersection will generate an empty container in out though will still return true. This is essentially a definition of touch: no intersection of interiors.

Since Boost.Geometry works with interiors, you cannot get more out of it.

What you really want is to consider your polygons as what the library CGAL defines as Nef polygons. CGAL provides an API which allows you to get a Nef Polygon as intersection of two Nef Polygons. In case the operands are touching, the result will be a poly-polyline.

But do not hold your breath, Nef operations are slower and API is more complicated than that of Boost.Geometry; you will probably get better results by implementing the feature yourself.

Michael Simbirsky
  • 3,045
  • 1
  • 12
  • 24