Search code examples
c++computational-geometrycgal

Similar to Computing the Exact Offset in CGAL, can I compute the "exact buffer" of a polyline?


Is there any already built and ready to use C++ algorithms out there similar to CGAL's offset_2 function but instead of computing the Minkowski sum of a circle and a polygon, the Minkowski sum of a circle and a polyline is computed (i.e., the buffer of the polyline)?

In application this is what I would like to do:

  1. Input a polyline with n vertices: ([x_0,y_0],[x_1,y_1],...,[x_n-1,y_n-1])
  2. Find the exact buffer of this polyline (output is a polygon that may have holes)
  3. Extract each individual conic-arc to test for intersections with other lines I have.
  4. display this buffered polyline

Thanks

EDIT: Possible Solution

Could I just generate a circle of radius r at each vertex and a rectangle with width of 2r along each line segment, and then take the union of these?

If I understand the CGAL documentation correctly, I can get an exact solution (i.e., something made up of conic arc), correct? If so, some guidance will be greatly appreciated.


Solution

  • So, following from my suggested solution, the Minkowski sum of a polyline and a circle of radius r is the union of circles or radius r at each vertex and rectangles of width r about each line segment.

    Following this, I used the Boolean Set-Operations on General Polygons and the example therein, which conveniently takes the union of circles of rectangles. The key feature of this was the fact that the GeneralPolygon_2 concept was used, which allows me to get an exact solution in the form of linear functions and circular arcs.

    Here is a snippet of my code (note that my inputted polyline uses complex coordinates):

    Polygon_set_2 S;
    // Generate a Circle for each Vertex
    for (int i=0; i<complexPolygon.size(); ++i){
        S.join(construct_polygon(Circle_2(Point_2(real(complexPolygon[i]), imag(complexPolygon[i])),1)));
    }
    // Generate a Rectangle for Each Ordered Pair of Vertices
    for (int i=0; i<complexPolygon.size()-1; ++i){
        complex<double> P1, P2, P12, R1, R2, R3, R4;
        P1 = complexPolygon[i];
        P2 = complexPolygon[i+1];
        P12 = P2-P1;
        R1 = P1 - complex<double>(0,w)*P12/abs(P12);
        R4 = P1 + complex<double>(0,w)*P12/abs(P12);
        R2 = R1 + P12;
        R3 = R4 +P12;
    
        S.join(construct_polygon(Point_2(real(R1), imag(R1)), Point_2(real(R2), imag(R2)),
                                 Point_2(real(R3), imag(R3)), Point_2(real(R4), imag(R4))));
    }
    fstream minkFile;
    minkFile.open("mink.txt",ios::out);//open in write mode
    if(minkFile.is_open()){
        list<Polygon_with_holes_2> res;
        S.polygons_with_holes (std::back_inserter (res));
        copy (res.begin(), res.end(),
        ostream_iterator<Polygon_with_holes_2>(minkFile, "\n"));
        cout << endl;
    }