我的表单上有2个(VisualBasic.PowerPacks)LineShapes:
alt text http://lh4.ggpht.com/_1TPOP7DzY1E/S2cIJan7eHI/AAAAAAAADAw/qwA0jFHEbBM/s800/intersection.png
当我点击其中一个时,会出现一个特定的上下文菜单。这些线可以由用户移动。上下文菜单与一条线相关联。但是,如果用户点击交叉点(如果存在),我需要显示另一个菜单,该菜单将选择一个交叉线来执行操作。
现在,我想知道如何检测点击点中的两条(或更多条)线相交,因为在这种情况下应该出现另一个上下文菜单。
我试图做的事情:
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事件。
但是这段代码只给了我最多的一行,但我也想要一个其他的列表。
答案 0 :(得分:3)
在您的坐标网络中,您有两行y1 = ax + c1
和y2 = bx + c2
。找到x1=x2
和y1=y2
的交叉点
y = ax + c1, y = bx + c2
ax + c1 = bx + c2
x = (c2 - c1)/(a - b)
然后检查交叉点是否超出线边界并计算接近度+ - 像素或两个。
答案 1 :(得分:2)
您只需要计算两个线段的交集。这很简单。
完整,working algorithm is described here。它适用于由两点定义的线段,因此应该很容易适应您的情况。
答案 2 :(得分:0)
serhio,那很简单Maths ......
计算线条的交点(可能在添加它们并存储结果时执行此操作),然后查看鼠标是否足够接近显示上下文菜单,以便您不需要像素完美点击。
答案 3 :(得分:0)
除了行交叉算法(如本页中的几个人所示),您需要将上下文菜单与行分离。在伪代码中,你需要像:
onLine1Click:
if intersection then handle intersection
else handle line1 click
onLine2Click:
if intersection then handle intersection
else handle line2 click
此处理可以显示上下文菜单。我相信如果/ then / else需要解决您的剩余问题。
答案 4 :(得分: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);
}
}