AngusJohnson / Clipper2

Polygon Clipping and Offsetting - C++, C# and Delphi
Boost Software License 1.0
1.52k stars 273 forks source link

Negative offset should be empty but is not #873

Closed LarsSkiba closed 3 months ago

LarsSkiba commented 3 months ago

Hello Angus,

after updating from 1.2.3 to 1.4.0 i found this regression. The result should be empty, because of a large negative offset.

image

Input shown in white. Offset result shown in red.

The geometry has a maximum width of ~5.2 and the is empty till an offset of -10, at -11 the issue appears and grows in size with larger negative offsets. These numbers are unscaled, the scaling is 8388608.

This following minimal example reproduces the issue and uses an offset of -29.75 * 8388608 :

    Clipper2Lib::ClipperOffset offset;
    offset.ArcTolerance(838860.800000000047);    
    Clipper2Lib::Paths64 closedPaths =
        {{{667680768, -36382704}, {667906112, -45554228}, {668582208, -51001588},
        {669708992, -56073272}, {671286528, -60769272}, {673314752, -65089592},
        {675793728, -69034232}, {678723392, -72603192}, {682103808, -75796480},
        {685934912, -78614080}, {690216768, -81056000}, {694949312, -83122240},
        {700132608, -84812800}, {705766592, -86127680}, {711851328, -87066880},
        {718386752, -87630400}, {725372928, -87818240}, {731466368, -87622400},
        {737202688, -87034880}, {742581888, -86055680}, {747603968, -84684800},
        {752268928, -82922240}, {756576768, -80768000}, {760527488, -78222080},
        {764121088, -75284480}, {767322688, -71994240}, {770097408, -68390400},
        {772445248, -64472956}, {774366208, -60241916}, {775860288, -55697276},
        {776927488, -50839036}, {777567808, -45667196}, {777781248, -40181752},
        {777189888, -31994866}, {775415808, -24719348}, {772561408, -18071030},
        {768729088, -11765750}, {763888128, -5736948},  {758007808, 81931},
        {751190528, 5969929},   {735354368, 18882574},  {729192448, 24453134},
        {725329408, 30095370},  {724041728, 36986884},  {724850688, 42595844},
        {727277568, 46602240},  {731322368, 49006080},  {736985088, 49807360},
        {743364608, 48435200},  {747921408, 44318720},  {750655488, 37457924},
        {751566848, 27852806},  {751566848, 23961606},  {789577728, 23961606},
        {789577728, 32010248},  {789374080, 37403368},  {788763008, 42462088},
        {787744640, 47186408},  {786318848, 51576328},  {784485760, 55631848},
        {782245248, 59352964},  {779597440, 62739684},  {776542208, 65792004},
        {773083840, 68496800},  {769226368, 70840960},  {764969920, 72824480},
        {760314368, 74447360},  {755259840, 75709600},  {749806208, 76611200},
        {743953600, 77152160},  {737701888, 77332480},  {731506560, 77146720},
        {725679488, 76589440},  {720220800, 75660640},  {715130368, 74360320},
        {710408320, 72688480},  {706054528, 70645128},  {702069120, 68230248},
        {698451968, 65443848},  {695233600, 62325292},  {692444288, 58913932},
        {690084160, 55209772},  {688153088, 51212812},  {686651200, 46923056},
        {685578368, 42340496},  {684934720, 37465132},  {684720128, 32296972},
        {684901888, 27416976},  {685447168, 22853136},  {686355968, 18605456},
        {687628288, 14673934},  {691125248, 7403531},   {695799808, 686091},
        {698526848, -2490229},  {701444608, -5578228},  {704553088, -8577907},
        {707852288, -11489265}, {722669568, -23920624}, {729494528, -29911024},
        {734445568, -34979824}, {737456128, -40043504}, {738459648, -46018544},
        {737425408, -51834864}, {734322688, -56381432}, {729561088, -59315196},
        {723550208, -60293120}, {715964928, -58833916}, {710862848, -54456312},
        {707967488, -47088628}, {707002368, -36659200}, {707002368, -32768000},
        {667967488, -32768000}}};
    offset.AddPaths(closedPaths, Clipper2Lib::JoinType::Round, Clipper2Lib::EndType::Polygon);    
    Clipper2Lib::Paths64 solution;
    offset.Execute(-249561088, solution);

    EXPECT_TRUE(solution.empty());

Would be nice if you could help out, let me know if more details are needed.

Thanks, Lars

LarsSkiba commented 3 months ago

Further minimized example: image

    Clipper2Lib::ClipperOffset offset;
    Clipper2Lib::Paths64 closedPaths = {
        {{667680768, -36382704},
         {737202688, -87034880},
         {742581888, -86055680},
         {747603968, -84684800}}};

    Clipper2Lib::Paths64 solution;
    offset.AddPaths(closedPaths, Clipper2Lib::JoinType::Miter, Clipper2Lib::EndType::Polygon);
    offset.Execute(-249561088, solution);
LarsSkiba commented 3 months ago

7714d940ca86eb7cc8cf5f9eda2b1486daf32cb1 caused the regression

LarsSkiba commented 3 months ago

This tolerance does not seem to be sufficient.

if (cos_a < 0.99) path_out.push_back(path[j]); // (#405)

In this example 0.996268 does cause the issue.

LarsSkiba commented 3 months ago

I changed the tolerance to 0.999 which is consistent with the tolerances used in surrounding code and updated the pull request.