C#自定义曲线绘图面板

一、实现功能

1、显示面板绘制。

2、拖动面板,X轴、Y轴都可以拖动。

3、显示面板缩放,放大或者缩小。

4、鼠标在面板中对应的XY轴数值。

5、自动生成的数据数组,曲线显示。

6、鼠标是否在曲线上检测。

二、界面

拖动面板

鼠标在曲线上识别

三、部分功能代码实现

1、图形面板

        /// <summary>/// 生成坐标系图片面板/// </summary>/// <returns></returns>public Bitmap DrawImage(){ImageBoardInit();return bitMap;}
        /// <summary>/// 创建绘图面板-显示坐标系/// </summary>private void ImageBoardInit(){//1、绘制X、Y坐标轴if ((int)height != 0 && (int)width != 0)  //做这个判断是因为在最小化的情况下width=0。{bitMap = new Bitmap((int)width, (int)height);  //根据给定的高度和宽度创建一个位图图像}            graphics = Graphics.FromImage(bitMap);    //从指定的 objBitmap 对象创建 objGraphics 对象 (即在objBitmap对象中画图)//根据给定颜色(LightGray)填充图像的矩形区域 (背景)graphics.DrawRectangle(new Pen(boardColor, 1), 0, 0, width - 1, height - 1);    //画边框graphics.FillRectangle(new SolidBrush(backColor), 1, 1, width - 2, height - 2); //填充边框//画X轴,注意图像的原始X轴和Y轴计算是以左上角为原点,向右和向下计算的xAxisPoint1.X = xSpace + xSliceBegin;xAxisPoint1.Y = (height / 2) + ySliceBegin;    //xAxisPoint2.X = width;xAxisPoint2.Y = xAxisPoint1.Y;graphics.DrawLine(new Pen(new SolidBrush(axisColor), 2), xAxisPoint1, xAxisPoint2);//画Y轴yAxisPoint1.X = xSpace + xSliceBegin;yAxisPoint1.Y = height ;yAxisPoint2.X = xSpace + xSliceBegin;yAxisPoint2.Y = 0 ;graphics.DrawLine(new Pen(new SolidBrush(axisColor), 2), yAxisPoint1, yAxisPoint2);//2、面板标题//graphics.DrawString("曲线编辑器", new Font("宋体", fontSize), new SolidBrush(Color.Blue), new PointF(width / 2, ySpace / 2));//3、画X轴上刻度、刻度说明            xSlice = (width - xSpace ) / xSliceCount;ySlice = (height / 2) / (ySliceCount / 2);int tempCountX1 = (int)(- xSliceBegin / xSlice);int tempCountY1 = (int)Math.Abs((ySliceBegin / ySlice));tempCountX = tempCountX1 + xSliceCount;tempCountY = tempCountY1 + ySliceCount/2;//画网格虚线Pen penDashed = new Pen(new SolidBrush(Color.Black));penDashed.DashStyle = DashStyle.Dash;for (int i = 1; i < tempCountX + 1; i++){//X轴刻度虚线graphics.DrawLine(penDashed, new PointF(i * xSlice + xSpace + xSliceBegin, 0 ), new PointF(i * xSlice + xSpace + xSliceBegin, height));//X轴刻度值标识文字string xStr = (i * xSliceValue).ToString();int nStrLength = xStr.Length;graphics.DrawString(xStr, new Font("宋体", fontSize), new SolidBrush(Color.Black), new PointF(i * xSlice + xSpace - fontSize * nStrLength + xSliceBegin, height / 2 + fontSize + ySliceBegin));}//Y轴虚线、刻度文字-正半轴for (int i = 0; i < tempCountY + 1; i++){graphics.DrawLine(penDashed, new PointF(xSpace + xSliceBegin, height / 2 - i * ySlice + ySliceBegin), new PointF(width, height / 2 - i * ySlice + ySliceBegin));//Y轴刻度值标识文字string yStr = (i * ySliceValue).ToString();int nStrLength = yStr.Length;if(i>0)graphics.DrawString(yStr, new Font("宋体", fontSize), new SolidBrush(Color.Black), new PointF(xSpace - fontSize * nStrLength + xSliceBegin, height / 2 - i * ySlice + ySliceBegin));}//Y轴虚线、刻度文字-负半轴for (int i = 1; i < tempCountY  + 1; i++){graphics.DrawLine(penDashed, new PointF(xSpace + xSliceBegin, height / 2 + i * ySlice + ySliceBegin), new PointF(width, height / 2 + i * ySlice + ySliceBegin));//Y轴刻度值标识文字string yStr = (-i * ySliceValue).ToString();int nStrLength = yStr.Length;graphics.DrawString(yStr, new Font("宋体", fontSize), new SolidBrush(Color.Black), new PointF(xSpace - fontSize * nStrLength + xSliceBegin, height / 2 + i * ySlice + ySliceBegin));}//4、原点刻度说明graphics.DrawString("0", new Font("宋体", fontSize + 2), new SolidBrush(Color.Black), new PointF(xSpace - fontSize * 2 + xSliceBegin, height / 2 + ySliceBegin));}

