|
Geometry : |
Subject: Re: [geometry] Ring intersection question
From: Will Lucas (wlucas_at_[hidden])
Date: 2014-11-06 18:29:31
On Thu, Nov 6, 2014 at 4:31 PM, Menelaos Karavelas <
menelaos.karavelas_at_[hidden]> wrote:
> Hi Will.
>
>
> On 07/11/2014 12:10 Ïμ, Menelaos Karavelas wrote:
>
> Hi Will.
>
> On 06/11/2014 11:56 μμ, Will Lucas wrote:
>
> On Thu, Nov 6, 2014 at 3:47 PM, Menelaos Karavelas <
> menelaos.karavelas_at_[hidden]> wrote:
>
>> Yet one more comment.
>>
>>
>> On 06/11/2014 11:44 μμ, Menelaos Karavelas wrote:
>>
>> Hi again.
>>
>> On 06/11/2014 11:34 μμ, Menelaos Karavelas wrote:
>>
>> Hi Will.
>>
>> On 06/11/2014 11:26 μμ, Will Lucas wrote:
>>
>> On Thu, Nov 6, 2014 at 3:07 PM, Menelaos Karavelas <
>> menelaos.karavelas_at_[hidden]> wrote:
>>
>>> Dear Will,
>>>
>>> I tried your polygons and the intersection seems to work.
>>> Please checkout the attached program, and let us know if you get a
>>> similar output. The output that I get is:
>>> MULTIPOLYGON(((75 150,250 150,250 75,75 75,75 150)))
>>>
>>> Best,
>>>
>>> - m.
>>>
>>>
>>> On 06/11/2014 10:44 μμ, Will Lucas wrote:
>>>
>>> Hi all,
>>>
>>> I have a question regarding the intersection of ring concepts using
>>> Boost.Geometry. I currently have two overlapping rectangles defined by the
>>> following WKTs:
>>>
>>> POLYGON((75 75,75 175,275 175,275 75,75 75))
>>> POLYGON((50 50,50 150,250 150,250 50,50 50))
>>>
>>> When I perform the intersection of these rectangles, I get the
>>> intersection points:
>>>
>>> POLYGON((75 150,250 75))
>>>
>>> The intersection points do not allow me to compute the area correctly
>>> after the intersection. Is there way to get a fully valid ring/polygon out
>>> of intersection, so that the area will be equal to the overlapping region?
>>>
>>> Thanks!
>>> Will
>>>
>>>
>>> _______________________________________________
>>> Geometry mailing listGeometry_at_[hidden]http://lists.boost.org/mailman/listinfo.cgi/geometry
>>>
>>>
>>>
>>> _______________________________________________
>>> Geometry mailing list
>>> Geometry_at_[hidden]
>>> http://lists.boost.org/mailman/listinfo.cgi/geometry
>>>
>>>
>> Menelaos,
>>
>> Thanks for the quick response! I have tested your code, and it
>> correctly outputs
>>
>> MULTIPOLYGON(((75 150,250 150,250 75,75 75,75 150)))
>>
>> I had to comment out the is_valid calls as I'm running the Ubuntu
>> package (boost 1.54.0), which doesn't contain that helper method.
>>
>>
>> Sure, this was just a sanity test.
>>
>> I'm guess the problem may be my re-mapping of the OpenCV data-types.
>> Here is what I currently am working with
>> https://gist.github.com/wlucas-DFT/0b8e1e07f34ee7e489c6
>>
>> Do I need to define a polygon wrapper for the custom Contour type I
>> have?
>>
>>
>> I think that the problem is that your intersection output type should be
>> a multipolygon rather than a ring/polygon. Please checkout the relevant doc
>> page:
>>
>> http://www.boost.org/doc/libs/1_56_0/libs/geometry/doc/html/geometry/reference/algorithms/intersection.html
>>
>> Try replacing the intersection output type by a multipolygon, or a
>> vector/deque of polygons and see what the output is.
>>
>>
>> Please see the updated attached program. I added one more call to
>> bg::intersection specifying a ring as the output (like you do), and I get
>> the result you get. I am now convinced that the problem is what I describe
>> above.
>>
>>
>> I think what is happening is that the BG code understands your ring as
>> a container of points (a multipoint/vector of points/etc), rather than a
>> multipolygon, in which case it is setup to output just the intersection
>> points.
>>
>> - m.
>>
>> All the best,
>>
>> - m.
>>
>> - m.
>>
>>
>>
>> _______________________________________________
>> Geometry mailing listGeometry_at_[hidden]http://lists.boost.org/mailman/listinfo.cgi/geometry
>>
>>
>>
>>
>>
>> _______________________________________________
>> Geometry mailing list
>> Geometry_at_[hidden]
>> http://lists.boost.org/mailman/listinfo.cgi/geometry
>>
>>
> So, it sounds as if I should follow along with this custom polygon example?
>
> https://github.com/boostorg/geometry/blob/master/example/c06_custom_polygon_example.cpp
>
>
> Yes.
>
> This would hopefully allow me to define a custom multi_polygon. As my
> initial attempt to just create an std::vector<dft::Contour> as a
> multi_polygon, resulted in a bunch of compiler complaints :D
>
>
> I think this is because your vector's value type is a ring rather than a
> polygon.
>
> For my specific problem, I'm not concerned with "holes" that may exist
> in a polygon (I actually indicate to OpenCV, to only return the exterior
> contours to me). Is there a way to indicate to BG that only exterior
> contours are used via the polygon traits?
>
>
> I think that one way is to define your polygon type such that it always
> has an empty container for the interior rings (holes). Registering such a
> polygon should do what you want.
>
>
> I am having second thoughts about my proposal above.
>
> What you need is to register your custom polygon type. This polygon type
> will be used to either register a multipolygon or as the value type of a
> container (vector/deque/etc.), which will then be passed to
> bg::intersection.
>
> The intersection algorithm expects a real polygon, so it might be the case
> that the fake/ring-like polygon I suggested may not work correctly with
> bg::intersection if it cannot store interior rings.
> On the other hand if your input to bg::intersection is just the outer
> rings of polygons, then their intersection cannot really produce holes, so
> it could well be the case that bg::intersection works nicely with the
> fake/ring-like polygons I suggested.
>
> So, I guess, the safe way is to fully register your polygons and then call
> bg::intersection using only their exterior rings.
> Then you can try to modify your custom polygon to never store interior
> rings, and see if this works with bg::intersection.
> I do not have the time to try this right away (use these fake/ring-like
> polygons in bg::intersection), but I would be very interested in knowing if
> it works (assuming you want/have the time to try it).
>
> Assuming that the solution with fake/ring-like polygons works, I see the
> two solutions as equivalent from the performance point of view.
>
> Best,
>
> - m.
>
>
> The other option is to pass to the intersection algorithm only the
> exterior ring of your polygons. Please take a look at the documentation for
> bg::exterior_ring (there is a const and a non-const version):
>
> http://www.boost.org/doc/libs/1_57_0/libs/geometry/doc/html/geometry/reference/access/exterior_ring/exterior_ring_1.html
>
> http://www.boost.org/doc/libs/1_57_0/libs/geometry/doc/html/geometry/reference/access/exterior_ring/exterior_ring_1_const_version.html
>
> Best,
>
> - m.
>
>
> I suppose worst case I can copy from OpenCV to BG data-structures, but
> that doesn't seem as elegant :)
>
> Will
>
>
> _______________________________________________
> Geometry mailing listGeometry_at_[hidden]http://lists.boost.org/mailman/listinfo.cgi/geometry
>
>
>
>
> _______________________________________________
> Geometry mailing list
> Geometry_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/geometry
>
>
Hi Menelaos,
Thanks so much for the help! It really helped get me over this hurdle! I
tried registering the OpenCV Contour (std::vector<cv::Point>) type to a BG
polygon and got multiple definition errors due to the ring already being a
tagged type to BG. It seems like the only way around that was to add a
struct that had a Contour inside, and register that new datatype. So,
rather than adding an additional datatype, I ended up just copying the
OpenCV types to BG ones. While not the most elegant solution, it is working
perfectly now!
Thanks again!
Will
Geometry list run by mateusz at loskot.net