• C#开发一个如上的工业仪表盘控件



    1写一个类继承自UserControl,我们给它起名为Dial
    2定义他的刻度属性,
      public int V//当前刻度1,省略VV(刻度2)
      {
       get
       {
        return mV;
       }
       set
       {
        if(mV==value)return;
        mV=value;
        Refresh();
       }
      }
      public int MaxMain//最大刻度 省略MaxM(刻度二的最大值)
      {
       get
       {
        return mMaxMain;
       }
       set
       {
        if(mMaxMain==value)return;
        mMaxMain=value;  
        Refresh();
       }
      }
    3在它的绘图事件下写下绘制表盘的代码(呵呵,这是重点呃)
      private void Dial_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
      {

       Rectangle rect1=this.ClientRectangle;
       rect1.Y+=3;
       rect1.Height=rect1.Width;
       e.Graphics.DrawArc(Pens.DarkGray,rect1,180+30,120);//画表盘圆弧1

       Rectangle rect2=this.ClientRectangle;
       rect2.Y+=3;
       rect2.X+=15;
       rect2.Y+=15;
       rect2.Width-=30;
       rect2.Height=rect2.Width;
       e.Graphics.DrawArc(Pens.DarkGray,rect2,180+30,120);//画表盘圆弧2
       Rectangle rect3=rect2;
       rect3.X+=50;
       rect3.Y+=50;
       rect3.Width-=100;
       rect3.Height-=100;
       e.Graphics.DrawArc(Pens.DarkGray,rect3,180+30,120);//画表盘圆弧3


       Rectangle rect4=rect2;
       rect4.X+=10;
       rect4.Y+=10;
       rect4.Width-=20;
       rect4.Height-=20;
       e.Graphics.DrawArc(Pens.DarkGray,rect4,180+30,120);//画表盘圆弧4

       int ox=rect1.Width/2+rect1.Left;
       int oy=rect1.Height/2+rect1.Top;

       double rad=0;
       Point pt1=new Point(0,0);
       Point pt2=new Point(0,0);

       for(int i=0;i<120/10;i++)//画大刻度
       {
        double _rad=PEI/180*10;
        rad=(_rad*i+(PEI/180*30));
        pt1=Trans(rect1.Width/2,rad,ox,oy);
        pt2=Trans(rect2.Width/2,rad,ox,oy);
        e.Graphics.DrawLine(Pens.DarkGray,pt1,pt2);
        pt1=Trans(rect2.Width/2,rad,ox,oy);
        pt2=Trans(rect4.Width/2,rad,ox,oy);
        e.Graphics.DrawLine(Pens.DarkGray,pt1,pt2);

       }
       for(int i=0;i<120/2;i++)//画细刻度
       {
        double _rad=PEI/180*2;
        rad=(_rad*i+(PEI/180*30));
        pt1=Trans(rect1.Width/2,rad,ox,oy);
        pt2=Trans(rect1.Width/2-5,rad,ox,oy);
        e.Graphics.DrawLine(Pens.DarkGray,pt1,pt2);
        pt1=Trans(rect2.Width/2,rad,ox,oy);
        pt2=Trans(rect2.Width/2-5,rad,ox,oy);
        e.Graphics.DrawLine(Pens.DarkGray,pt1,pt2);
       }
       pt1=Trans(rect1.Width/2,PEI/180*30,ox,oy);
       pt2=Trans(rect3.Width/2,PEI/180*30,ox,oy);
       e.Graphics.DrawLine(Pens.DarkGray,pt1,pt2);//画表盘直边1
       pt1=Trans(rect1.Width/2,PEI/180*150,ox,oy);
       pt2=Trans(rect3.Width/2,PEI/180*150,ox,oy);
       e.Graphics.DrawLine(Pens.DarkGray,pt1,pt2);//画表盘直边2
       double v=120;
       v/=MaxMain;
       v*=V;
       v=(PEI/180*v+PEI/180*30);
       pt1=Trans(rect1.Width/2,v,ox,oy);
       pt2=Trans(rect2.Width/2,v,ox,oy);
       e.Graphics.DrawLine(Pens.Red,pt1,pt2);//画指针1


       v=120;
       v/=MaxMain;
       v*=VV;
       v=(PEI/180*v+PEI/180*30);
       pt1=Trans(rect2.Width/2,v,ox,oy);
       pt2=Trans(rect4.Width/2,v,ox,oy);
       e.Graphics.DrawLine(Pens.Red,pt1,pt2);//画指针2

       pt1=Trans(rect3.Width/2-5,PEI/180*50,ox,oy);
       pt2=Trans(rect3.Width/2-5,PEI/180*130,ox,oy);
       Rectangle tr=new Rectangle(pt2,new Size(pt1.X-pt2.X,15));
       FontFamily fontFamily = new FontFamily("Arial");
       Font font = new Font(
        fontFamily,
        9,
        FontStyle.Regular,
        GraphicsUnit.Point);
       e.Graphics.DrawRectangle(Pens.DarkBlue,tr);
       e.Graphics.DrawString(V.ToString()+"."+VV.ToString(),font,Brushes.Red,tr);//绘制数字窗口
       font.Dispose();
       
      }

    好像一切都挺顺利,Trans(rect2.Width/2,v,ox,oy);这个东东干什么的?
    这其实正是核心,让我们一起看看:
      private Point Trans(int r,double rad,int ox,int oy)
      {
       Point pt=new Point(0,0);
       int xx=(int)(r*Math.Cos(rad));
       int yy=(int)(r*Math.Sin(rad));
       pt.Y=-yy;
       pt.X=xx;
       pt.X+=ox;
       pt.Y+=oy;
       return pt;

      }
    其实它是求以ox,oy为坐标原点的一个极坐标系中的点所对应的系统中的点的。
    x=r×cos(rad)
    y=r×sin(rad)
    很熟悉吧?
    因为我们和圆弧打交道用极坐标很方便和强大,所以在Dial_Paint()中坐标在计算时都是用极坐标来描述的,在绘图时用Trans()得到GDI的直角坐标! 

  • 相关阅读:
    用laravel写的项目如何布置在虚拟机上
    在Laravel中注册中间件
    ssh出错
    DB2单表导入导出
    DB2 还原数据库
    ssh-keygen 免交互
    DB2 命令
    21个项目玩转深度学习:基于TensorFlow的实践详解06—人脸检测和识别——数据集
    jieba—parallel
    更新数据
  • 原文地址:https://www.cnblogs.com/guola/p/400886.html
Copyright © 2020-2023  润新知