900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > C#开发的3D图表控件 适用于winform项目

C#开发的3D图表控件 适用于winform项目

时间:2023-01-17 14:54:42

相关推荐

C#开发的3D图表控件 适用于winform项目

C#开发的3D图表控件,适用于winform项目,

使用了opentk绘制3D图形。图表颜色,文字颜色,均可以替换。欢迎来白嫖。

资源地址:

C#开发的3D图表控件,适用于winform项目,使用了opentk绘制3D图形。图表颜色,文字颜色,均可以替换-C#文档类资源-CSDN下载

核心绘图代码如下:

public class QChart : GLControl

{

private bool _loaded;

private int _x;

private float _rotationx,_rotationy;

private float zIndex = 12;//俯视角度,好看

private bool locked = false;//是否锁定

private readonly Stopwatch _sw = new Stopwatch();

private List<Point3D> points;

public float FontSize { get; set; }

private Dictionary<String, Txture> fts = new Dictionary<string, Txture>();//材质集合

/// <summary>

/// 坐标线条颜色

/// </summary>

public Color LineColor { get; set; }

/// <summary>

/// 点颜色

/// </summary>

public Color DotColor { get; set; }

/// <summary>

/// 标题颜色

/// </summary>

public Color TitleColor { get; set; }

/// <summary>

/// X轴标题

/// </summary>

public String XTitle { get; set; }

/// <summary>

/// Y轴标题

/// </summary>

public String YTitle { get; set; }

/// <summary>

/// Z轴标题

/// </summary>

public String ZTitle { get; set; }

public int XRange { get; set; }

public int YRange { get; set; }

public int ZRange { get; set; }

public QChart()

{

BackColor = Color.White;

LineColor = Color.Gray;

DotColor = Color.Green;

TitleColor = Color.Black;

XTitle = "X";

YTitle = "Y";

ZTitle = "Z";

XRange = 5;

YRange = 3;

ZRange = 3;

_rotationy = 1;

FontSize = 12;//文字大小

}

private double maxx, minx, maxy, miny, maxz, minz;

/// <summary>

/// 传入坐标集合

/// </summary>

/// <param name="points"></param>

public void ShowPoints(List<Point3D> points) {

this.points = points;

if (points==null|| points.Count == 0) return;

maxx = points[0].X;

minx = points[0].X;

maxy = points[0].Y;

miny = points[0].Y;

maxz = points[0].Z;

minz = points[0].Z;

foreach (Point3D p in points) {

if (p.X > maxx) maxx = p.X;

if (p.X < minx) minx = p.X;

if (p.Y > maxy) maxy =p.Y;

if (p.Y < miny) miny = p.Y;

if (p.Z > maxz) maxz = p.Z;

if (p.Z < minz) minz = p.Z;

}

//防止直接到边界

maxx += 0.2;

minx -= 0.2;

maxy += 0.2;

miny -= 0.2;

maxz += 0.2;

minz -= 0.2;

}

/// <summary>

/// 窗体加载

/// </summary>

/// <param name="e"></param>

protected override void OnLoad(EventArgs e)

{

Control.CheckForIllegalCrossThreadCalls = false;

base.OnLoad(e);

this._loaded = true;

//GL.ClearColor(Color.Black);

this.SetupViewport();

Application.Idle += this.Application_Idle;

this._sw.Start();

this.MouseDown += on_MouseDown;

this.MouseLeave += on_MouseLeave;

this.MouseMove += on_MouseMove;

this.MouseUp += on_MouseUp;

this.MouseWheel += on_MouseWheel;

}

/// <summary>

/// 系统空闲

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void Application_Idle(object sender, EventArgs e)

{

while (this.IsIdle)

{

this.Render();

}

}

//时间更新方法

private double ComputeTimeSlice()

{

this._sw.Stop();

double timeSlice = this._sw.Elapsed.TotalMilliseconds;

this._sw.Reset();

this._sw.Start();

return timeSlice;

}

//初始化可视区域

private void SetupViewport()

{

var w = this.Width;

var h = this.Height;

GL.MatrixMode(MatrixMode.Projection);

GL.LoadIdentity();

GL.Viewport(0, 0, w, h); // Use all of the glControl painting area

if (h == 0) h = 1;

Glu.Perspective(60.0f, w / h, 0.01, 100);

Glu.LookAt(0, 0, zIndex, 0, 0, 0, 0, 1, 0);

}

//大小改变

protected override void OnResize(EventArgs e)

{

base.OnResize(e);

if (!this._loaded)

{

return;

}

this.SetupViewport();

this.Invalidate();

}

//窗体的绘图事件

protected override void OnPaint(PaintEventArgs e)

{

base.OnPaint(e);

if (!this._loaded)

{

return;

}

this.Render();

}

//绘图主事件

private void Render()

{

GL.ClearColor(BackColor);//背景色

GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit| ClearBufferMask.StencilBufferBit);

GL.MatrixMode(MatrixMode.Modelview);

GL.LoadIdentity();

GL.Rotate(_rotationx, 1, 0, 0);//X轴旋转

GL.Rotate(_rotationy, 0, 1, 0);//Y轴旋转

GL.Enable(EnableCap.DepthTest);//必须开启深度测试

GL.Enable(EnableCap.AlphaTest);

GL.AlphaFunc(AlphaFunction.Equal, 1.0f);

drawText(0, 0, 0, "hello");

//绘制坐标

GL.Color3(LineColor);//线颜色

//水平线,X面

for(int i = -XRange; i <= XRange; i++) {

GL.Begin(BeginMode.Lines);

GL.Vertex3(i, -YRange, -ZRange);

GL.Vertex3(i, -YRange, ZRange);

GL.End();

}

for (int i = -ZRange; i <= ZRange; i++)

{

GL.Begin(BeginMode.Lines);

GL.Vertex3(-XRange, -YRange, i);

GL.Vertex3(XRange, -YRange,i);

GL.End();

}

//竖直线,Y面

for (int i = -YRange; i <= YRange; i++)

{

GL.Begin(BeginMode.Lines);

GL.Vertex3(-XRange, i, -ZRange);

GL.Vertex3(-XRange, i, ZRange);

GL.End();

}

for (int i = -ZRange; i <= ZRange; i++)

{

GL.Begin(BeginMode.Lines);

GL.Vertex3(-XRange, -YRange, i);

GL.Vertex3(-XRange, YRange, i);

GL.End();

}

//Z面

for (int i = -YRange; i <= YRange; i++)

{

GL.Begin(BeginMode.Lines);

GL.Vertex3(-XRange,i, -ZRange);

GL.Vertex3(XRange, i, -ZRange);

GL.End();

}

for (int i = -XRange; i <= XRange; i++)

{

GL.Begin(BeginMode.Lines);

GL.Vertex3(i,-YRange, -ZRange);

GL.Vertex3(i, YRange, -ZRange);

GL.End();

}

//输出三个坐标标题

// GL.text

//如果有点,才绘制点

if (points != null && points.Count > 0) {

GL.Color3(DotColor);

GL.PointSize(3);

GL.Begin(BeginMode.Points);

foreach (Point3D p in points) {

double x = XRange*( 2 * (p.X - minx) / (maxx - minx)-1);

double y = YRange * (2 * (p.Y - miny) / (maxy - miny) - 1);

double z = ZRange * (2 * (p.Z- minz) / (maxz - minz) - 1);

GL.Vertex3(x, y, z);

}

GL.End();

// GL.DrawPixels

}

this.SwapBuffers();

}

