当前位置: 首页 > news >正文

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

相关文章:

C#自定义曲线绘图面板

一、实现功能 1、显示面板绘制。 2、拖动面板&#xff0c;X轴、Y轴都可以拖动。 3、显示面板缩放&#xff0c;放大或者缩小。 4、鼠标在面板中对应的XY轴数值。 5、自动生成的数据数组&#xff0c;曲线显示。 6、鼠标是否在曲线上检测。 二、界面 拖动面板 鼠标在曲线上…...

Java后端面试题+下一篇答案+实况场景题

uu们大家好&#xff01;市面上面试题很多&#xff0c;这边汇总并更新一下java后端面试的题目&#xff0c;助大家早日斩下心仪的offer&#xff01;&#xff01;&#xff08;下次跟新场景题...等我多碰几次壁...哈哈哈哈哈&#xff09; 这边放题目&#xff0c;下一篇跟新所有另面…...

完美解决vant浮动气泡+弹出菜单

使用框架&#xff1a; vue3&#xff0c;vant4 项目需求&#xff1a; 需要有一个浮动气泡&#xff0c;点击弹出导航菜单 遇到的问题&#xff1a; 1. 使用van-floating-bubble包裹van-popover&#xff0c;但点击后只会重复显示不能隐藏 2. popover位置固定&#xff0c;不能根据…...

SpringSecurity -- 入门使用

文章目录 什么是 SpringSesurity &#xff1f;细节使用方法 什么是 SpringSesurity &#xff1f; 在我们的开发中&#xff0c;安全还是有些必要的 用 拦截器 和 过滤器 写代码还是比较麻烦。 SpringSecurity 是 SpringBoot 的底层安全默认选型。一般我们需要认证和授权&#xf…...

C语言习题~day33

1.以下程序运行时&#xff0c;若输入1abcedf2df输出结果是&#xff08;&#xff09; #include <stdio.h> int main() { char a 0, ch; while ((ch getchar()) ! \n) { if (a % 2 ! 0 && (ch > a && ch < z)) ch ch - a A; a; putchar(ch); }…...

作业报告┭┮﹏┭┮(Android反调试)

一&#xff1a;Android反调试 主要是用来防止IDA进行附加的&#xff0c;主要的方法思路就是&#xff0c;判断自身是否有父进程&#xff0c;判断是否端口被监听&#xff0c;然后通过调用so文件中的线程进行监视&#xff0c;这个线程开启一般JNI_OnLoad中进行开启的。但是这个是…...

在 Delphi BSD11中安装 DCU 格式的第三方组件库

在 Delphi BSD 11 中安装 DCU 格式的第三方组件库可以按照以下步骤进行&#xff1a; 打开 Delphi&#xff1a;启动 Delphi 开发环境。 选择安装组件&#xff1a; 在菜单栏中&#xff0c;选择 Component -> Install Component。 选择 DCU 文件&#xff1a; 在弹出的对话框中…...

综合题第二题(路由器的配置)

题目 如何计算子网掩码 第一类 我们可以观察到上图的IP地址后面有“/26”、“30”。我们都知道子网掩码是由多个连续“1”和多个连续“0”组成的&#xff0c;“、26”表示子网掩码的二进制表达中有26个1。 例如&#xff1a;156.95.9.128/26 1111 1111.1111 1111.1111 1111.1…...

人工智能概览

目录 什么是人工智能 人工智能的历史与发展 人工智能发展时间轴示意图&#xff1a; 人工智能的主要分支 机器学习与深度学习在AI中的地位 什么是人工智能 人工智能&#xff08;Artificial Intelligence, AI&#xff09;是指由人制造出来的具有一定智能的系统&#xff0c;能够理…...

[vulnhub] Prime 1

https://www.vulnhub.com/entry/prime-1,358/ 主机发现端口扫描 探测存活主机&#xff0c;137是靶机 nmap -sP 192.168.75.0/24 // Starting Nmap 7.93 ( https://nmap.org ) at 2024-09-22 16:25 CST Nmap scan report for 192.168.75.1 Host is up (…...

