前言:感觉上是有点标题党了,但事确实是这么个事,代码也确实一开始是计划这么用的——只不过后来在实现的过程中,发现情况要比现在还要简单一些(虽然现在也挺简单)。
背景情况是这样的,我们有一个机器人会按照特定轨道进行自动取货送货,所以就需要在机器人开始任务的时候进行一个位置的实时监控。在一开始设想的时候(主要是模拟环境),我是用代码控制他的坐标的,也就是现在的代码。但实际上,我只要能够从PLC实时获取到坐标并显示出来即可。所以软件上基本就画个路径并且设置好轨道坐标即可。.
但是写都写出来了,记录下吧;以下代码可能没什么实用价值,我也不废话了- -,可以直接翻到最后看下效果。
-
以下主要是通过GDI+绘制的,所以理论上是没什么比较复杂的东西
-
private class HRoad
{
public int ID { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int Length { get; set; }
}
private class VRoad
{
public int ParentID { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int Length { get; set; }
}
-
Pen penR = new Pen(Color.LightGray, 2);
Pen penB = new Pen(Color.Red, 1);
List<HRoad> hRoads = new List<HRoad>();
List<VRoad> vRoads = new List<VRoad>();
int x = 20, y = 100;
bool isRun = false;
int hIndex = 0;
int speed = 200;
int stopX = 200;
-
private void Init()
{
int hx = 20, hy = 20;
int hlength = 500, vlength = 80;
for (int i = 1; i <= 3; i++)
{
HRoad road = new HRoad { ID = i, X = hx, Y = i * vlength + hy, Length = hlength };
hRoads.Add(road);
if (i < 3)
{
vRoads.Add(new VRoad { ParentID = road.ID, X = 80 * i, Y = road.Y, Length = vlength });
}
}
}
-
private void panel2_Paint(object sender, PaintEventArgs e)
{
Graphics graphics = e.Graphics;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
foreach (var hRoad in hRoads)
{
graphics.DrawLine(penR, hRoad.X, hRoad.Y, hRoad.X + hRoad.Length, hRoad.Y);
}
foreach (var vRoad in vRoads)
{
graphics.DrawLine(penR, vRoad.X, vRoad.Y, vRoad.X, vRoad.Y + vRoad.Length);
}
Rectangle rect = new Rectangle(x, y - 10, 20, 20);
graphics.DrawRectangle(penB, rect);
graphics.FillEllipse(new SolidBrush(Color.LightBlue), stopX + 5, hRoads.Last().Y - 5, 10, 10);
}
-
private async void Start()
{
while (isRun && hIndex < hRoads.Count)
{
var move = vRoads.Find(s => s.ParentID == hRoads[hIndex].ID);
if (move != null)
{
while (isRun)
{
if (move.X - 10 > x)
{
x += 10;
panel2.Invalidate(new Rectangle(hRoads[hIndex].X, hRoads[hIndex].Y - 10, hRoads[hIndex].Length, 22));
}
else if (move.X - 10 == x)
{
if (y < move.Length + move.Y)
{
y += 10;
panel2.Invalidate(new Rectangle(move.X-10, move.Y-10 , 22, move.Length+22));
}
else
{
hIndex++;
break;
}
}
else
{
x -= 10;
panel2.Invalidate(new Rectangle(hRoads[hIndex].X, hRoads[hIndex].Y-10, hRoads[hIndex].Length, 22));
}
await Task.Delay(speed);
}
}
else
{
while (x != stopX && isRun)
{
if (stopX > x)
{
x += 10;
}
else
{
x -= 10;
}
panel2.Invalidate(new Rectangle(hRoads[hIndex].X, hRoads[hIndex].Y - 10, hRoads[hIndex].Length, 22));
await Task.Delay(speed);
}
btn_start_Click(null, null);
break;
}
}
}
-
private void btn_start_Click(object sender, EventArgs e)
{
if (btn_start.Text == "开始")
{
btn_start.Text = "停止";
btn_pause.Enabled = true;
isRun = true;
x = 20; y = 100; hIndex = 0;
panel2.Invalidate();
speed = (int)num_speed.Value;
stopX = (int)num_stop.Value;
Start();
}
else
{
btn_start.Text = "开始";
btn_pause.Text = "暂停";
btn_pause.Enabled = false;
isRun = false;
}
}
private void btn_pause_Click(object sender, EventArgs e)
{
if (btn_pause.Text == "暂停")
{
btn_pause.Text = "继续";
isRun = false;
}
else
{
btn_pause.Text = "暂停";
isRun = true;
Start();
}
}
-