分享

C#绘制等值线(源码)

 超弦 2017-07-31

源码: 

using System; 

using System.Collections.Generic; 

using System.ComponentModel;

 using System.Data; using System.Drawing; using System.Text; 

using System.Windows.Forms; 

 

namespace MyContour

 { 

public partial class frmMain : Form   

  { 

        #region 属性  

        public static bool showPoint = false;        

 public static bool drawLines = true;        

 private float[,] _Data;        

 /// <summary> 

        /// 等值线原始格点数据        

 /// </summary>         

public float[,] Data         

            get { return _Data; }            

 set { _Data = value; }         

}  

        

private float[] _ContourValues;         

/// <summary> 

 /// 等值线值数组        

 /// </summary> 

        public float[] ContourValues        

 { 

            get { return _ContourValues; }             

set { _ContourValues = value; }         

}          

        #endregion

  

        #region 窗体所有操作  

        public frmMain()        

 { 

            InitializeComponent();            

 MakeTestData();             

setColor(); 

            gg = pictureBox1.CreateGraphics();      

   }  

 

        private void button1_Click(object sender, EventArgs e)         

            this.timer1.Enabled = false;  

            initValue();  //重新初始化绘制路径的数组 

MakeTestData();        

 pictureBox1.Refresh();         

}  

        

private void pictureBox1_Paint(object sender, PaintEventArgs e)      

  { 

         if (this.Data == null) return;         

StringFormat sf = new StringFormat();            

 sf.Alignment = StringAlignment.Center;            

 sf.LineAlignment = StringAlignment.Center;            

 Pen pen = new Pen(Color.DarkGray, 1);             

//绘制等值线             

if (drawLines)             

                this.plotContour(e.Graphics, pictureBox1.Size);             

            //绘制网格 

            if (frmMain.showPoint)             

                int ww = pictureBox1.Width / (Data.GetLength(0) - 1); //x轴间隔长度                 

int yy = pictureBox1.Height / (Data.GetLength(1) - 1);//y轴间隔长度  

                

//绘制网格横竖线 

                for (int p = 0; p < Data.GetLength(0); p++)                 

             e.Graphics.DrawLine(pen, new Point(p * ww, 0), new Point((p) * ww, pictureBox1.Height));

 

                for (int k = 0; k < Data.GetLength(1); k++)    

             { 

                    e.Graphics.DrawLine(pen, new Point(0, k * yy), new Point(pictureBox1.Width, k * yy)); 

                 } 

 

                //绘制网格斜线 

                for (int j = 0; j < Data.GetLength(0) - 1; j++)                 

                    for (int i = 1; i < Data.GetLength(1); i++)  

                  { 

                  e.Graphics.DrawLine(pen, new Point(j * ww, (i - 1) * yy), new Point((j + 1) * ww, i * yy)); 

                  e.Graphics.DrawLine(pen, new Point(j * ww, i * yy), new Point((j + 1) * ww, (i - 1) * yy));                       }             

   }

 

      //绘制格点值 

     for (int j = 0; j < Data.GetLength(1); j++)            

     { 

            for (int i = 0; i < Data.GetLength(0); i++)                   

  { 

                     e.Graphics.DrawString(Data[i, j].ToString("f0"), DefaultFont, Brushes.Blue, i * pictureBox1.Width / (Data.GetLength(0) - 1), j * pictureBox1.Height / (Data.GetLength(1) - 1), sf);  

              }

       }

 }

 }  

  private void pictureBox1_SizeChanged(object sender, EventArgs e)       

  { 

        pictureBox1.Refresh();        

 }  

  

 private void setColor()        

 { 

label1.BackColor = getSpectrumColor(0f);             label2.BackColor = getSpectrumColor(1f);             label3.BackColor = getSpectrumColor(2f);             label4.BackColor = getSpectrumColor(3f);             label5.BackColor = getSpectrumColor(4f);             label6.BackColor = getSpectrumColor(5f);             label7.BackColor = getSpectrumColor(6f);             label8.BackColor = getSpectrumColor(7f);        

 }  

        

private void checkBox1_CheckedChanged(object sender, EventArgs e)        

 { 

frmMain.showPoint = checkBox1.Checked;             

pictureBox1.Refresh();         

}  

       

 //生成路径按钮 

