2

私はすでにグラハム スキャンを実装していますが、私のプログラムのボトルネックは並べ替えです (80% の時間)。私はそれを改善したいと思います、今私は次のことをしています:

 std::sort(intersections.begin() + 1, intersections.end(), [&minElement](Point const& a, Point const& b)
 {return angle (minElement - a, XAxis) < angle (minElement - b,XAxis);});

これで正確な角度が得られますが、角度関数は次のようになるため、安価ではありません。

float angle (const Point& v1, const Point& v2) {
    return dot (v1, v2) / (v1.Length () * v2.Length ());
}

Length 関数では、最もコストのかかる操作の 1 つである平方根を実行する必要があります。しかし、このようにして私は良い注文を得ます。

Slope、dot、ccw で配列を並べ替えてみましたが、比較から sqrt を削除するだけでしたが、どれも同じ並べ替えを提供しませんでした。何かアドバイスをいただけますか?

4

2 に答える 2

3

ポイントを相対的な角度で並べ替える場合、2 つのポイントがなす正確な角度を知る必要はありません。むしろ、あるポイントが他のポイントの左にあるか右にあるかを知る必要があるだけです。

イメージ。たとえば、2 つの点 (x 1 , y 1 ) と (x 2 , y 2 )を比較したい場合、一番下の点が (x p , y p ) にあると仮定します。2 つのベクトル v 1 = (x 1 - x p , y 1 - y p ) と v 2 = (x 2 - x p , y 2 - y p ) を見てください。v 1が v 2の左側にあるか右側にあるかを判断するには、つまり、v 1からv に向かう角度の符号を確認する必要があります。2 . 正の場合、v 2は v 1の左側にあり、負の場合、v 1は v 2の左側にあります。

2D 外積には、次の優れた特性があります。

v 1 × v 2 = |v 1 | | v 2 | 罪(θ)

ここで、θ は v 1から v 2に向かう角度です。これは、v 1が v 2の右側にある場合は θ > 0であり、その逆も同様であることを意味します。これは、外積をとることによって純粋にどちらがどこに行くかを比較できるため、便利です!

言い換えると:

  • v 1 × v 2 > 0 の場合、v 2は v 1の左側にあります。
  • v 1 × v 2 = 0 の場合、点は同一線上にあります。
  • v 1 × v 2 < 0 の場合、v 2は v 1の右側にあります。

2D 外積式は次の式で与えられます。

(Δx 1 , Δy 1 ) × (Δx 2 , Δy 2 ) = (Δx 1 Δy 2 - Δx 2 Δy 1 )

ここで、Δx 1は x 1 - x pなどを表します。

したがって、上記の量を計算し、その符号を見て、2 つの点が互いにどのように関係しているかを判断できます。平方根は必要ありません!

于 2017-01-12T22:53:18.677 に答える