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

C#自定义曲线便器功能实现(简化版)

目录

一、曲线编辑器实现功能

二、实现方法说明

三、关键代码说明

1、绘制背景板和曲线

2、绘制坐标系面板

3、绘制曲线

四、工程下载连接


一、曲线编辑器实现功能

添加或者删除控制点,通过移动控制点来修改曲线形状

二、实现方法说明

            1、坐标系系统:

            使用0-500的范围映射到屏幕坐标系

            自动绘制网格线(间隔50单位)

            坐标轴显示在左侧和底部

            2、控制点功能:

            左键点击空白区域添加新控制点

            拖动现有控制点调整位置

            自动按X坐标排序保持曲线有效性

            限制控制点移动范围(防止越界和重叠)

           3、 曲线绘制:

            使用GraphicsPath.AddCurve方法实现平滑曲线

            张力系数设为0.5(可调整)

            实时更新曲线显示
          4、坐标转换:

            MapXToScreen/MapYToScreen:将逻辑坐标转换为屏幕坐标

            MapScreenToLogical:将屏幕坐标转换为逻辑坐标

         5、交互优化:

            双缓冲技术消除闪烁

            抗锯齿处理

            控制点吸附范围判断
        二、使用说明:

        点击空白区域添加新控制点

        拖动红色控制点调整曲线形状

        控制点自动按X坐标排序

        曲线实时更新

        三、扩展建议:

        添加右键菜单删除控制点

        实现曲线预设功能

        添加数值输入框精确调整坐标

        增加坐标轴标签

        实现数据导出/导入功能

        添加撤销/重做功能
         * 

        该实现提供了基本的曲线编辑功能,可以作为图像处理工具的基础模块,后续可根据具体需求添加更多高级功能。

三、关键代码说明

1、绘制背景板和曲线

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            //base.OnPaint(e);
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;

            // 绘制坐标系背景
            DrawCoordinateSystem(g);

            // 绘制控制点
            foreach (var point in controlPoints)
            {
                DrawControlPoint(g, point);
            }

            // 绘制曲线
            if (controlPoints.Count >= 2)
            {
                DrawCurve(g);
            }
        }

2、绘制坐标系面板

private void DrawCoordinateSystem(Graphics g)
        {
            // 绘制坐标系背景
            g.FillRectangle(Brushes.White, coordinateArea);

            // 绘制坐标轴
            using (Pen axisPen = new Pen(Color.Black, 2))
            {
                // X轴
                g.DrawLine(axisPen,
                    coordinateArea.Left,
                    coordinateArea.Bottom,
                    coordinateArea.Right,
                    coordinateArea.Bottom);

                // Y轴
                g.DrawLine(axisPen,
                    coordinateArea.Left,
                    coordinateArea.Bottom,
                    coordinateArea.Left,
                    coordinateArea.Top);
            }

            // 绘制网格线
            using (Pen gridPen = new Pen(Color.LightGray, 1))
            {
                // X轴网格
                for (float x = 0; x <= 500; x += 50)
                {
                    float screenX = MapXToScreen(x);
                    g.DrawLine(gridPen, screenX, coordinateArea.Top, screenX, coordinateArea.Bottom);
                }

                // Y轴网格
                for (float y = 0; y <= 500; y += 50)
                {
                    float screenY = MapYToScreen(y);
                    g.DrawLine(gridPen, coordinateArea.Left, screenY, coordinateArea.Right, screenY);
                }
            }
        }

3、绘制曲线

        private void DrawCurve(Graphics g)
        {
            if (controlPoints.Count < 2) return;

            List<PointF> screenPoints = new List<PointF>();
            foreach (var point in controlPoints)
            {
                screenPoints.Add(new PointF(
                    MapXToScreen(point.X),
                    MapYToScreen(point.Y)));
            }

            // 使用GraphicsPath绘制平滑曲线
            using (GraphicsPath path = new GraphicsPath())
            using (Pen curvePen = new Pen(Color.Blue, 2))
            {
                path.AddCurve(screenPoints.ToArray(), 0.5f); // 张力系数
                g.DrawPath(curvePen, path);
            }
        }

