我的表单中有一个Groupbox里面的图片框,里面有雷达图片作为背景图片。我的意图是在运行时动态加载雷达区域内的微小Jpeg图像(叠加),但我不确定实现此目的的最佳方式。 欢迎所有疯狂的想法(但我宁愿容易做一些)。 谢谢大家。在C#中模拟雷达的最佳方法是什么?
回答
这很大程度上取决于你的“雷达”需要的样子,但几乎可以肯定你需要实现Paint事件处理程序,并自己绘制雷达显示的内容。一个图片框只会让你到目前为止(“不太”)。
GDI +非常易于使用来绘制圆圈,线条,文本和图像,并且可以完全控制显示器的外观。
最简单的方法是将您的微型JPEG加载到微小的PictureBox中,并在运行时将它们添加到主PictureBox的Controls集合中(即将它们放置在PictureBox上)。
由于这可能会产生闪烁,稍微复杂一点的方法是将主图片和微小图片保存在类级别的Bitmap对象中,并在主PictureBox的Paint事件中复制主图片,然后再复制每个小图片图片添加到使用DrawImage方法的第二个类级别的位图(名为_doubleBuffer或类似的东西),然后将_doubleBuffer复制到您的PictureBox(也使用DrawImage)。无论何时需要更新显示并重新绘制所有内容,只需调用PictureBox的Invalidate方法即可。
这里有很多关于SO的例子展示了如何使用这些方法。祝你好运,这听起来很有趣(如果你正在重写经典的街机游戏Submarine,请告诉我 - 我喜欢那款游戏)。
至于实际的例子:
// Among others
using System.Collections.Generic;
using System.Drawing;
using System.IO;
class TinyPic {
public readonly Image Picture;
public readonly Rectangle Bounds;
public TinyPic(Image picture, int x, int y) {
Picture = picture;
Bounds = new Rectangle(x, y, picture.Width, picture.Height);
}
}
class MyForm : Form {
Dictionary<String, TinyPic> tinyPics = new Dictionary<String, TinyPic>();
public MyForm(){
InitializeComponent(); // assuming Panel myRadarBox
// with your background is there somewhere;
myRadarBox.Paint += new PaintEventHandler(OnPaintRadar);
}
void OnPaintRadar(Object sender, PaintEventArgs e){
foreach(var item in tinyPics){
TinyPic tp = item.Value;
e.Graphics.DrawImageUnscaled(tp.Picture, tp.Bounds.Location);
}
}
void AddPic(String path, int x, int y){
if (File.Exists(path)){
var tp = new TinyPic(Image.FromFile(path), x, y);
tinyPics[path] = tp;
myRadarBox.Invalidate(tp.Bounds);
}
}
void RemovePic(String path){
TinyPic tp;
if (tinyPics.TryGetValue(path, out tp)){
tinyPics.Remove(path);
tp.Picture.Dispose();
myRadarBox.Invalidate(tp.Bounds);
}
}
}
当然这是很基本的,假定图像源的路径,并没有考虑许多复杂的东西照顾,但这是它的快速和肮脏的JIST你当然可以继续发展。
干杯.....没有完成GDI +或任何图形pprogrammingin C#和迫近的最后期限(这是在我截止日期前在我<48前突然出现)这可以帮助.. – 2009-08-17 00:59:39
Click here运行一个示例应用程序,演示如何做雷达(或单向,至少)的基础知识。注意:此应用程序不会执行双缓冲或微小图像的透明度。
该项目的源代码是here。
更新代码:
public partial class Form1 : Form
{
private Bitmap _canvas;
private float _sweepStartAngle = -90;
private float _sweepAngle = 15;
private SolidBrush _sweepBrush = new SolidBrush(Color.Red);
private Rectangle _sweepRect;
private Timer _sweepTimer = new Timer();
private Bitmap _submarine;
private Point _submarinePosition = new Point(0, 0);
private Random rnd = new Random();
public Form1()
{
InitializeComponent();
_canvas = new Bitmap(pbScope.Width, pbScope.Height);
pbScope.Image = _canvas;
_sweepRect = new Rectangle(0, 0, pbScope.Width, pbScope.Height);
_submarine = (Bitmap)pbSubmarine.Image;
RedrawScope();
_sweepTimer.Interval = 100;
_sweepTimer.Tick += new EventHandler(_sweepTimer_Tick);
_sweepTimer.Start();
}
void _sweepTimer_Tick(object sender, EventArgs e)
{
_sweepStartAngle += _sweepAngle;
RedrawScope();
}
private void RedrawScope()
{
using (Graphics g = Graphics.FromImage(_canvas))
{
// draw the background
g.DrawImage(pbBackground.Image, 0, 0);
// draw the "sweep"
GraphicsPath piepath = new GraphicsPath();
piepath.AddPie(_sweepRect, _sweepStartAngle, _sweepAngle);
g.FillPath(_sweepBrush, piepath);
//g.FillPie(_sweepBrush, _sweepRect, _sweepStartAngle, _sweepAngle);
// move the submarine and draw it
_submarinePosition.X += rnd.Next(3);
_submarinePosition.Y += rnd.Next(3);
// check if submarine intersects with piepath
Rectangle rect = new Rectangle(_submarinePosition, _submarine.Size);
Region region = new Region(piepath);
region.Intersect(rect);
if (!region.IsEmpty(g))
{
g.DrawImage(_submarine, _submarinePosition);
}
}
pbScope.Image = _canvas;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
_sweepTimer.Stop();
_sweepTimer.Dispose();
}
private void Form1_Load(object sender, EventArgs e)
{
//GraphicsPath piepath = new GraphicsPath();
//piepath.AddPie(
}
}
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.pbScope = new System.Windows.Forms.PictureBox();
this.pbBackground = new System.Windows.Forms.PictureBox();
this.pbSubmarine = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pbScope)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pbBackground)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pbSubmarine)).BeginInit();
this.SuspendLayout();
//
// pbScope
//
this.pbScope.Location = new System.Drawing.Point(12, 12);
this.pbScope.Name = "pbScope";
this.pbScope.Size = new System.Drawing.Size(300, 300);
this.pbScope.TabIndex = 0;
this.pbScope.TabStop = false;
//
// pbBackground
//
this.pbBackground.Image = ((System.Drawing.Image)(resources.GetObject("pbBackground.Image")));
this.pbBackground.Location = new System.Drawing.Point(341, 12);
this.pbBackground.Name = "pbBackground";
this.pbBackground.Size = new System.Drawing.Size(300, 300);
this.pbBackground.TabIndex = 1;
this.pbBackground.TabStop = false;
this.pbBackground.Visible = false;
//
// pbSubmarine
//
this.pbSubmarine.Image = ((System.Drawing.Image)(resources.GetObject("pbSubmarine.Image")));
this.pbSubmarine.Location = new System.Drawing.Point(658, 45);
this.pbSubmarine.Name = "pbSubmarine";
this.pbSubmarine.Size = new System.Drawing.Size(48, 48);
this.pbSubmarine.TabIndex = 2;
this.pbSubmarine.TabStop = false;
this.pbSubmarine.Visible = false;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(326, 328);
this.Controls.Add(this.pbSubmarine);
this.Controls.Add(this.pbBackground);
this.Controls.Add(this.pbScope);
this.Name = "Form1";
this.Text = "Radar";
this.Load += new System.EventHandler(this.Form1_Load);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
((System.ComponentModel.ISupportInitialize)(this.pbScope)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pbBackground)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pbSubmarine)).EndInit();
this.ResumeLayout(false);
}
你可以在代码中编辑?今天的标准不仅仅需要外部链接。 – 2014-03-05 12:00:42
当然,虽然发布依赖于控件初始化和布局等的代码并不是非常实用 – MusiGenesis 2014-03-05 17:15:13
- 1. 在ruby中模拟第三方对象的最佳方法是什么?
- 2. 在Grails中建模地图值的最佳方法是什么?
- 3. 在C#中评估sql语句的最佳方法是什么?
- 4. 在C中重置char []的最佳方法是什么?
- 5. 在C#.NET中保存cookie的最佳方法是什么?
- 6. 在C++中检查代理的最佳方法是什么?
- 7. 模拟XAML代码继承的最佳方式是什么?
- 8. Rails:模拟这个has_and_belongs_to_many协会的最佳方式是什么
- 9. 在Linux上为Ruboto设置Android模拟器的最佳方法是什么?
- 10. 在HTML textarea上模拟HTML输入“maxlength”属性的最佳方法是什么?
- 11. 模仿c#中findstr功能的最佳方式是什么?
- 12. 将数据存储在objective-c模型中的最佳方法是什么?
- 13. 实现雷达模拟
- 14. 评论的最佳方法是什么?
- 15. 用C学习GLADE的最佳/最快方法是什么?
- 16. 模拟复杂的生产Web开发环境的最佳方法是什么?
- 17. 验证C#中readline输入的最佳方法是什么?
- 18. 在HTML中模拟水平XAML StackPanel的最佳方式是什么?
- 19. 模拟WAN网络的最佳方法
- 20. 模拟域的最佳方法?
- 21. 数据库:模拟这些需求的最佳方法是什么?
- 22. 执行数学表达式的最佳方法是什么?
- 23. 什么是最佳搜索方法?
- 24. 在Delphi中实现C#的BackgroundWorker的最佳方式是什么?
- 25. 通过HTTP模拟过程调用的最佳/最RESTful方式是什么?
- 26. 什么是在rails中排名模型的最佳方式
- 27. 在Django模型中表示URL的最佳方式是什么?
- 28. 在C#中,测试数据集是否为空的最佳方法是什么?
- 29. 在C#中做事情的最佳方式是什么?
- 30. 在C++中清除容器的最佳方式是什么?
该死!这听起来很疯狂......想想我会按照上面JW的建议去阅读GDI +的初学者。谢谢。没玩过潜艇;我更喜欢NES版的“寻找红十月”。 – 2009-08-16 17:29:12
这并不复杂,它实际上只是Jason的回答。我也在谈论GDI +和处理Paint事件。 – MusiGenesis 2009-08-16 17:37:00
双缓冲部分对于避免闪烁是必不可少的。 – MusiGenesis 2009-08-16 17:37:35