2

いくつかの長方形をboost::geometryと交差させるための小さなテストアプリケーションがあります。

typedef boost::geometry::model::point
<
double, 2, boost::geometry::cs::cartesian
> point;

typedef boost::geometry::model::polygon<point > polygon;

polygon Intersect(polygon p1, polygon p2) {
    std::vector < polygon > result;
    boost::geometry::intersection(p1, p2, result);
    return result.front();
}

polygon IntersectionTest() {
    polygon one, two, three, four;

    boost::geometry::read_wkt("POLYGON((35 25, 35 35, 15 35, 15 25, 35 25))", one);
    boost::geometry::read_wkt("POLYGON((45 30, 45 50, 25 50, 25 30, 45 30))", two);
    boost::geometry::read_wkt("POLYGON((50  0, 50 40, 10 40, 10  0, 50  0))", three);
    boost::geometry::read_wkt("POLYGON((40 20, 40 60,  0 60,  0 20, 40 20))", four);

    return Intersect(Intersect(Intersect(one, two), three), four);
}

何か間違ったことをしなければなりません。結果は次のようになると思いますが、平行な長方形の交点は常に4 + 1ポイントの長方形である必要があり、エッジにあるため、次の(35 30, 35 40, 25 40, 25 30, 35 30)ようなポイントを含む10ポイントの長さのポリゴンが得られます。交差点ではまったく。それをSVGに入れると、長方形は期待どおりのように見えます。50 050 0

何が間違っている可能性がありますか?バグである場合、boost::geometryどうすればそれを確認できますか?(現在1.48を使用しています。)バグの場合、問題を回避する方法はありますか?

4

2 に答える 2

3

ポリゴンクラスには、次のテンプレートパラメータがあります。

template
<
    typename Point,
    bool ClockWise = true,
    bool Closed = true,
    template<typename, typename> class PointList = std::vector,
    template<typename, typename> class RingList = std::vector,
    template<typename> class PointAlloc = std::allocator,
    template<typename> class RingAlloc = std::allocator
>
class polygon {...}

ご覧のとおり、2番目のテンプレートパラメータのデフォルトはtrueです。つまり、ポリゴンを定義するポイントは時計回りの順序であると見なされます。

これは実際にはあなたの問題です。

ジオメトリのWKT形式を見ると、ポイントを反時計回りの順序で記述しています。

したがって、次のいずれかを行う必要があります。

typedef boost::geometry::model::polygon<point,false> polygon;

または、時計回りの順序でWKT文字列にポイントを書き込みます。すなわち:

boost::geometry::read_wkt("POLYGON((35 25, 15 25, 15 35, 35 35, 35 25))", one);
boost::geometry::read_wkt("POLYGON((45 30, 25 30, 25 50, 45 50, 45 30))", two);

これにより、期待どおりの結果が得られます。

個人的なコメントとして、read_wktが読書に正しい方向を強制するなら、それはおそらく素晴らしいことでしょう...

于 2011-11-28T10:35:48.987 に答える
2

私はds27680の答えに同意します。

3番目のオプションは、read_wktの後にboost :: geometry ::correct(ジオメトリ)を呼び出すことです。方向がわからない場合は、これを行うことをお勧めします。

read_wktは確かに正しい方向を強制しません。その理由は、正しい関数には面積の計算が必要であるためです。面積の計算は、ポリゴンが正しい順序であることがユーザーにわかっている場合に保存できます(通常既知です)。

于 2012-01-19T17:19:07.080 に答える