2、数据点曲线显示

        /// <summary>/// 绘制XY轴曲线/// </summary>/// <param name="xDatas">X轴数据</param>/// <param name="yDatas">Y轴数据</param>/// <param name="splineColor">曲线颜色</param>/// <param name="tension">曲线系数:0.0f-1.0f,默认0.5f,0.0f是直线</param>/// <param name="isPointFill">是否标出点</param>public void DrawXY(float[] xDatas,float[] yDatas,Color splineColor,float tension,bool isPointFill){int xLength = xDatas.Length;int yLength = yDatas.Length;if(xLength!=yLength){graphics.DrawString("X和Y数据长度不相等",new Font("宋体", fontSize + 5), new SolidBrush(Color.Blue), new Point((int)xSpace, (int)(height / 2)));return;}PointF[] splinePoints = new PointF[xDatas.Length];float xSlicePos = 0, ySlicePos = 0; //转换后的点在Image面板上像素点位置Brush brushPoint = new SolidBrush(splineColor);        //数据点画刷for(int i=0;i<xDatas.Length;i++){xSlicePos = xSliceBegin + xSpace + xDatas[i] * xSlice / xSliceValue;ySlicePos = ySliceBegin + height / 2 - yDatas[i] * ySlice / ySliceValue;splinePoints[i] = new PointF(xSlicePos, ySlicePos);if (isPointFill){//graphics.FillEllipse(brushPoint, xSlicePos - 4, ySlicePos - 4, 8, 8); //原点graphics.FillRectangle(brushPoint, xSlicePos - 4, ySlicePos - 4, 8, 8); //矩形}                }graphics.DrawCurve(new Pen(splineColor, 2.0f), splinePoints, tension);//graphics.Dispose();}

3、鼠标当前所在面板位置对应的坐标系统XY值

        int ex = 0, ey = 0;int mouseToValueX = 0;float mouseToValueY = 0;   //鼠标位置当前值float fMouseToValueX = 0;private void pictureBox1_MouseMove(object sender, MouseEventArgs e){ex = e.X;ey = e.Y;//1、显示鼠标在坐标系内X、Y对应的值fMouseToValueX =cureDraw.MousePosToValue_X(ex);mouseToValueX = (int)Math.Round(cureDraw.MousePosToValue_X(ex));//mouseToValueY = (float)Math.Round(cureDraw.MousePosToValue_Y(ey));mouseToValueY = cureDraw.MousePosToValue_Y(ey);if (mouseToValueX<0){mouseToValueX = 0;}if (mouseToValueX >= 0 && ex < pictureBox1.Width - 60){                labMousePos.Text = "X:" + mouseToValueX.ToString() + ";" + "Y:" + mouseToValueY.ToString();labMousePos.Location = new Point(ex + 50, ey + 40);}if (mouseToValueX >= 0 && ex > pictureBox1.Width - 60){                labMousePos.Text = "X:" + mouseToValueX.ToString() + ";" + "Y:" + mouseToValueY.ToString();labMousePos.Location = new Point(ex - 50, ey + 40);}}

