32

多边形求并集(Union)

 3 years ago
source link: http://www.banbeichadexiaojiubei.com/index.php/2020/11/21/多边形求并集union/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
jAFvEvI.png!mobile

CGAL计算多边形并集

CGAL提供一系列的join函数用于计算两个Polygon的并集(Union)。

bool join(const Type1 & p1, const Type2 & p2, General_polygon_with_holes_2 & res)

Type1和Type2支持的类型如下,简单的说就是,它支持计算任意简单多边形和带洞(hole)多边形求并集。

Type1 Type2 Polygon_2 Polygon_2 Polygon_2 polygon_with_holes_2 Polygon_with_holes_2 Polygon_2 Polygon_with_holes_2 Polygon_with_holes_2 General_polygon_2 General_polygon_2 General_polygon_2 General_polygon_with_holes_2 General_polygon_with_holes_2 General_polygon_2 General_polygon_with_holes_2 General_polygon_with_holes_2

完整的代码如下:

#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Gps_circle_segment_traits_2.h>
#include <CGAL/Boolean_set_operations_2.h>
#include <CGAL/Lazy_exact_nt.h>
#include <list>
#include <cstdlib>
#include <cmath>

typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_2                                   Point_2;
typedef Kernel::Circle_2                                  Circle_2;
typedef CGAL::Gps_circle_segment_traits_2<Kernel>         Traits_2;
typedef CGAL::General_polygon_set_2<Traits_2>             Polygon_set_2;
typedef Traits_2::Polygon_2                               Polygon_2;
typedef Traits_2::Polygon_with_holes_2                    Polygon_with_holes_2;
typedef Traits_2::Curve_2                                 Curve_2;
typedef Traits_2::X_monotone_curve_2                      X_monotone_curve_2;

// Construct a polygon from a circle.
Polygon_2 construct_polygon (const Circle_2& circle) {
  // Subdivide the circle into two x-monotone arcs.
  Traits_2 traits;
  Curve_2 curve (circle);
  std::list<CGAL::Object> objects;
  traits.make_x_monotone_2_object() (curve, std::back_inserter(objects));
  CGAL_assertion (objects.size() == 2);

  // Construct the polygon.
  Polygon_2 pgn;
  X_monotone_curve_2 arc;
  std::list<CGAL::Object>::iterator iter;
  for (iter = objects.begin(); iter != objects.end(); ++iter) {
    CGAL::assign(arc, *iter);
    pgn.push_back (arc);
  }
  return pgn;
}

// The main program:
int main (int argc, char* argv[]) {
  // Read the number of circles from the command line.
  unsigned int n_circles = 8;

  // Create the circles, equally spaced of the circle x^2 + y^2 = 1.
  const double pi = std::atan(1.0) * 4;
  const double n_circles_reciep = 1.0 / n_circles;
  const double radius = 1;
  const double frac = 2 * pi * n_circles_reciep;
  std::list<Polygon_2> circles;
  unsigned int k;
  for (k = 0; k < n_circles; k++) {
    const double angle = frac * k;
    const double x = radius * std::sin(angle);
    const double y = radius * std::cos(angle);
    Point_2 center = Point_2(x, y);
    Circle_2 circle(center, radius);
    circles.push_back (construct_polygon (circle));
  }

  // Compute the union aggregately.
  std::list<Polygon_with_holes_2> res;
  CGAL::join (circles.begin(), circles.end(), std::back_inserter (res));
  // Print the result.
  std::copy (res.begin(), res.end(),
             std::ostream_iterator<Polygon_with_holes_2>(std::cout, "\n"));
  std::cout << std::endl;

  return 0;
}

Boost计算多边形并集(Union)

Boost库中也提供了求解多边形并集的方法。

template<typename Geometry1, typename Geometry2, typename Collection>
void union_(Geometry1 const & geometry1, Geometry2 const & geometry2, Collection & output_collection)

完整的代码如下:

#include <iostream>
#include <vector>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>

#include <boost/foreach.hpp>

int main() {
    typedef boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > polygon;

    polygon green, blue;

    boost::geometry::read_wkt(
        "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3)"
            "(4.0 2.0, 4.2 1.4, 4.8 1.9, 4.4 2.2, 4.0 2.0))", green);

    boost::geometry::read_wkt(
        "POLYGON((4.0 -0.5 , 3.5 1.0 , 2.0 1.5 , 3.5 2.0 , 4.0 3.5 , 4.5 2.0 , 6.0 1.5 , 4.5 1.0 , 4.0 -0.5))", blue);

    std::vector<polygon> output;
    boost::geometry::union_(green, blue, output);

    int i = 0;
    std::cout << "green || blue:" << std::endl;
    BOOST_FOREACH(polygon const& p, output) {
        std::cout << i++ << ": " << boost::geometry::area(p) << std::endl;
    }


    return 0;
}

输出的效果如下:

F3am6n.png!mobile

在线效果体验网站

iA3Ebqe.png!mobile

https://www.bing.com/api/maps/sdk/mapcontrol/isdk#binaryOperations+JS

6bmqMnF.png!mobile

https://milevski.co/martinez/demo/#geo

参考材料

https://doc.cgal.org/latest/Boolean_set_operations_2/Boolean_set_operations_2_2set_union_8cpp-example.html

https://www.boost.org/doc/libs/1_56_0/libs/geometry/doc/html/geometry/reference/algorithms/union_.html


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK