源码: 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 } } |
|