$include_dir="/home/hyper-archives/geometry/include"; include("$include_dir/msg-header.inc") ?>
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:
>>         >
>>         http://itcnt05.itc.nl/agile_old/Conference/mallorca2002/proceedings/posters/p_molina.pdf
>>         >
>>         > 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
>>         adding that.
>>
>>         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:
alpha about PI
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