4、鼠标是否在曲线上检测

        bool isMouseOn = false;private void timer1_Tick(object sender, EventArgs e){//bool isMouseOn = cureDraw.IsMouseOnPointCheck(xDatas, yDatas, ex, ey);//bool isMouseOn = cureDraw.IsMouseOnPointCheck(xDatasExpand, yDatasExpand, ex, ey);float tempX = 0, tempY = 0;int n = 0;bool b1 = false, b2 = false;foreach (var xData in xDatasExpand){if(Math.Abs(xData-fMouseToValueX)<0.02){tempX = xData;}}for (int i = 0; i < xDatasExpand.Length;i++ ){if(xDatasExpand[i]==tempX){n = i;}}if (Math.Abs(yDatasExpand[n] - mouseToValueY)<2.5){isMouseOn = true;}else{isMouseOn = false;}txtValue1.Text = xDatasExpand[n].ToString();    //YtxtValue2.Text = fMouseToValueX.ToString();txtValue3.Text = yDatasExpand[n].ToString();    //XtxtValue4.Text = mouseToValueY.ToString();txtValue5.Text = n.ToString();if (isMouseOn){labMousePos.ForeColor = Color.Red;                }else{labMousePos.ForeColor = Color.Black;}}

四、、工程下载链接

https://download.csdn.net/download/panjinliang066333/89775386

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/145433.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Linux —— 多线程

一、本篇重点 1.了解线程概念&#xff0c;理解线程与进程区别与联系 2.理解和学会线程控制相关的接口和操作 3.了解线程分离与线程安全的概念 4.学会线程同步。 5.学会互斥量&#xff0c;条件变量&#xff0c;posix信号量&#xff0c;以及读写锁 6.理解基于读写锁的读者写…

《JKTECH柔性振动盘:原理与多行业应用》东莞市江坤自动化科技有限公司

一、柔性振动盘的原理 柔性振动盘是一种新型的自动化上料设备&#xff0c;它采用先进的音圈电机技术和柔性振动技术&#xff0c;实现了对各种不规则形状、微小尺寸、易损伤零部件的高效上料和分拣。 其工作原理主要包括以下几个方面&#xff1a; 1. 音圈电机驱动 柔性振动盘内部…

分布式系统的概念与设计模式

概念 定义&#xff1a;分布式系统是指将数据和计算任务分散到多个独立的计算机上&#xff0c;这些计算机通过网络进行通信和协作&#xff0c;共同对外提供服务。分布式系统不仅提高了系统的可靠性和可扩展性&#xff0c;还增强了系统的并发处理能力和数据管理能力。 特点&…

运维开发之堡垒机(Fortress Machine for Operation and Development)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

mysql通过binlog做数据恢复

1 介绍 binlog&#xff08;二进制日志&#xff09;在 MySQL 中具有非常重要的作用。它记录了数据库的所有更改操作&#xff0c;主要用于数据恢复、复制和审计等方面。以下是 binlog 的主要作用&#xff1a; 1.数据恢复 binlog 可以用于恢复数据库中的数据。当数据库发生故障时…

分布式框架 - ZooKeeper

一、什么是微服务架构 1、单体架构 顾名思义一个软件系统只部署在一台服务器上。 ​ 在高并发场景中&#xff0c;比如电商项目&#xff0c;单台服务器往往难以支撑短时间内的大量请求&#xff0c;聪明的架构师想出了一个办法提高并发量&#xff1a;一台服务器不够就加一台&am…

微信小程序拨打电话点取消报错“errMsg“:“makePhoneCall:fail cancel“

问题&#xff1a;微信小程序中拨打电话点取消&#xff0c;控制台报错"errMsg":"makePhoneCall:fail cancel" 解决方法&#xff1a;在后面加上catch就可以解决这个报错 wx.makePhoneCall({phoneNumber: 181********}).catch((e) > {console.log(e) //用…

数据安全治理

数据安全治理 1.数据安全治理2.终端数据安全加密类权限控制类终端DLP类桌面虚拟化安全桌面 3.网络数据安全4.存储数据安全5.应用数据安全6.其他话题数据脱敏水印与溯源 7.UEBA8.CASB 1.数据安全治理 数据安全治理最为重要的是进行数据安全策略和流程制订。在企业或行业内经常发…

前端实用工具(二):编程规范化解决方案

目录 本地代码规范化工具 代码检测工具ESLint 代码格式化工具Prettier 远程代码规范化工具 远程提交规范化工具commitizen 提交规范检验工具commitlint husky 什么是git hooks commitlint安装 husky安装 检测代码提交规范 ESLint husky 自动修复格式错误lint-staged…

使用 Puppeteer-Cluster 和代理进行高效网络抓取: 完全指南

文章目录 一、介绍&#xff1f;二、什么是 Puppeteer-Cluster&#xff1f;三、为什么代理在网络抓取中很重要&#xff1f;四、 为什么使用带代理的 Puppeteer-Cluster&#xff1f;五、分步指南&#xff1a; 带代理的 Puppeteer 群集5.1. 步骤 1&#xff1a;安装所需程序库5.2. …

基于 ROS 的Terraform托管服务轻松部署ChatGLM2-6B

介绍 ChatGLM2-6B是开源中英双语对话模型ChatGLM-6B的第二代版本&#xff0c;在保留了初代模型对话流畅、部署门槛较低等众多优秀特性的基础上&#xff0c;ChatGLM2-6B具有更强大的性能、更长的上下文、更高效的推理等特性。 资源编排服务&#xff08;Resource Orchestration…

C++入门 之 类和对象(下)

目录 一、初始化列表 二、隐式类型转换与explict 三、静态成员——static 四、友元 五、内部类 六、匿名对象 七.对象拷贝时的编译器优化 一、初始化列表 之前我们实现构造函数时&#xff0c;初始化成员变量主要使用函数体内赋值&#xff0c;构造函数初始化还有一种方式&…

闯关leetcode——66. Plus One

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/plus-one/description/ 内容 You are given a large integer represented as an integer array digits, where each digits[i] is the ith digit of the integer. The digits are ordered from mo…

pdf文件怎么直接翻译?使用这些工具让翻译变得简单

在全球化日益加深的职场环境中&#xff0c;处理外语PDF文件成为了许多职场人士面临的共同挑战。 面对这些“加密”的信息宝库&#xff0c;如何高效、准确地将英文pdf翻译成对应语言&#xff0c;成为了提升工作效率的关键。 以下是几款在PDF翻译领域表现出色的软件&#xff0c…

基于 UniApp 平台的学生闲置物品售卖小程序设计与实现

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

寄存器二分频电路

verilog代码 module div2_clk ( input clk, input rst,output clk_div);reg clk_div_r; assign clk_div clk_div_r;always(posedge clk) beginif(rst)beginclk_div_r < 1b0;endelsebeginclk_di…

pytorch实现RNN网络

目录 1.导包 2. 加载本地文本数据 3.构建循环神经网络层 4.初始化隐藏状态state 5.创建随机的数据&#xff0c;检测一下代码是否能正常运行 6. 构建一个完整的循环神经网络 7.模型训练 8.个人知识点理解 1.导包 import torch from torch import nn from torch.nn imp…

API安全推荐厂商瑞数信息入选IDC《中国数据安全技术发展路线图》

近日&#xff0c;全球领先的IT研究与咨询公司IDC发布报告《IDC TechScape&#xff1a;中国数据安全技术发展路线图&#xff0c;2024》。瑞数信息凭借其卓越的技术实力和广泛的行业应用&#xff0c;被IDC评选为“增量型”技术曲线API安全的推荐厂商。 IDC指出&#xff0c;数据安…

Liveweb视频汇聚平台支持GB28181转RTMP、HLS、RTSP、FLV格式播放方案

GB28181协议凭借其在安防流媒体行业独有的大统一地位&#xff0c;目前已经在各种安防项目上使用。雪亮工程、幼儿园监控、智慧工地、物流监控等等项目上目前都需要接入安防摄像头或平台进行直播、回放。而GB28181协议作为国家推荐标准&#xff0c;目前基本所有厂家的安防摄像头…

Netty源码解析-请求处理与多路复用

Netty基本介绍&#xff0c;参考 Netty与网络编程 摘要 Netty源码系列-NioEventLoop 1.1 Netty给Channel分配Nio Event Loop的规则 看下图&#xff0c;EventLoopGroup是线程组&#xff0c;每个EventLoop是一个线程&#xff0c;那么线程处理请求是怎么分配的呢&#xff1f;我…