JavaSE——lombok、juint单元测试、断言

一、lombok的使用 默认jvm不解析第三方注解&#xff0c;需要手动开启 链式调用 二、juint单元测试 下载juint包 public class TestDemo {// 在每一个单元测试方法执行之前执行Beforepublic void before() {// 例如可以在before部分创建IO流System.out.println("befor…...

商标价值如何评估与增值?

商标是企业的标志&#xff0c;代表着企业的产品或服务质量、信誉和形象。一个具有高知名度和美誉度的商标&#xff0c;能够为企业带来巨大的商业价值。它不仅可以帮助企业在市场中脱颖而出&#xff0c;吸引消费者的关注和购买&#xff0c;还可以作为企业的重要资产进行融资、并…...

linux命令之firewall-cmd用法

firewall-cmd Linux上新用的防火墙软件&#xff0c;跟iptables差不多的工具 补充说明 firewall-cmd 是 firewalld的字符界面管理工具&#xff0c;firewalld是centos7的一大特性&#xff0c;最大的好处有两个&#xff1a;支持动态更新&#xff0c;不用重启服务&#xff1b;第…...

深入浅出CSS盒子模型

“批判他人总是想的太简单 剖析自己总是想的太困难” 文章目录 前言文章有误敬请斧正 不胜感恩&#xff01;什么是盒子模型&#xff1f;盒子模型的组成部分详解1. 内容区&#xff08;Content&#xff09;2. 内边距&#xff08;Padding&#xff09;3. 边框&#xff08;Border&am…...

字符编码发展史4 — Unicode与UTF-8

上一篇《字符编码发展史3 — GB2312/Big5/GBK/GB18030》我们讲解了ANSI编码中的GB2312/Big5/GBK/GB18030。本篇我们将继续讲解字符编码的第三个发展阶段中的Unicode与UTF-8。 2.3. 第三个阶段 国际化 前面提到的第二个阶段&#xff0c;各个国家和地区各自为政&#xff0c;纷纷…...

【flink】之如何消费kafka数据并读写入redis?

背景&#xff1a; 最近公司出现做了一个新需求&#xff0c;需求内容是加工一个营销时机&#xff0c;但是加工营销时机的同时需要把数据内容里的一个idmapping存入redis用于后续的读写。 准备&#xff1a; <!-- 依赖 --><dependency><groupId>org.apache.fl…...

搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(二)-索引

场景 首先介绍测试的场景&#xff0c;本系列schema定义 pdm文档索引&#xff0c;包括nested&#xff0c;作为文档扩展属性字段&#xff0c;_content字段是组件保留字段&#xff0c;支持文本内容&#xff0c;字段属性还有其他属性&#xff0c;如boost&#xff0c;getter&#x…...

离散化算法

离散化 在C中&#xff0c;离散化通常指的是将连续的数值或数据转化为离散的形式。这在数值分析、信号处理、图像处理和机器学习等领域都非常常见。以下是一些离散化的基本概念和方法&#xff1a; 1.区间划分&#xff1a; 将连续变量的值域分成多个区间&#xff0c;每个区间对…...

基于ollama的本地RAG实践

先放参考的原文链接大语言模型实战——搭建纯本地迷你版RAG_本地rag-CSDN博客 一、大模型选择 在我之前的文章中有讲到&#xff0c;我用的是ollama中的llama3.1 Ollama在Windows安装&#xff0c;使用&#xff0c;简单调用API_ollama如何对外提供api-CSDN博客 二、嵌入模型 …...

安卓开发板_MTK开发板_联发科开发评估套件Demo板接口介绍

开发板是一种功能丰富的电路平台&#xff0c;专为开发人员设计&#xff0c;集成了多种传感器、扩展接口和通信模块。这使得开发者能够高效进行原型设计和功能验证&#xff0c;极大地简化了软硬件开发的过程。 此次介绍的安卓开发板由MT8788核心板与底板构成&#xff0c;特别之处…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...