因为项目需要做一个电子飞行仪表盘包括地平仪和磁罗盘,网上找了很久,没有找到一个合适的控件,就学习了一些图形处理的开源代码做一个简陋的仪表盘来使用,希望对其他人有帮助,如果有好的建议不妨留言
源程序代码https://download.csdn.net/download/qq_42237381/10877536
目录
一、效果示意
二、原理说明
三、代码参考
一、效果示意
飞行仪表应用于飞行器上主要是飞行姿态角的监测
包括俯仰角,偏航角和滚动角
点击开始按钮,随机生成姿态角

二、原理说明
既然要仿真一些,先从网上找几个机械仪表的样式来学习,再从网上找些图片当做背景来使用
好了,这个就是俯仰角的表盘背景,需要将将它切割成一个圆,通过移动图片的位置在图片框的显示,不同的角度,滚动角可以和这个表放一起,滚动了多少度将图片旋转多少度,在写一圈的刻度值即可。

再找一个磁罗盘的图片,需要代码将它切割成一个圆,里面的表盘也用个截图工具截下来,只需要代码让里面的表盘转动既可以达到效果

三、代码参考
开始编程,创建WINFORM程序,添加两个图片框控件,一个按钮控件,一个时间控件。
程序如下,
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;namespace Dashboard
{public partial class Form1 : Form{public Image imgtmp;public Image imgori;public Bitmap bitmp;public Bitmap bm;public bool IsSure = false;double DbPitchAngle = new double(); //俯仰角度[-90,90]double DbRowAngle = new double(); //滚转角度[-180,180]double DbYawAngle = new double(); //航向角度[-45,45]public Form1(){InitializeComponent();}//重绘旋转后的仪表盘图片 public void Overlap(Bitmap btm, int x, int y, int w, int h){Bitmap image = new Bitmap(btm);Bitmap hi = new Bitmap(bm);Graphics g = Graphics.FromImage(hi);g.DrawImage(image, new Rectangle(x, y, w, h));bm = hi;}//-------------------磁罗盘显示函数-------------------////入口参数://航向角 dir_angle 范围0~360 度 private void Compass_Disp(double dir_angle){string file = System.IO.Path.Combine(Environment.CurrentDirectory, @"point.jpg");bitmp = new Bitmap(file);Bitmap pointImage = new Bitmap(250, 250);System.Drawing.Graphics gPoint = System.Drawing.Graphics.FromImage(pointImage);gPoint.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;gPoint.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//计算偏移量Rectangle rectPoint = new Rectangle(0, 0, 250, 250);gPoint.TranslateTransform(125, 125);//g.RotateTransform(360 - row_angle);gPoint.RotateTransform((float)dir_angle);//恢复图像在水平和垂直方向的平移 gPoint.TranslateTransform(-125, -125);gPoint.DrawImage(bitmp, rectPoint);//重至绘图的所有变换 gPoint.ResetTransform();gPoint.Dispose();//保存旋转后的图片bm = pointImage;Overlap(pointImage, 0, 0, 250, 250);CompointBox.Image = bm;// 刻度盘截圆System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();gp.FillMode = 0;gp.AddEllipse(new Rectangle(0, 0, 350, 350));ComshellBox.Region = new Region(gp);//表盘截圆System.Drawing.Drawing2D.GraphicsPath gp1 = new System.Drawing.Drawing2D.GraphicsPath();gp1.FillMode = 0;gp1.AddEllipse(new Rectangle(0, 0, 250, 250));CompointBox.Region = new Region(gp1);gp1.Dispose();gp.Dispose();gPoint.Dispose();bitmp.Dispose();//Graphics gp1 = CompointBox.CreateGraphics();//gp1.DrawEllipse()}//-------------------地平仪刻度划线函数-------------------////入口参数:无 public Image Hori_Line(){bitmp = new Bitmap(350, 350);System.Drawing.Graphics gscale = System.Drawing.Graphics.FromImage(bitmp);Pen p1 = new Pen(Color.Red, 4);Pen p2 = new Pen(Color.Green, 3);//准心绘线//gscale.DrawEllipse(Pens.Red ,165, 165, 20, 20);gscale.DrawLine(p2, 145, 175, 205, 175);gscale.DrawLine(p1, 145, 185, 175, 175);gscale.DrawLine(p1, 205, 185, 175, 175);//滚转刻度线gscale.DrawEllipse(Pens.White, 35, 35, 280, 280);int i, i1, j, j1, k;for (k = 0; k < 73; k++){i = Convert.ToInt32(140 * Math.Cos(k * Math.PI / 36) + 175);j = Convert.ToInt32(140 * Math.Sin(k * Math.PI / 36) + 175);if (k % 2 == 0){i1 = Convert.ToInt32(155 * Math.Cos(k * Math.PI / 36) + 175);j1 = Convert.ToInt32(155 * Math.Sin(k * Math.PI / 36) + 175);}else{i1 = Convert.ToInt32(150 * Math.Cos(k * Math.PI / 36) + 175);j1 = Convert.ToInt32(150 * Math.Sin(k * Math.PI / 36) + 175);}gscale.DrawLine(Pens.White, i, j, i1, j1);}gscale.Dispose();return bitmp;}//-------------------地平仪显示函数-------------------////入口参数://俯仰角 pitch_angle 范围-90~90 度 //滚动角 row_angle 范围-90~90 度private void Hori_Disp(double pitch_angle, double row_angle){//1地平仪图像载入带平移int pic_position;pic_position = Convert.ToInt32(pitch_angle * 3.86);string file = System.IO.Path.Combine(Environment.CurrentDirectory, @"11.jpg");try{imgtmp = new Bitmap(file);row_angle = row_angle % 360;//弧度转换 double ar = 2;double radian = (row_angle - 90) * Math.PI / 180.0;double radiana = (row_angle - 90 - ar) * Math.PI / 180.0;double radianc = (row_angle - 90 + ar) * Math.PI / 180.0;double cos = Math.Cos(radian);double cosa = Math.Cos(radiana);double cosc = Math.Cos(radianc);double sin = Math.Sin(radian);double sina = Math.Sin(radiana);double sinc = Math.Sin(radianc);//目标位图Bitmap dsImage = new Bitmap(350, 350);System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(dsImage);g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//计算偏移量Rectangle rect = new Rectangle(-175, -175 + pic_position, 700, 700);g.TranslateTransform(175, 175);g.RotateTransform((float)row_angle);//恢复图像在水平和垂直方向的平移 g.TranslateTransform(-175, -175);g.DrawImage(imgtmp, rect);//重至绘图的所有变换 g.ResetTransform();g.Dispose();//保存旋转后的图片bm = dsImage;//调用imgori 已经是画好的刻度盘Bitmap bitmp = new Bitmap(imgori);Overlap(bitmp, 0, 0, 350, 350);Bitmap pointImage = new Bitmap(350, 350);// 指针设计 ;System.Drawing.Graphics gPoint = System.Drawing.Graphics.FromImage(pointImage);SolidBrush h = new SolidBrush(Color.Red);Point a = new Point(Convert.ToInt32(175 + 131 * cosa), Convert.ToInt32(180 + 131 * sina));Point b = new Point(Convert.ToInt32(141 * cos + 175), Convert.ToInt32(141 * sin + 175));Point c = new Point(Convert.ToInt32(175 + 131 * cosc), Convert.ToInt32(180 + 131 * sinc));Point[] pointer = { a, b, c };gPoint.FillPolygon(h, pointer);Overlap(pointImage, 0, 0, 350, 350);HoriBox.Image = bm;g.Dispose();imgtmp.Dispose();}catch (Exception ex){MessageBox.Show(ex.Message);}System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();gp.FillMode = 0;gp.AddEllipse(new Rectangle(0, 0, 350, 350));HoriBox.Region = new Region(gp);gp.Dispose();}/// <summary>/// 开始按钮点击/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button1_Click(object sender, EventArgs e){if (IsSure == false){timer1.Enabled = true;IsSure = true;button1.Text = "停止";}else{timer1.Enabled = false;IsSure = false;button1.Text = "开始";}}private void timer1_Tick(object sender, EventArgs e){double DbPitchAngle = 0; //俯仰角度[-90,90]double DbRowAngle = 0; //滚转角度[-180,180]double DbYawAngle = 0; //航向角度[-45,45]Random pR = new Random();Random rR = new Random();Random yR = new Random();DbPitchAngle = pR.Next(0, 90);DbRowAngle = rR.Next(-180, 180);DbYawAngle = yR.Next(-45,45);Hori_Disp(DbPitchAngle, DbRowAngle);Compass_Disp(DbYawAngle);Hori_Line();}private void Form1_Load(object sender, EventArgs e){imgori = Hori_Line();}}
}

