//按键事件

protected override void OnKeyDown(KeyEventArgs e)

{

base.OnKeyDown(e);

if (e.KeyCode == Keys.Space)

{

this._x++;

SetupViewport();

this.Invalidate();

}

}

private bool msDown = false;//是否鼠标按下

private int oldX = 0;//原始X坐标

private int oldY = 0;

private void on_MouseWheel(object sender, MouseEventArgs e)

{

// MessageBox.Show(e.Delta+"");

if (e.Delta > 0)

{

zIndex += 1;

if (zIndex > 20) zIndex = 20;

}

else if (e.Delta < 0)

{

zIndex -= 1;

if (zIndex < 8) zIndex = 8;

}

SetupViewport();

this.Invalidate();

}

private void on_MouseDown(object sender, MouseEventArgs e)

{

msDown = true;

oldX = e.X;//记录

oldY = e.Y;

Cursor = Cursors.Hand;

;

}

private void on_MouseMove(object sender, MouseEventArgs e)

{

if (!msDown) return;

int dx = e.X - oldX;

int dy = e.Y - oldY;

if (dy > 0) _rotationx += 0.5f;

else if (dy < 0) _rotationx -= 0.5f;

if (dx > 0) _rotationy += 0.5f;

else if (dx < 0) _rotationy -= 0.5f;

SetupViewport();

this.Invalidate();

}

