c++castingpolygondata-conversionclipperlib

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


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.


Solution

  • 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.