Boost.Geometry はじめてました

はじめてました。
ゲームで使うのには微妙かなーと思っていましたけど、多面体の当たり判定なんかはこっち使えば楽そうな気がしたのでちょっとつついてみました。
とりあえず、Polygon モデルだけ。

[ソース]

#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/strategies/transform.hpp>
#include <boost/geometry/strategies/transform/matrix_transformers.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>

namespace bg = boost::geometry;

int
main(){
    typedef bg::model::d2::point_xy<float> point_type;
    bg::model::polygon<point_type> polygon;
    
    // outer() で、各頂点へのコンテナへアクセス
    // デフォルトだと std::vector が使用される
    // 適当に頂点を追加
    polygon.outer().push_back(point_type( 0.0f,  0.5f));
    polygon.outer().push_back(point_type( 0.5f,  0.0f));
    polygon.outer().push_back(point_type( 0.1f, -0.1f));
    polygon.outer().push_back(point_type( 0.0f, -0.5f));
    polygon.outer().push_back(point_type(-0.1f, -0.1f));
    polygon.outer().push_back(point_type(-0.5f,  0.0f));
    // 最後に最初の頂点位置を設定して閉じる
    polygon.outer().push_back(point_type( 0.0f,  0.5f));
    
    // dsv で、出力フォーマット
    std::cout << "polygon:" << bg::dsv(polygon) << std::endl;
    
    bg::model::polygon<point_type> polygon2;
    // 平行移動してみたり
    bg::strategy::transform::translate_transformer<point_type, point_type> translate(0.5f, 0.3f);
    // polygon が translate された結果が polygon2 に出力される
    bg::transform(polygon, polygon2, translate);
    std::cout << "polygon:" << bg::dsv(polygon) << std::endl;
    std::cout << "polygon2:" << bg::dsv(polygon2) << std::endl;
    
    // 2つの Polygon (Geometry) の当たり判定とか
    if( bg::intersects(polygon, polygon2) ){
        std::cout << "あててんのよ!!" << std::endl;
    }
    
    return 0;
}

[出力]

polygon:(((0, 0.5), (0.5, 0), (0.1, -0.1), (0, -0.5), (-0.1, -0.1), (-0.5, 0), (0, 0.5)))
polygon:(((0, 0.5), (0.5, 0), (0.1, -0.1), (0, -0.5), (-0.1, -0.1), (-0.5, 0), (0, 0.5)))
polygon2:(((0.5, 0.8), (1, 0.3), (0.6, 0.2), (0.5, -0.2), (0.4, 0.2), (0, 0.3), (0.5, 0.8)))
あててんのよ!!

[移動後の画像]

上記のソースは Polygon だけですが、他にも Point や linestring なんかがあります。
基本的な使い方はそんなに変わらないかな?
ドキュメントとかはまだ不十分な所が多いので分からなければ example や test を見たほうが早いかも知れません。


とりあえず、Boost.Geometry をやって幾何学よりもテンプレート力が上がった。
Boost.Geometry のアダプト周りの処理はいい感じですね。
もうちょっと本体のソースも読んでいきたいです。

[追記]

Polygon の当たり判定をする場合、disjoint を使用するよりも !disjoint を返す intersects があると教えてもらったので修正。
id:faith_and_brave さんありがとうございます!

[boost]

  • ver 1.47.0