4

フォームに2つの(VisualBasic.PowerPacks)LineShapesがあります。

代替テキストhttp://lh4.ggpht.com/_1TPOP7DzY1E/S2cIJan7eHI/AAAAAAAADAw/qwA0jFHEbBM/s800/intersection.png

それらの1つをクリックすると、特定のコンテキストメニューが表示されます。線はユーザーが移動できます。コンテキストメニューは行に関連付けられています。ただし、ユーザーが交点をクリックした場合(存在する場合)、他のメニューを表示する必要があります。これにより、アクションを実行する交線の1つが選択されます。

ここで、クリックポイントで2つ(またはそれ以上)の線が交差していることを検出する方法を考えます。この場合、他のコンテキストメニューが表示されるはずだからです。

私がやろうとしたこと:

    private void shapeContainer1_MouseDown(object sender, MouseEventArgs e)
    {
        // right click only
        if (e.Button == MouseButtons.Right)
        {
            LineShape target = 
                (shapeContainer1.GetChildAtPoint(e.Location) as LineShape);

            if (target != null)
            {
                Console.WriteLine(new Point(target.X1, target.Y1));
            }

        }
    }

コンテナにはLineShapesしかないと思います。つまり、LineShapeがマウスの下にある場合、ShapeContainerはMouseDownイベントを発生させません。

しかし、このコードは私にmostTop行しか与えませんが、他のリストも必要です。

4

5 に答える 5

3

座標ネットワークには、 と の 2 つの線がy1 = ax + c1ありy2 = bx + c2ます。次に交点 が線の境界線を超えていないことを確認し、近接度を計算します +- ピクセルまたは 2 x1=x2y1=y2
y = ax + c1, y = bx + c2
ax + c1 = bx + c2
x = (c2 - c1)/(a - b)

于 2010-02-01T17:16:11.280 に答える
2

2 つの線分の交点を計算するだけで済みます。これはかなり単純です。

完全に機能するアルゴリズムについては、こちらで説明しています。2 点で定義されたライン セグメントから外れて動作するため、状況に簡単に適応できるはずです。

于 2010-02-01T17:16:40.710 に答える
0

Serhio、それは簡単な数学です...

線の交点を計算し(おそらく、線が追加されて結果が保存されるときにこれを行います)、マウスがコンテキストメニューを表示するのに十分近いかどうかを確認して、ピクセル完璧なクリックを必要としないようにします.

于 2010-02-01T17:15:11.997 に答える
0

ライン交差アルゴリズム (このページで数人が示しているように) とは別に、コンテキスト メニューをラインから切り離す必要があります。疑似コードでは、次のようなものが必要です。

onLine1Click:
if intersection then handle intersection
else handle line1 click

onLine2Click:
if intersection then handle intersection
else handle line2 click

この処理は、コンテキスト メニューを表示することができます。残りの問題を解決するには、この if/then/else が必要だと思います。

于 2010-02-01T19:12:37.483 に答える
0
    /// obtains a list of shapes from a click point
    private List<LineShape> GetLinesFromAPoint(Point p) 
    {
        List<LineShape> result = new List<LineShape>();
        Point pt = shapeContainer1.PointToScreen(p);

        foreach (Shape item in shapeContainer1.Shapes)
        {
            LineShape line = (item as LineShape);
            if (line != null && line.HitTest(pt.X, pt.Y))
            {
                result.Add(line);                    
            }
        }
        return result;
    }

    private void shapeContainer1_MouseDown(object sender, MouseEventArgs e)
    {
        // right click only
        if (e.Button == MouseButtons.Right)
        {
            List<LineShape> shapesList = GetLinesFromAPoint(e.Location);
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("At this point {0} there are {1} lines.", 
                e.Location, shapesList.Count);
        }
    }
于 2010-02-01T23:52:23.223 に答える