Boost logo

Boost Users :

Subject: Re: [Boost-users] measuring distance between a point and a segment
From: Adam Wulkiewicz (adam.wulkiewicz_at_[hidden])
Date: 2016-04-21 08:13:03


Juliette Pera wrote:
> Thanks for your answer.
> Here's some more information.
>
> I am going through the list of vertices of a segment, stored in a
> vector of Eigen::Vector2D and then I am computing the distance from a
> point stored in Eigen::vector2d to a each segment of my polygon.
>
> I calculate the distance using my own function and then I calculate it
> using boost function distance.
> I declare a segment of type boost::geometry::model::segment<double>
> in which I add my two vertices that make the segment.
>

You probably mean
boost::geometry::model::segment<boost::geometry::model::point<double, 2,
boost::geometry::cs::cartesian> > ?

> Then I display the result for each vertices and I get the same result
> for every segment using boost.
>
> I hope it's more clear now.
>

If xsegment_t is of type boost::geometry::model::segment and
geom::append() is boost::geometry::append() then it doesn't set the
endpoints of a segment. It's because a segment is not a container so
appending to it doesn't change it. If xsegment_t was e.g.
boost::geometry::model::linestring or instead of bg::append() the
endpoints of a segment was passed into the constructor it should work.

The behavior of bg::append() is indeed confusing. Anyway, try using the
constructor of bg::model::segement instead:

xsegment_t segment(geom::make_point(A[0],A[1]),
                    geom::make_point(B[0],B[1]));
double distance2 = geom::distance(segment, geom::make_point(P[0],P[1]));

Please let me know if this helps.

TL;DR

A side note. If the overall goal was to calculate the distance from a
point to Polygon2D then you could write your own Ring type (a Polygon
without holes), e.g. wrap std::vector<Eigen::Vector2d> and adapt your
type to Boost.Geometry Ring concept. Or simply register
std::vector<Eigen::Vector2d> as a Ring (though then all std::vectors of
Eigen::Vector2d points would be treated as Rings). It'd require to adapt
Eigen::Vector2d type to Boost.Geometry Point concept and since
Eigen::Vector2d provides operator[] for element access you would be
forced to adapt it manually specializing traits. If the goal was to
calculate the closest distance to the edge of Polygon2D then instead of
adapting std::vector to the Ring concept you could adapt it to the
Linestring concept. Then Boost.Geometry could calculate the distance for
you.

Here Boost.Geometry point_xy is adapted:
https://github.com/boostorg/geometry/blob/develop/include/boost/geometry/geometries/point_xy.hpp#L87

You could copy it and replace:
model::d2::point_xy<CoordinateType, CoordinateSystem> -> Eigen::Vector2d
CoordinateType -> double
CoordinateSystem -> cs::cartesian
returnp.templateget<Dimension>(); -> return p[Dimension];
p.templateset<Dimension>(value); -> p[Dimension] =
value;

Here is an example of adapting std::vector to the Ring concept:
http://www.boost.org/doc/libs/1_60_0/libs/geometry/doc/html/geometry/reference/adapted/register/boost_geometry_register_ring.html

So you could register your vector like this:
BOOST_GEOMETRY_REGISTER_RING(std::vector<Eigen::Vector2d>)

And then
bg::distance(polygon2D, P)
should return the distance between Polygon and Point.

See also:
http://www.boost.org/doc/libs/1_60_0/libs/geometry/doc/html/geometry/reference/concepts/concept_point.html
http://www.boost.org/doc/libs/1_60_0/libs/geometry/doc/html/geometry/reference/concepts/concept_ring.html
http://www.boost.org/doc/libs/1_60_0/libs/geometry/doc/html/geometry/reference/concepts/concept_linestring.html
http://www.boost.org/doc/libs/1_60_0/libs/geometry/doc/html/geometry/reference/adapted/register/boost_geometry_register_linestring.html

Regards,
Adam



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net