What would be the best way to simulate Radar in C#?

后端 未结 4 1837
北海茫月
北海茫月 2020-12-20 00:33

I have a Picture box inside a Groupbox in my form with the Picture of a radar set as the background picture. My intention is to dynamically load tiny Jpeg images within the

相关标签:
4条回答
  • 2020-12-20 00:59

    It depends a lot on what your "radar" needs to look like, but almost certainly you'll need to implement the Paint event handler, and draw the contents of the radar display yourself. A picture box will only get you so far ("not very").

    GDI+ is very easy to use to draw circles, lines, text, and images, and will give you complete control over how your display looks.

    0 讨论(0)
  • 2020-12-20 01:09

    Click here to run a sample application that demonstrates the basics of how to do radar (or one way, at least). Note: this application does not do double-buffering or transparency of the tiny image.

    Source code for the project is here.

    Update code:

    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);
    
        }
    
    0 讨论(0)
  • 2020-12-20 01:14

    The simplest way is to load your tiny JPEGs into tiny PictureBoxes, and add them to the main PictureBox's Controls collection (i.e. place them on the PictureBox) at runtime.

    Since this will probably produce flicker, the slightly more complex way is to keep the main picture and the tiny pictures in class-level Bitmap objects, and in the main PictureBox's Paint event, you copy the main picture followed by each tiny picture onto a second class-level Bitmap (named _doubleBuffer or something like that) using the DrawImage method, and then copy _doubleBuffer onto your PictureBox (also using DrawImage). Whenever you need to update your display and redraw everything, you just call the PictureBox's Invalidate method.

    There are loads of examples here on SO that show how to use these methods. Good luck, it sounds fun (if you're rewriting the classic arcade game Submarine, let me know - I loved that game).

    0 讨论(0)
  • 2020-12-20 01:17

    As for actual example:

      // 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);
          }
        }
      }
    

    This of course is very basic, assumes image source is path and doesn't take care of many intricate things, but that's the quick and dirty jist of it which you can certainly build on.

    0 讨论(0)
提交回复
热议问题