BoostにGeometryというとても便利そうなライブラリ群がサポートされていることが分かったので、試してみました。また、実験として2つのポリゴンの重複ポリゴンを取得してみます。
まず私の環境はVCPKGを導入しているのでBoostのGeometryをインストールする必要があります。下記コマンドでVCPKGのモジュール名を確認します。vcpkg.exeのパスはご自身の環境に合わせてください。私の環境ではVCPKGはC:\src\vcpkg
C:\src\vcpkg\vcpkg.exe search geometry
下記の実行結果からモジュール名は boost-geometry であることが分かります。
下記コマンドでboost-geometryをインストールします。
C:\src\vcpkg\vcpkg.exe install boost-geometry
これで環境構築は終わりました。それでは、実験用に以下のソースコードを用意します。
#include #include #include <boost/geometry.hpp> #include <boost/geometry/geometries/point_xy.hpp> #include <boost/geometry/geometries/polygon.hpp> #include <boost/foreach.hpp> namespace bg = boost::geometry; int main() { typedef bg::model::d2::point_xy<double> boost_pnt; typedef bg::model::polygon<boost_pnt> boost_poly; boost_poly blue{ {{0.0, 0.0}, {0.0, 2.0}, {2.0, 2.0}, {2.0, 0.0}, {0.0, 0.0}}, {} }; boost_poly red{ {{1.0, -1.0}, {1.0, 1.0}, {3.0, 1.0}, {3.0, -1.0}, {1.0, -1.0}}, {} }; std::deque<boost_poly> output; bg::intersection(blue, red, output); int i = 0; std::cout << "blue && red:" << std::endl; BOOST_FOREACH(boost_poly const& p, output) { for (auto it = boost::begin(bg::exterior_ring(p)); it != boost::end(bg::exterior_ring(p)); ++it) { double x = bg::get<0>(*it); double y = bg::get<1>(*it); std::cout << x << ", " << y << std::endl; } } return 0; }
以下のCMakeLists.txtを使ってVisual Studio 2019のプロジェクトを生成します。
cmake_minimum_required(VERSION 2.8 FATAL_ERROR) set(ProjectName geo_intersect) project(${ProjectName}) add_executable (${ProjectName} main.cpp) set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT "${ProjectName}") find_package(Eigen3 REQUIRED) set(MY_INCLUDE_DIR ${MY_INCLUDE_DIR} ${EIGEN3_INCLUDE_DIR}) set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC ON) set(Boost_USE_MULTITHREADED ON) set(Boost_ARCHITECTURE "-x64") find_package(Boost 1.30 REQUIRED) if(Boost_FOUND) target_link_libraries (${ProjectName} ${Boost_LIBRARIES}) find_path(BOOST_GEOMETRY_INCLUDE_DIRS "boost/geometry.hpp") set(MY_INCLUDE_DIR ${MY_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${BOOST_GEOMETRY_INCLUDE_DIRS}) endif() target_include_directories(${ProjectName} PRIVATE ${MY_INCLUDE_DIR}) set_property(TARGET ${ProjectName} PROPERTY CXX_STANDARD 17) set_property(TARGET ${ProjectName} PROPERTY CXX_STANDARD_REQUIRED ON)
上記のソースコードでは、下図の青と赤のポリゴンを生成して、それらが重複している緑の領域のポリゴンを求めて、その座標を出力します。
ビルドして実行してみてください。下記のような上図緑の部分の座標が出力されるはずです。 座標としては (2, 1), (2, 0), (1, 0), (1, 1), (2, 1)です。
blue && red: 2, 1 2, 0 1, 0 1, 1 2, 1