Converting polygon coordinates from Double to Long for use with Clipper library
Asked Answered
H

1

8

I have two polygons with their vertices stored as Double coordinates. I'd like to find the intersecting area of these polygons, so I'm looking at the Clipper library (C++ version). The problem is, Clipper only works with integer math (it uses the Long type).

Is there a way I can safely transform both my polygons with the same scale factor, convert their coordinates to Longs, perform the Intersection algorithm with Clipper, and scale the resulting intersection polygon back down with the same factor, and convert it back to a Double without too much loss of precision?

I can't quite get my head around how to do that.

Hydrolyte answered 17/7, 2013 at 23:39 Comment(0)
S
7

You can use a simple multiplier to convert between the two:

/* Using power-of-two because it is exactly representable and makes
the scaling operation (not the rounding!) lossless. The value 1024
preserves roughly three decimal digits. */
double const scale = 1024.0;

// representable range
double const min_value = std::numeric_limits<long>::min() / scale;
double const max_value = std::numeric_limits<long>::max() / scale;

long
to_long(double v)
{
    if(v < 0)
    {
        if(v < min_value)
            throw out_of_range();
        return static_cast<long>(v * scale - 0.5);
    }
    else
    {
        if(v > max_value)
            throw out_of_range();
        return static_cast<long>(v * scale + 0.5);
    }
}

Note that the larger you make the scale, the higher your precision will be, but it also lowers the range. Effectively, this converts a floating-point number into a fixed-point number.

Lastly, you should be able to locate code to compute intersections between line segments using floating-point math easily, so I wonder why you want to use exactly Clipper.

Sprint answered 18/7, 2013 at 5:43 Comment(5)
I need to get the intersecting area of two polygons as a new polygon. In some cases, these polygons may have 'holes' or may be concave. Clipper should handle all those edge cases. Thanks for your help!Hydrolyte
"scale" - it seems that it is not used for scaling the double?Paluas
is there also a backwards conversion ?\Dunstable
Yes there is, @NSDawg, and it's pretty simple, since you don't have overflow issues (only perhaps rounding/conversion inaccuracies), that conversion is trivial.Sprint
I found my way to it just wasnt sure because I didnt add/substract 0.5 so i thought I am wrong.Dunstable

© 2022 - 2024 — McMap. All rights reserved.