在蚁群执行过程中动态绘制蚂蚁
本文关键字:绘制 蚂蚁 动态 过程中 蚁群 执行 | 更新日期: 2023-09-27 17:51:19
对于我个人的c#蚁群项目,在这个问题(在c# WinForm项目中显示移动像素的轨迹)之后,我试图应用第二个建议的解决方案:将轨迹绘制成位图并将新蚂蚁绘制到表面上的解决方案。
[...]Application.Run(new ShowAnts());[...]
public partial class ShowAnts : Form
{
Bitmap bmp;
int j = 0;
public ShowAnts()
{
InitializeAntProgram();
InitializeComponent();
bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);
pictureBox1.Image = bmp;
}
public void RenderAnts(object sender, PaintEventArgs e)
{
using (Graphics G = Graphics.FromImage(pictureBox1.Image))
{
while (j < 1000)
{
Map.EvaporatesPheromones();
foreach (Vector2D food in foodSrcs)
{
Map.SetMapPoint(food, 500);
}
foreach (Ant a in ants)
{
Brush c;
c = Brushes.DarkBlue;
if (a.role == AntRole.Scout)
{
a.Move(j);
c = Brushes.Red;
}
e.Graphics.FillRectangle(Brushes.DarkBlue, a.position.x, a.position.y, 1, 1);
G.FillRectangle(Brushes.Gray, a.position.x, a.position.y, 1, 1);
}
j++;
}
}
}
}
上面的代码显示了将蚂蚁运动绘制到窗体中的图形尝试。它工作得很完美,但它只显示了最终结果。我想展示一步一步的进化,保持图形轨迹信息,而不重新解析我的地图信息。
请考虑到我正在开发这个"图形界面"的工作控制台项目已经存在,所以:
- 一些变量是在项目的其他地方设置的(即:食物);
- ' a.Move(j); '指的是蚂蚁逻辑本身(分析,决策,新细胞运动指的是地图数组);
- ' j '计数器用于计数步骤和设置任意停止,但没有实际用途;
- 我已经存储到地图数组和其他一些变量有关信息,信息素,运动,位置等
看看你的代码和上一个问题的评论,似乎你错过了动画运动的部分。相反,你是在似乎是Paint
事件的内部循环。
这里有一个快速修复。它添加了一个触发RenderAnts
事件的Timer
,该事件似乎连接到pictureBox1.Paint
处理程序..:
几个类级别变量:
int counter = 0;
int limit = 1000;
Timer antTimer = new Timer();
开始代码: antTimer.Interval = 50; // <-- pick your speed !!
antTimer.Tick += (ss, ee) =>
{ pictureBox1.Invalidate(); counter++; if (counter > limit) antTimer.Stop(); };
antTimer.Start();
速度为50ms,即每秒20个Ticks
。
Tick
事件与一个很小的Lambda
表达式内联,并且只有一条语句加上循环逻辑。通过Invalidating
, pictureBox1
控制Paint
事件,从而触发RenderAnts
事件。
还请注意,我称之为"快速修复"。通常你会用来区分动画的渲染和移动代码;但在这种情况下,这种细微的差别并不重要。
现在我们改变RenderAnts
方法,取出循环:
public void RenderAnts(object sender, PaintEventArgs e)
{
using (Graphics G = Graphics.FromImage(pictureBox1.Image))
{
Map.EvaporatesPheromones();
foreach (Vector2D food in foodSrcs)
{
Map.SetMapPoint(food, 500);
}
foreach (Ant a in ants)
{
Brush c = Brushes.DarkBlue;
if (a.role == AntRole.Scout)
{
a.Move(j);
c = Brushes.Red;
}
e.Graphics.FillRectangle(c, a.position.x, a.position.y, 1, 1);
G.FillRectangle(Brushes.Gray, a.position.x, a.position.y, 1, 1);
}
}
}
你可能还想添加一个启动/停止Button
。还有一个TrackBar
来改变速度…
现在你应该能够看到你的蚂蚁在20Hz的进度,留下灰色的痕迹。