1

DrawCurve() や DrawLine() などの GDI+ 機能を使用する win32 API ベースの GUI アプリを作成しました。

このアプリは、マルチグラフを表す直線と曲線を描画します。

エッジのデータ構造は、単純に 5 つの int の構造体です。(x1、y1、x2、y2、id)

2 つの頂点間にエッジが 1 つしかない場合は、DrawLine() を使用して直線セグメントが描画されます。複数のエッジがある場合は、DrawCurve() を使用して曲線が描画されます。ここでは、2 つの頂点の中点の周りに直線エッジを広げて、それらを曲線にしています。それから数単位ピクセル離れた点は、法線方程式を使用して計算されます。さらにエッジが追加された場合は、中点から 2 単位ピクセル離れたピクセルが選択され、次は 3 単位ピクセルというように選択されます。

ここで、エッジのクリックの検出について 2 つの質問があります。

  1. 直線エッジを見つける際に、検索時間を最小限に抑えるにはどうすればよいですか?
    クリックされたピクセルが線分上にあるかどうかを確認するのは非常に簡単ですが、エッジの数が多い場合、すべてのエッジを比較するのは非効率的です。O(log n)で実行できるようです。ここで、nはエッジの数です。
    編集: この時点で、エッジ (クラス Edge) はエッジ ID (int) を Edge オブジェクトにマップする std::map に格納され、ピクセルをエッジ ID にマップする別のコンテナーを宣言することを検討しています。
    二分探索木の使用を検討していますが、何が鍵になるのでしょうか? それとも、2D ピクセル配列だけを使用する必要がありますか?

  2. DrawCurve() で使用される点の配列を取得できますか? これが不可能な場合は、カーディナル スプラインを再計算し、点の配列を取得して、ユーザーがクリックした点がその配列内の任意の点と一致するかどうかを確認する必要があります。

4

1 に答える 1

0

複雑な形状の線がある場合は、次のように実行できます。

  • グラフのサイズの内部ビットマップを作成し、黒で塗りつぶします。
  • グラフをレンダリングするときは、クリック可能にしたいエッジもこのビットマップにレンダリングしますが、別の色でレンダリングします。これらの色の値を、対応するIDと一緒にテーブルに保存します。ここで重要なのは、色が異なる(ユニーク)ということです。
  • グラフをクリックしたら、X座標とY座標を内部ビットマップに転送し、ピクセルを読み取ります。黒以外の場合は、テーブルの色の値を調べて、関連付けられたIDを取得します。

この方法では、形状をまったく気にする必要はありません。また、独自の曲線アルゴリズムなどを使用する必要もありません。コストは余分なメモリです。これは考慮事項ですが、巨大なグラフ(この場合は図面をバッファリングできます)でない限り、ほとんどの場合問題にはなりません。2回目のパスで内部ビットマップをレンダリングして、メイングラフィックスを(通常どおり)高速に表示できます。

お役に立てれば!

(ヒント:「内部」の線を幅の広いペンでレンダリングできるため、感度が高くなります)。

于 2012-11-06T07:21:15.760 に答える