private void button2_Click(object sender, EventArgs e)       

 { 

drawLines = false; 

 this.pictureBox1.Refresh();             

nums = 0; 

if (drawValues[nums].color != null)           

  { 

pens.Color = drawValues[nums].color; 

        gg.DrawLine(pens, drawValues[nums].x1, drawValues[nums].y1, drawValues[nums].x2, drawValues[nums].y2); 

         nums++;             

}            

 Else

 { 

            this.timer1.Enabled = false;                

 nums = 0;            

 } 

            timer1.Enabled = true;             

drawLines = true;        

 }  

        

Graphics gg = null;  //绘制路径的对象        

Pen pens = new Pen(Color.Black, 1); 

 

private void timer1_Tick(object sender, EventArgs e)         

 if (drawValues[nums].color != Color.FromArgb(0, 0, 0))            

 { 

pens.Color = drawValues[nums].color; 

gg.DrawLine(pens, drawValues[nums].x1, drawValues[nums].y1, drawValues[nums].x2, drawValues[nums].y2);                 

nums++;             

}            

 else             

         this.timer1.Enabled = false;                 

nums = 0;            

 }         

}          

#endregion  

 

 #region 绘制等值线操作  

 /// <summary>         

/// 生成测试数据         

/// </summary> 

 

 public void MakeTestData()        

 { 

const int nx = 10, ny = 10, nv = 7;  

 _ContourValues = new float[nv]; 

 for (int i = 0; i < nv; i++)             

        _ContourValues[i] = i*10;             

}   

   _Data = new float[nx,ny];  //nx,ny            

 Random ran = new Random();            

 for(int j=0;j<ny;j++)            

 { 

      for(int i=0;i<nx;i++)                 

          _Data[i, j] = ran.Next(0, 70); 

 //如果格点值等于等值线值,格点值加一个小值                     

for (int k = 0; k < nv; k++)                    

 { 

                 if (_Data[i, j] == ContourValues[k])   

                          _Data[i, j] += 0.0001f;                    

 }                 

}            

 }         

}          

       

 int v1, v2, v3, small, medium, large;        

 int[] ix = new int[4], iy = new int[4];         

float x1, x2, y1, y2, target; 

 float[] X= new float[5], Y= new float[5], value= new float[5];  

 

 int iX(float x,int width)         

 {  

       return (int)Math.Round(width/(Data.GetLength(0)-1) * x);          

}  

 

 int iY(float y,int height)         

 {  

       return (int)Math.Round(height/(Data.GetLength(1)-1) * y);          

}  

        /// <summary> 

        /// 根据等值线值取得相应级别颜色         /// </summary> 

        /// <param name="value"></param>         /// <returns></returns> 

public Color getSpectrumColor(float value) 

 Color c = Color.Black;             

float c0 = 0.0F,               c1 = 256.0F,               c2 = 256.0F * 2.0F,               c3 = 256.0F * 3.0F,               c4 = 256.0F * 4.0F,               c5 = 256.0F * 5.0F; 

     float Step = c5 * (value) /ContourValues.Length;  

     if (Step > c4 && Step <= c5)            

 { 

                float a = Step - c4; 

                c = Color.FromArgb(255, (int)(255.0F - 255.0F * a / c1), 0);             

      else if (Step > c3 && Step <= c4)            

 { 

                float a = Step - c3; 

                c = Color.FromArgb((int)(255.0F * a / c1), 255, 0);           

  } 

      else if (Step > c2 && Step <= c3)            

 { 

                float a = Step - c2; 

                c = Color.FromArgb(0, 255, (int)(255.0F - 255.0F * a / c1));            

 } 

      else if (Step > c1 && Step <= c2)            

 { 

                float a = Step - c1; 

                c = Color.FromArgb(0, (int)(255.0F * a / c1), 255);             

        else if (Step >= c0 && Step <= c1)             

                float a = Step; 

                c = Color.FromArgb((int)(255.0F - 255.0F * a / c1), 0, 255);             

}

 Else

 { 

                c = Color.Black;             

}  

            return c;

 }  

  

 /// <summary>

/// 插值计算         

/// </summary> 

/// <param name="xa"></param>         

/// <param name="ya"></param>         

/// <param name="xb"></param>        

 /// <param name="yb"></param>         

/// <param name="yy"></param>         

