C# 在C窗体上画完圆圈后,我如何知道我单击了哪个圆圈?

C# 在C窗体上画完圆圈后,我如何知道我单击了哪个圆圈?,c#,winforms,click,draw,geometry,C#,Winforms,Click,Draw,Geometry,我必须用图形表示一个定向图,如下图所示 我有一个C窗体,当我用鼠标点击它时,我必须画一个节点。如果我单击表单上尚未绘制节点的某个位置,这意味着我使用了绘制节点的提示进行了点击,如果它是一个节点,我必须选择它并记住它。在下一次鼠标单击时,如果我触摸到一个尚未绘制节点的位置,这意味着像以前一样,我想绘制一个新节点,如果是我单击的节点,我需要绘制从第一个记忆节点到所选节点的线,并添加道路成本详细信息 当我点击表单时,我知道如何绘制代表图形节点的圆。我正在使用以下代码: namespace RepGra

我必须用图形表示一个定向图,如下图所示

我有一个C窗体,当我用鼠标点击它时,我必须画一个节点。如果我单击表单上尚未绘制节点的某个位置,这意味着我使用了绘制节点的提示进行了点击,如果它是一个节点,我必须选择它并记住它。在下一次鼠标单击时,如果我触摸到一个尚未绘制节点的位置,这意味着像以前一样,我想绘制一个新节点,如果是我单击的节点,我需要绘制从第一个记忆节点到所选节点的线,并添加道路成本详细信息

当我点击表单时,我知道如何绘制代表图形节点的圆。我正在使用以下代码:

namespace RepGraficaAUnuiGraf
{
    public partial class Form1 : Form
    {
        Graphics graphDrawingArea;
        Bitmap bmpDrawingArea;
        Graphics graph;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            bmpDrawingArea = new Bitmap(Width, Height);
            graphDrawingArea = Graphics.FromImage(bmpDrawingArea);
            graph = Graphics.FromHwnd(this.Handle);
        }

        private void Form1_Click(object sender, EventArgs e)
        {          
            DrawCentralCircle(((MouseEventArgs)e).X, ((MouseEventArgs)e).Y, 15);
            graph.DrawImage(bmpDrawingArea, 0, 0);
        }

        void DrawCentralCircle(int CenterX, int CenterY, int Radius)
        {
            int start = CenterX - Radius;
            int end = CenterY - Radius;
            int diam = Radius * 2;
            bmpDrawingArea = new Bitmap(Width, Height);
            graphDrawingArea = Graphics.FromImage(bmpDrawingArea);
            graphDrawingArea.DrawEllipse(new Pen(Color.Blue), start, end, diam, diam);
            graphDrawingArea.DrawString("1", new Font("Tahoma", 13), Brushes.Black, new PointF(CenterX - 8, CenterY - 10));
        }

    }
}

我的问题是,我怎样才能知道我是否在表格上的坐标x,y处画了一个节点,它是哪一个?我考虑将节点表示为按钮,带有标签或类似于节点编号的东西。在绘图中,圣巴巴拉的节点编号应为1,巴斯托的节点编号应为2。一种简单的方法是在绘制圆时将所有圆放入列表中。在鼠标单击处理程序中,您可以浏览列表并检查每个圆的鼠标是否在圆内


然而,从长远来看,这种方法不会扩大规模。如果你有很多圆,你可能需要研究空间搜索算法。

一个简单的方法是在绘制圆时将所有圆放入一个列表中。在鼠标单击处理程序中,您可以浏览列表并检查每个圆的鼠标是否在圆内


然而,从长远来看,这种方法不会扩大规模。如果你有很多圆圈,你可能想研究一下空间搜索算法。

一种方法是创建一个用户控件来表示和绘制你的圆圈,并在用户单击它时进行处理。然后,您可以让每个圆对象确定它是否被单击,而不是使用X和Y坐标来尝试找出用户单击的位置以及他们是否单击了圆。

一种方法是创建一个表示和绘制圆的UserControl,以及用户单击圆时的处理。然后,您可以让每个圆形对象确定它是否被单击,而不是使用X和Y坐标来尝试找出用户单击的位置以及他们是否单击了圆形。

扩展Anders Abel的答案:

保留一个列表,存储每个节点的信息,包括 中心点 半径 其他相关信息。。。 单击时,确定是否命中其中一个节点

遍历所有节点 使用以下命令查找从单击点到节点中心的距离: 如果距离小于半径,则选择节点 如果未选择节点,则在单击的位置添加新节点
根据Anders Abel的回答展开:

保留一个列表,存储每个节点的信息,包括 中心点 半径 其他相关信息。。。 单击时,确定是否命中其中一个节点

遍历所有节点 使用以下命令查找从单击点到节点中心的距离: 如果距离小于半径,则选择节点 如果未选择节点,则在单击的位置添加新节点
恐怕您缺少Windows UI的基本预期模式。扔掉上面的代码并执行以下操作:

在内存中创建一个数据结构,该结构表示您需要跟踪的有关图形、其节点和边的所有文档

单击鼠标时,您不会绘制。您只需按照上面的建议修改文档数据结构。另外,您调用Invalidate,这将导致稍后重新绘制

覆盖在油漆上。这是您进行所有绘制的地方,绘制存储的数据结构的视觉表示


恐怕您缺少Windows UI的基本预期模式。扔掉上面的代码并执行以下操作:

在内存中创建一个数据结构,该结构表示您需要跟踪的有关图形、其节点和边的所有文档

单击鼠标时,您不会绘制。您只需按照上面的建议修改文档数据结构。另外,您调用Invalidate,这将导致稍后重新绘制

覆盖在油漆上。这是您进行所有绘制的地方,绘制存储的数据结构的视觉表示


您还可以创建一个节点列表,检查节点中心到单击点之间的距离是否。您还可以创建一个节点列表,检查节点中心到单击点之间的距离是否是在发布我尝试过的问题之后,而不是在用户单击时在表单上绘制圆圈以放置按钮。我重写了OnPaint方法来绘制它们,并在TabIndex属性中将索引放在数组中找到节点的位置。比
在发布问题后,我尝试在表单上单击按钮,而不是画圆圈。我重写了OnPaint方法来绘制它们,并在TabIndex属性中将索引放在数组中找到节点的位置。感谢您提供创建UserControl的指针。
private void Form1_MouseClick(object sender, MouseEventArgs e)
{    
       int x1 = node.Center.X, y1 = node.Center.Y, x2, y2;
       Point local = this.PointToClient(Cursor.Position);
       bool clicked = false;
       x2 = local.X;
       y2 = local.Y;
       float distance = Convert.ToSingle(Math.Sqrt((x1 - x2) ^ 2 + (y1 - y2) ^ 2));
       if(distance <= radius) clicked = true;
}