4、鼠标按下添加控制点和移动控制点

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            //base.OnMouseDown(e);

            // 检查是否点击控制点
            for (int i = 0; i < controlPoints.Count; i++)
            {
                PointF logicalPoint = controlPoints[i];
                float screenX = MapXToScreen(logicalPoint.X);
                float screenY = MapYToScreen(logicalPoint.Y);

                if (Math.Abs(e.X - screenX) < pointRadius * 2 &&
                    Math.Abs(e.Y - screenY) < pointRadius * 2)
                {
                    selectedPointIndex = i;
                    return;
                }
            }

            // 添加新点(限制在坐标系区域内)
            if (coordinateArea.Contains(e.Location))
            {
                PointF newPoint = MapScreenToLogical(e.Location);
                controlPoints.Add(newPoint);
                controlPoints.Sort((a, b) => a.X.CompareTo(b.X)); // 按X坐标排序
                selectedPointIndex = controlPoints.IndexOf(newPoint);
                this.Invalidate();
            }

        }
        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            //base.OnMouseMove(e);

            if (selectedPointIndex >= 0 && e.Button == MouseButtons.Left)
            {
                // 限制移动范围在坐标系内
                float x = Math.Max(coordinateArea.Left, Math.Min(e.X, coordinateArea.Right));
                float y = Math.Max(coordinateArea.Top, Math.Min(e.Y, coordinateArea.Bottom));

                // 更新控制点位置
                PointF newPoint = MapScreenToLogical(new Point((int)x, (int)y));

                // 保持X坐标有序
                if (selectedPointIndex > 0 && newPoint.X < controlPoints[selectedPointIndex - 1].X)
                    newPoint.X = controlPoints[selectedPointIndex - 1].X;

                if (selectedPointIndex < controlPoints.Count - 1 && newPoint.X > controlPoints[selectedPointIndex + 1].X)
                    newPoint.X = controlPoints[selectedPointIndex + 1].X;

                controlPoints[selectedPointIndex] = newPoint;
                this.Invalidate();
            }
        }

四、工程下载连接

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

相关文章:

  • PTA团体程序设计天梯赛-练习集46-50题
  • qt程序打包成一个文件
  • Chapter 8 Charge Pump
  • Jmeter分布式集群压测
  • 什么是反射以及反射机制优缺点
  • UR5e机器人位姿
  • 手机录视频风噪太大?华为Pura X“AI降风噪“太硬核了
  • ISSN号是什么?连续出版物标识的应用与生成
  • 算法 | 优化算法比较
  • 面向医药仓储场景下的药品分拣控制策略方法 研究(大纲)
  • SEARCH-R1:大型语言模型的多轮搜索推理革命
  • 安当KADP应用加密组件:高性能Java数据加密和脱敏解决方案
  • 【深度学习新浪潮】AI ISP技术与手机厂商演进历史
  • prometheus 添加alertmanager添加dingtalk机器人告警
  • 魔方AI(mofangai.net)是一个一站式人工智能资源聚合平台,致力于为用户精选国内外优质的人工智能工具
  • 模板计算(Stencil Computation)简介
  • Flink实战教程从入门到精通(基础篇)(三)Flink集群部署
  • 软考-软件设计师-面向对象
  • CSS 中@media查询的工作原理,如何利用它实现不同设备的样式适配
  • HarmonyOS Failure[MSG_ERR_INSTALL_GRANT_REQUEST_PERMISSIONS_FAILED]报错权限自查
  • 民生访谈|今年上海还有哪些重要演出展览?场地配套如何更给力?
  • 优化网络营商环境,上海严厉打击涉企网络谣言、黑灰产等违法犯罪
  • 不主动上门检查,上海已制定14个细分领域“企业白名单”甄别规则
  • 观察|印巴交火开始升级,是否会升级为第四次印巴战争?
  • 印观察|印巴战火与莫迪政府三重冒险:南亚火药桶已至临界点
  • 央行行长:债券市场“科技板”准备工作基本就绪,目前近百家市场机构计划发行超三千亿科技创新债