private void on_MouseUp(object sender, MouseEventArgs e)

{

msDown = false;

Cursor = Cursors.Default;

}

private void on_MouseLeave(object sender, EventArgs e)

{

msDown = false;

}

double pixrate = 0.05;//像素比

/// <summary>

/// GL绘制文字

/// </summary>

/// <param name="x">显示文字的x坐标</param>

/// <param name="y">显示文字的y坐标</param>

/// <param name="z">显示文字的z坐标</param>

/// <param name="s">文字</param>

private void drawText(double x, double y, double z, String s) {

Txture t = getTexture(s);

// GL.Enable(EnableCap.DepthTest);//必须开启深度测试

//GL.Enable(EnableCap.AlphaTest);

// GL.AlphaFunc(AlphaFunction.Greater, 0.0f);

GL.BindTexture(TextureTarget.Texture2D, t.txtureid);//绑定材质

float width = (float)(t.bmp.Width * pixrate);

float height = (float)(t.bmp.Height * pixrate);

GL.Begin(BeginMode.Polygon);

GL.TexCoord2(0.0f, 0.0f);

GL.Vertex3(x, y, z);//左上

GL.TexCoord2(1.0f, 0.0f);

GL.Vertex3(x+width, y, z);//右上

GL.TexCoord2(1.0f, 1.0f);

GL.Vertex3(x+width,y-height, z);//右下

GL.TexCoord2(0.0f, 1.0f);

GL.Vertex3(x, y-height,z);//左下

GL.End();

// GL.DrawPixels(t.bmp.Width, t.bmp.Height, GlPixelFormat.Bgra, PixelType.UnsignedByte,t.pix);

}

/// <summary>

/// 获取文字材质

/// </summary>

/// <param name="s">文字</param>

/// <returns>材质对象</returns>

private Txture getTxture(String s) {

if (fts.ContainsKey(s)) return fts[s];

Txture t = new Txture(s,FontSize,TitleColor);

fts.Add(s, t);

return t;

}

/// <summary>

/// 创建文字材质,如果有,用现成的,没有就重新绘制

/// </summary>

/// <param name="s"></param>

/// <returns></returns>

private Txture getTexture(String s) {

if (fts.ContainsKey(s)) return fts[s];

Txture t = new Txture(s, FontSize, TitleColor);

t.txtureid = LoadTexture(t.bmp);

fts.Add(s, t);

return t;

}

/// <summary>

/// 把bmp加载到gl材质

/// </summary>

/// <param name="bmp"></param>

/// <returns></returns>

int LoadTexture(Bitmap bmp)

{

//new ShowPic().doShow(bmp);

int texture;

GL.Enable(EnableCap.Texture2D);

GL.GenTextures(1, out texture);

GL.BindTexture(TextureTarget.Texture2D, texture);

// GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Modulate);

BitmapData bitmapData1 = bmp.LockBits(

new Rectangle(0, 0, bmp.Width, bmp.Height),

ImageLockMode.ReadOnly,

SysPixelFormat.Format32bppArgb

);

GL.TexImage2D(

TextureTarget.Texture2D,

0,

PixelInternalFormat.Rgba,

bitmapData1.Width,

bitmapData1.Height,

0,

GlPixelFormat.Bgra,

PixelType.UnsignedByte,

bitmapData1.Scan0

);

bmp.UnlockBits(bitmapData1);

GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);

GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

// GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp);

// GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp);

return texture;

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。