我必须以图形方式表示一个方向图,如下图所示。
alt text http://img694.imageshack.us/img694/1605/graf.gif
我有一个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)
答案 0 :(得分:4)
一种方法是创建一个代表(并绘制)您的圈子的UserControl,并在用户点击它时进行处理。然后,您可以让每个圆形对象确定是否已单击它,而不是使用X和Y坐标来确定用户单击的位置以及它们是否单击了圆圈。
答案 1 :(得分:4)
扩展Anders Abel的答案:
单击确定是否有其中一个节点被点击
答案 2 :(得分:2)
我担心你错过了Windows用户界面的基本预期模式。抛出上面的代码并执行此操作:
在内存中创建一个表示“文档”的数据结构(跟踪图形,节点和边缘所需的一切)。
单击鼠标时,不绘制。您只需修改“文档”数据结构(如上所述)。另外,您调用Invalidate(),这将导致稍后重绘。
覆盖OnPaint()。这就是您绘制所有绘图的位置,绘制您存储的数据结构的可视化表示。
答案 3 :(得分:1)
一种简单的方法是在绘制时将所有圆圈放入列表中。在鼠标单击处理程序中,您可以浏览列表并检查每个圆圈是否鼠标位于圆圈内。
然而,从长远来看,这种方法不会扩展。如果你有很多圈子,你可能想要研究空间搜索算法。
答案 4 :(得分:1)
您还可以创建节点列表,并检查节点中心与点击点之间的距离是否为<=半径。
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;
}