/// <returns></returns> 

  float interp(float xa, float ya, float xb, float yb, float yy)        

 { 

  if ((yb - ya) != 0.0F)             

                return xa + (yy - ya) * (xb - xa) / (yb - ya);            

 }            

 Else

 { 

                return 0.0F;             

}  

 

Font font = new Font("Times New Roman", 8.0f);         

Brush brush = new SolidBrush(Color.Blue);  

       

 //等值线分析及绘图 

 public void plotContour(Graphics g,Size size)        

 { 

            nums = 0; 

            Pen pen = new Pen(Color.Black, 1);             

            for (int j = 0; j < Data.GetLength(1)-1; j++)             

                for (int i = 0; i < Data.GetLength(0)-1; i++)                 

                    //网格四个角坐标,变量值 

                    X[0] = i; Y[0] = j; value[0] = Data[i, j]; 

                    X[1] = i + 1; Y[1] = j; value[1] = Data[i + 1, j];                     

X[2] = i + 1; Y[2] = j+1; value[2] = Data[i + 1, j+1];                     

X[3] = i  Y[3] = j+1; value[3] = Data[i, j+1];           //网格中心点坐标,变量值 

                    X[4] = 0.5F * (X[0] + X[1]); Y[4] = 0.5F * (Y[1] + Y[2]); value[4] = 0.25F * (value[0] + value[1] + value[2] + value[3]);                                        

 v3 = 4;  

                   

 //巡检单元格范围内所有的点信息

              for (v1 = 0; v1 < 4; v1++)                     

                        v2 = v1 + 1; 

                        if (v1 == 3) v2 = 0;  

                        reorder(v1, v2, v3);                         //巡检点范围内所有的点信息 

                        for (int lines = 0; lines < ContourValues.Length; lines++)                         

                            target = ContourValues[lines];  

                            if (value[small] < target && target < value[large])                             

                                x1 = interp(X[small], value[small], X[large], value[large], target); 

                                y1 = interp(Y[small], value[small], Y[large], value[large], target);  

                                if (target > value[medium])                                

 { 

                                    x2 = interp(X[medium], value[medium], X[large], value[large], target); 

                                    y2 = interp(Y[medium], value[medium], Y[large], value[large], target); 

                                 }

                                 else                                

 { 

                                    x2 = interp(X[small], value[small], X[medium], value[medium], target); 

                                    y2 = interp(Y[small], value[small], Y[medium], value[medium], target); 

                                  }                                  

                                pen.Color = getSpectrumColor(target/10); 

                                g.DrawLine(pen, iX(x1,size.Width), iY(y1,size.Height), iX(x2,size.Width), iY(y2,size.Height)); 

                                //g.DrawString(target.ToString(), font, brush, new 

PointF((iX(x1, size.Width) + iX(x2, size.Width)) / 2, (iY(y1, size.Height)+iY(y2,size.Height) / 2)));  

                                drawValues[nums].color = getSpectrumColor(target / 10);  

                              drawValues[nums].x1 = iX(x1, size.Width);                                

 drawValues[nums].y1 = iY(y1, size.Height);                                 

drawValues[nums].x2 = iX(x2, size.Width);

drawValues[nums].y2 = iY(y2, size.Height);                                 

nums++;                            

 }

}

            }

     }

 }

       } 

       

 

 int nums = 0;        

 struct DrawValues        

 { 

public Color color;             

public int x1;            

 public int y1;             

public int x2;             

public int y2;        

 }  

 

 DrawValues []drawValues = new DrawValues[90000]; //存储绘制点的信息  

/// <summary> 

/// 根据i,j,k三点值,算出大中小三点        

/// </summary> 

 /// <param name="i"></param>         

/// <param name="j"></param>        

 /// <param name="k"></param>         

void reorder(int i, int j, int k)         

            int temp;  

            large = i;            

 medium = j;             

small = k;  

            if (value[small] > value[medium])             

                temp = medium;                 

medium = small;                 

small = temp;            

 }  

            if (value[medium] > value[large])             

                temp = large; 

large = medium;                 

medium = temp;            

 }  

            if (value[small] > value[medium])             

                temp = medium;  

               medium = small;              

   small = temp;            

 }        

 }  

      

  //数组重新初始化 

  private void initValue()         

      drawValues = new DrawValues[90000]; //存储绘制点的信息       

  }   

        #endregion    

 }

 }

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约