標題:
C#示波器控件 ScopeV1.0
[打印本頁]
作者:
liuda
時間:
2015-1-23 03:10
標題:
C#示波器控件 ScopeV1.0
C#示波器控件 ScopeV1.0
// C#示波器控件 ScopeV1.0 測試版僅供參考
// C# 2008
// author: dzrjojo
// date: 2010.07.28
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace Dongzr.WindPowerTool
{
public partial class Scope : UserControl
{
public const int INTERVAL = 1000; // 采樣時間間隔1000ms
public const int MAX_CURVE_NUM = 10; // 示波器顯示最大曲線數(shù)為10
private const int SCOPE_WIDTH = 500; // 示波器寬度
private const int SCOPE_HEIGHT = 500; // 示波器高度
private const int SCOPE_FRAME = 25; // 示波器邊框寬度
private const int DATA_LENGTH = SCOPE_WIDTH; // 示波器最大采樣點數(shù)設為示波器寬度
private Curve[] curve;
// private ReaderWriterLock datas_lock; // 單線程不需要讀寫鎖
private Brush brush;
private Font font;
private Pen white_dash_pen;
private bool hold;
private Bitmap bitmap;
public Scope()
{
InitializeComponent();
}
// 添加曲線
public bool CreateCurve(int id,Color color,string unit)
{
bool re = false;
if (id >= 0 && id < MAX_CURVE_NUM)
{
// datas_lock.AcquireWriterLock(-1);
if (this.curve[id] == null)
{
this.curve[id] = new Curve();
}
if (this.curve[id].show == false)
{
this.curve[id].Init(true, color, DATA_LENGTH, INTERVAL, unit);
re = true;
}
// datas_lock.ReleaseWriterLock();
}
return re;
}
// 刪除曲線
public void RemoveCurve(int id)
{
// datas_lock.AcquireWriterLock(-1);
if (this.curve[id] != null)
{
if (this.curve[id].show == true)
{
this.curve[id].show = false;
}
}
// datas_lock.ReleaseWriterLock();
this.Invalidate();
}
// 添加單點數(shù)據(jù)
public void AddData(int id,float f)
{
if (this.hold == false)
{
// datas_lock.AcquireWriterLock(-1);
if (this.curve[id] != null)
{
if (this.curve[id].show == true)
{
for (int i = Curve.points - 1; i > 0; i--)
{
if (this.curve[id].counter == 0)
{
this.curve[id].data_raw[i].X = 0;
}
else
{
this.curve[id].data_raw[i].X = this.curve[id].data_raw[i - 1].X + 1;
}
this.curve[id].data_raw[i].Y = this.curve[id].data_raw[i - 1].Y;
}
this.curve[id].data_raw[0].X = 0;
this.curve[id].data_raw[0].Y = f;
if (this.curve[id].counter < Curve.points)
{
this.curve[id].counter++;
}
}
}
// datas_lock.ReleaseWriterLock();
this.Invalidate();
}
}
// 暫停波形
public bool Hold
{
set
{
this.hold = value;
}
}
// 設置曲線參數(shù)
private void SetCurveOffsetX(int id, int offset_x) // 暫時禁止X軸偏置設置,其原點在右,向左為正方向
{
if (this.curve[id] != null)
{
Curve.offset_x = offset_x;
this.Invalidate();
}
}
public void SetCurveOffsetY(int id, int offset_y)
{
if (this.curve[id] != null)
{
this.curve[id].offset_y = offset_y;
this.Invalidate();
}
}
public void SetCurveZoomX(int id, float zoom_x)
{
if (this.curve[id] != null)
{
if (zoom_x >= 1.0f) // 限制X軸縮放比例 >=1
{
Curve.zoom_x = zoom_x;
this.Invalidate();
}
}
}
public void SetCurveZoomY(int id, float zoom_y)
{
if (this.curve[id] != null)
{
this.curve[id].zoom_y = zoom_y;
}
}
// 示波器初始化
private void Scope_Load(object sender, EventArgs e)
{
// datas_lock = new ReaderWriterLock();
curve = new Curve[MAX_CURVE_NUM];
Curve.InitStatic(DATA_LENGTH, INTERVAL, 0, 1.0f);
brush = new SolidBrush(Color.Yellow);
font = new Font("SimSun", 10, System.Drawing.FontStyle.Regular);
white_dash_pen = new Pen(Color.White, 1);
white_dash_pen.DashStyle = DashStyle.Dot;
hold = false;
}
// size改變時刷新
private void Scope_Resize(object sender, EventArgs e)
{
this.Invalidate();
}
// 右鍵菜單about
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Scope V1.0\r\n\r\nCopyRight dongzr 2010-2012", "About...");
}
// 繪圖,雙緩沖在Scope屬性里設置
private void Scope_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighSpeed;
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.Clear(Color.DarkGray);
g.ScaleTransform(-(float)this.Width / (SCOPE_WIDTH + SCOPE_FRAME*2),
-(float)this.Height / (SCOPE_HEIGHT + SCOPE_FRAME*2) ); // 縮放,并使XY軸反向
g.TranslateTransform(-(SCOPE_WIDTH + SCOPE_FRAME) , - (SCOPE_HEIGHT/2 + SCOPE_FRAME)); // 新的坐標原點,位于波形顯示區(qū)的右側中點
// 示波器顯示范圍指示
g.SetClip(new Rectangle(0, SCOPE_HEIGHT / 2 + 5, SCOPE_WIDTH, SCOPE_FRAME - 10));
g.Clear(Color.Black);
g.DrawRectangle(Pens.YellowGreen, new Rectangle(0, SCOPE_HEIGHT / 2 + 10, (int)(SCOPE_WIDTH / Curve.zoom_x), SCOPE_FRAME - 20));
// 繪制零點指示標志
g.SetClip(new Rectangle(SCOPE_WIDTH + 5, -SCOPE_HEIGHT / 2, SCOPE_FRAME - 10, SCOPE_HEIGHT));
g.Clear(Color.Black);
for (int ls = 0; ls < MAX_CURVE_NUM; ls++)
{
if (this.curve[ls] != null)
{
if (this.curve[ls].show == true)
{
g.DrawLine(this.curve[ls].pen, SCOPE_WIDTH + 5, this.curve[ls].offset_y, SCOPE_WIDTH + 15, this.curve[ls].offset_y + 3);
g.DrawLine(this.curve[ls].pen, SCOPE_WIDTH + 5, this.curve[ls].offset_y, SCOPE_WIDTH + SCOPE_FRAME - 5, this.curve[ls].offset_y);
g.DrawLine(this.curve[ls].pen, SCOPE_WIDTH + 5, this.curve[ls].offset_y, SCOPE_WIDTH + 15, this.curve[ls].offset_y - 3);
}
}
}
// 設置作圖區(qū)域為波形顯示區(qū),大小為SCOPE_WIDTH*SCOPE_HEIGHT
g.SetClip(new Rectangle(0, -SCOPE_HEIGHT / 2, SCOPE_WIDTH, SCOPE_HEIGHT));
g.Clear(Color.Black);
// 繪制坐標網(wǎng)格
for (int step = SCOPE_WIDTH / 50,i = 0; i <= 50; i++)
{
if (i % 5 == 0)
{
g.DrawLine(white_dash_pen, i * step, -SCOPE_HEIGHT / 2, i * step, SCOPE_HEIGHT / 2);
}
else
{
g.DrawLine(white_dash_pen, i * step, -SCOPE_HEIGHT / 2, i * step, -SCOPE_HEIGHT / 2 + step / 2);
// g.DrawLine(white_dash_pen, i * step, -step / 4, i * step, step / 4);
g.DrawLine(white_dash_pen, i * step, SCOPE_HEIGHT / 2, i * step, SCOPE_HEIGHT / 2 - step / 2);
}
}
for (int step = SCOPE_HEIGHT / 50, i = -25; i <= 25; i++)
{
if (i % 5 == 0)
{
g.DrawLine(white_dash_pen, SCOPE_WIDTH, i * step, 0, i * step);
}
else
{
g.DrawLine(white_dash_pen, SCOPE_WIDTH, i * step, SCOPE_WIDTH - step / 2, i * step);
// g.DrawLine(white_dash_pen, SCOPE_WIDTH / 2 + step / 4, i * step, SCOPE_WIDTH / 2 - step / 4, i * step);
g.DrawLine(white_dash_pen, step / 2, i * step, 0, i * step);
}
}
// 繪制data
// datas_lock.AcquireWriterLock(-1);
for (int ls = 0; ls < MAX_CURVE_NUM; ls++)
{
if (this.curve[ls] != null)
{
if (this.curve[ls].show == true)
{
// data變換
for (int i = 0; i < Curve.points; i++)
{
this.curve[ls].data_show[i].X = this.curve[ls].data_raw[i].X * Curve.zoom_x + Curve.offset_x;
this.curve[ls].data_show[i].Y = this.curve[ls].data_raw[i].Y * this.curve[ls].zoom_y + this.curve[ls].offset_y;
}
// 顯示
g.DrawLines(this.curve[ls].pen, this.curve[ls].data_show);
}
}
}
// datas_lock.ReleaseWriterLock();
// 繪制單位坐標
g.ScaleTransform(-1, -1);
g.SetClip(new Rectangle(-SCOPE_WIDTH, SCOPE_HEIGHT / 2 + 5, SCOPE_WIDTH, SCOPE_FRAME - 10));
g.Clear(Color.Black);
g.DrawString("10 9 8 7 6 5 4 3 2 1 0", font, brush, -SCOPE_WIDTH, SCOPE_HEIGHT / 2 + 5);
g.RotateTransform(-90);
g.SetClip(new Rectangle(-SCOPE_HEIGHT / 2 , 5, SCOPE_HEIGHT, SCOPE_FRAME - 10));
g.Clear(Color.Black);
g.DrawString("-5 -4 -3 -2 -1 0 1 2 3 4 5", font, brush, -SCOPE_HEIGHT / 2, 5);
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
bool isSave = true;
SaveFileDialog saveImageDialog = new SaveFileDialog();
saveImageDialog.Title = "Save Scope image";
saveImageDialog.Filter = @".bmp|*.bmp";
if (saveImageDialog.ShowDialog() == DialogResult.OK)
{
string fileName = saveImageDialog.FileName.ToString();
if (fileName != "" && fileName != null)
{
System.Drawing.Imaging.ImageFormat imgformat = null;
imgformat = System.Drawing.Imaging.ImageFormat.Bmp;
if (isSave)
{
try
{
bitmap = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
this.DrawToBitmap(bitmap, this.ClientRectangle);
bitmap.Save(fileName, imgformat);
MessageBox.Show("圖片已經(jīng)成功保存!");
}
catch
{
MessageBox.Show("保存失敗!");
}
finally
{
bitmap.Dispose();
}
}
}
}
}
}
internal class Curve
{
public bool show; // 是否顯示
public PointF[] data_raw; // 數(shù)據(jù)原始值
public PointF[] data_show; // 數(shù)據(jù)顯示值
public Pen pen; // 畫筆
public static int points; // 采樣點數(shù)
public string unit; // 數(shù)據(jù)的單位
public static int interval; // 采樣點的時間間隔,單位ms
public static int offset_x; // 橫軸偏置
public int offset_y; // 縱軸偏置
public static float zoom_x; // 橫軸縮放比例
public float zoom_y; // 縱軸縮放比例
public int counter;
public Curve()
{
this.show = false;
}
public static void InitStatic(int points, int interval, int offset_x, float zoom_x)
{
Curve.points = points;
Curve.interval = interval;
Curve.offset_x = offset_x;
Curve.zoom_x = zoom_x;
}
public void Init(bool show, Color color, int points, int interval, string unit)
{
this.show = show;
this.unit = unit;
this.pen = new Pen(color, 1);
this.data_raw = new PointF[Curve.points];
this.data_show = new PointF[Curve.points];
this.offset_y = 0;
this.zoom_y = 1.0f;
this.counter = 0;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
this.scope1.CreateCurve(0, Color.Yellow, "");
this.scope1.SetCurveZoomY(0,100);
this.scope1.CreateCurve(1, Color.Cyan, "");
for(int i = 0;i<500;i++)
{
this.scope1.AddData(0,sin(3.14* i / 100));
this.scope1.AddData(1,cos(3.14* i / 100));
}
this.scope1.RemoveCurve(1);
復制代碼
作者:
12345678901
時間:
2015-10-25 02:28
這個怎么用。
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1