# Geometry :

Subject: Re: [geometry] [Boost-users] [boost.geometry] buffer distance strategies
From: Barend Gehrels (barend_at_[hidden])
Date: 2014-11-07 13:34:15

Hi Grzegorz,

gchlebus wrote On 6-11-2014 19:08:
>
>
> 2014-11-04 17:23 GMT+01:00 Barend Gehrels [via Boost] <[hidden email]
> </user/SendEmail.jtp?type=node&node=4668774&i=0>>:
>
> Hi Grzegorz,
>
>
>>
>> 2014-10-29 23:18 GMT+01:00 Barend Gehrels [via Boost] <[hidden
>> email] <http://user/SendEmail.jtp?type=node&node=4668617&i=0>>:
>>
>>
>>
>> gchlebus wrote On 24-10-2014 16:44:
>>
>> > Hi,
>> >
>> > I am wondering whether it would be possible to achieve
>> anisotropic buffering
>> > (distances in neg x, pos x, neg y, pos y can have different
>> values) of a
>> > polygon using the buffer function with custom-implemented
>> distance strategy.
>> > What I want to achieve is presented on the figure 2-b in
>> the following
>> > paper:
>> >

>> >
>> > I would be grateful to hear from you whether it is doable, and if positive,
>> > how one could implement such a custom distance strategy.
>> The current distance strategy has (currently) no means to get
>> the angle,
>> or a vector of the new point to be buffered. We can consider
>>
>> However, by writing custom strategies for join, side, point (for
>> point-buffers) and possibly end (for line-buffers) you should
>> be able to
>> create this, because these have this information.
>>
>> Attached a program doing similar things with polygons and
>> points (I vary
>> the distance based on angle - you will have to do something
>> with your
>> anistropic model).
>>
>> The output is also attached.
>>
>> The program defines three custom strategies, all based on the
>> same
>> mechanism, to create interesting output.
>> I did not do the end-strategy but that would look similar,
>> you can look
>> at the provided end-strategy (round) and apply the same
>> function.
>>
>
>
> gchlebus wrote On 31-10-2014 18:13:
>> I really appreciate your example code, it helped me a lot.
>> Attached you can find my source code.
>> In my implementation of the anisotropic buffering I didn't know
>> how to make use of the distance strategy, as it was possible to
>> make it work using only side and join strategies.
>> I encountered strange behavior when changing number of points
>> describing a full circle. Using 360 points produced a good
>> output, whereas 90 points caused only the second polygon to be
>> buffered (see attached figures). I would be thankful if you could
>> help me to resolve this issue as well as for any remarks to my code.
>>
>
> I could reproduce this. Basically the join-strategy should always
> include points perp1 and perp2 (these are the two points
> perpendicular to the two sides which the join-strategy joints).
> Either they are re-calculated, or they can be just added to begin
> and end. So I did the last option, and that piece of code now
> looks like:
>
> double const angle_increment = 2.0 * M_PI / double(point_count);
> double alpha = angle1 - angle_increment;
> * range_out.push_back(perp1);**// added
> * for (int i = 0; alpha >= angle2 && i < point_count; i++,
> alpha -= angle_increment)
> {
> pdd v = getPointOnEllipse(alpha);
> Point p;
> bg::set<0>(p, bg::get<0>(vertex) + v.first);
> bg::set<1>(p, bg::get<1>(vertex) + v.second);
> range_out.push_back(p);
> }
> * range_out.push_back(perp2);**// added*
>
> My sample code of course also suffered from that, so I added it
> there too if I use it in the future.
>
> I tested your algorithm with various points and distances and it
> now seems always OK.
>
> You ask for remarks on your code: it looks good ;-) one thing,
> many terms are recalculated such as pow(xPos*tan(alpha), 2)); or
> just tan(alpha), I usually store these into variables, to avoid
> expensive recalculations of the same terms, though maybe they are
> optimized by the compiler.
>
> Regards, Barend
>
>
> P.S. this list discourages top-postings
>
>
> Hallo Barend,
>
> I corrected the join strategy, but still the buffering doesn't work in
> all cases as expected. When using xPos = 1, and other values equal 0,
> the buffered polygon contains a hole (see xPos1.svg), whereas setting
> xPos to 2 produces a correct result (xPos2.svg). Do you know how to
> fix it? I attached also main.cpp, as I changed the code a bit and it
> contains the polygon for which causes the strange behavior.
>

That is most probably caused by an error in some of your calculations:

The line y = sqrt(yPos2 * (1 - pow(x, 2) / xNeg2));
causes a NAN for this input:

then xNeg2 = 0.010000000000000002
and x = -0.10000000000000002
and yPos2 = 0.010000000000000002

This adds a weird line containing NAN to the join, causing the buffer
process fail.
I got this using these parameters:
double xPos = 1.0, xNeg = 0.1, yPos = 0.1, yNeg = 0.1;

and not the parameters you have (that was fine for me).

I think you should make the calculations full-proof first...

For example add a line in the join-strategy:
std::cout << i << " "<< angle1 << " " << angle2 << " " <<
v.first << " " << v.second << std::endl;

Regards, Barend

Geometry list run by mateusz at loskot.net