2

任意の形状のGraphicsPathを定義されたスペース(ほとんどの場合、長方形または円)に「合わせる」必要があります。

現在、Matrixオブジェクトを使用してGraphicsPathをスケーリングしていますが、スケーリングは正常に機能しますが、問題はスケール係数を取得することです。

私が思いつくことができる最良のテクニックは、GraphicsPathをRegionに変換し、RectangleまたはCircleをRegionに変換し、以下を実行することです。

rgnShape.Intersect(rgnCircle);

次に、次のことを確認します。

rgnShape.IsEmpty()

ただし、これは、形状が大きすぎて収まらないかどうかを示しているだけなので、形状を小さくして、再試行する必要があります(場合によっては何度も何度も)。

ポリゴンGraphicsPathが完全に円に収まるように、スケーリング係数を即座に計算する簡単な方法はありますか?結果は、円内に完全に収まる最大のポリゴンになるはずです。

4

5 に答える 5

2

Simon によって発見された、パスではなくポイントに関するこの問題の議論については、http://en.wikipedia.org/wiki/Smallest_circle_problemを参照してください。

  1. それで、それをして、rgnShape.Intersect(rgnCircle);それが機能したかどうかを確認するために使用します。失敗した場合は、各曲線を取得し、見つけた円の中心から最も遠いポイントを取得します (特定の領域に複数のポイントがある場合があります)。

  2. それらをポイント リストに追加し、アルゴリズムを再適用します。ゼロから始める必要はありません。境界上にないポイントを考慮する必要はありません (つまり、アルゴリズムの元の呼び出しで見つかった "Set Q" にないポイントを無視します)。

再帰呼び出しを生成する確率が i 番目の点で 1/i ではないため、これはもはや線形ではないことに注意してください。

これには、明示的に処理する必要があるエッジ条件が 1 つあります。ステップ 1 の最初の繰り返しで見つかった領域の外側で見つかった曲線の 1 つが完全な円形で、外側の円に接している場合、「Set Q」内に無限の点が存在し、このアルゴリズムは惨めに失敗します。rgnShape.Intersect(rgnCircle);そのため、初めて適用した後、この場合は完全に丸い曲線を明示的に確認する必要があります。たとえば、形状が である場合、最初の反復で見つかった領域の外側にあるかどう(}かを明示的に確認する必要があります()(この説明で()は、円であると想定します) 。(

これでもかなり悪いですが、すべての曲線をポイントに変更するよりはましです。

于 2011-01-04T15:21:24.287 に答える
2

二分探索が必要な理由がわかりません。

シェイプの境界四角形を取得し、そのシェイプをフィットさせたいターゲット四角形を取得したら、2 つの比率targetHeight / shapeHeightとを比較できますtargetWidth / shapeWidth

小さい比率を取り、これをスケーリング係数として使用して形状をスケーリングします。

ターゲットが長方形ではなく円である場合は、比率を取得してtargetCircleDiameter / boundingRectangleDiagonalこれを倍率として使用することにより、同様のソリューションを使用できます。

于 2010-12-30T06:45:42.130 に答える
0

簡単な数学を使って反対の方向に進んでみませんか?つまり、パスのバウンディングボックス/円を取得し、高さ/幅の事前定義された長方形の比率を計算し、それをBBの同じ値と比較し、それに応じてBBをストレッチします(たとえば、事前定義された比率が1未満の場合、BBは水平方向にストレッチされます)それ以外の場合は垂直方向に同じ比率に一致させます)、最後に全体を事前定義された長方形のサイズにスケーリングします。スケール係数は、事前定義された高さをBBの高さで割った値と、事前定義された幅をBBの幅で割った値の間の最小値になりました。(境界円の場合、サイズを調整する必要はありません。)

于 2011-01-04T07:16:23.190 に答える
0

グラフィックパスの中心と半径を計算できませんか?

重心 (座標の平均) を計算し、標準偏差の 2 倍を追加することもできます。これにより、グラフの約 92% が得られます。ほとんどの場合、これで問題はありませんが、グラフの「重み」が最も大きい場合は失敗します。一方的に。

ポイントの中心を計算することもできます-すべてのポイントを実行し、境界ボックスを計算するときのようにすべての方向で最大/最小ポイントを取得し、これの中心を取り、(最大/最小) ポイントまでの最長距離を半径として測定します。

境界球アルゴリズムを探すと、おそらくより洗練されたアルゴリズムを見つけることができますが、何かを表示するだけの場合は、いくつかのトレードオフを行うことができます. 衝突検出を行っている場合、そのための簡単なアルゴリズムもいくつかあります:)

于 2011-01-03T09:42:15.520 に答える
0

GraphicsPath と Region で GetBounds を使用し、長方形のサイズを比較して、少なくとも近づけることができます。

定義されたスペースが正確な正方形である場合。

定義されたスペースが何か他のものである場合、それは少なくともあなたを近づけるでしょう. 次に、バイナリ検索を使用して、実際のスケーリング量を見つけることができます。

于 2010-12-30T00:33:39.313 に答える