4

我的表单上有 2 个 (VisualBasic.PowerPacks)LineShapes:

替代文字 http://lh4.ggpht.com/_1TPOP7DzY1E/S2cIJan7eHI/AAAAAAAADAw/qwA0jFHEbBM/s800/intersection.png

当我单击其中一个时,会出现一个特定的上下文菜单。用户可以移动线条。上下文菜单与一行相关联。但是,如果用户单击交叉点(如果存在),我需要显示另一个菜单,它将选择一条交叉线来执行操作。

现在,我想知道如何检测 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

在您的坐标网络中,您有两条带有y1 = ax + c1和的线y2 = bx + c2。找到交点 wherex1=x2y1=y2
y = ax + c1, y = bx + c2
ax + c1 = bx + c2
x = (c2 - c1)/(a - b)
然后检查交点是否超出线边界并计算接近度 +- 像素或两个。

于 2010-02-01T17:16:11.280 回答
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 回答