C#,计算几何,鼠标点击绘制 (二维,三次)B样条曲线的代码

news2024/12/23 8:40:55

B样条(B-Spline)是常用的曲线拟合与插值算法之一。

这里给出在 Form 的 图像 Picturebox 组件上,按鼠标点击点绘制 (三次)B样条曲线的代码。

2022-12-05 修改了代码。

1 文本格式

using System;
using System.Data;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Legalsoft.Truffer.Algorithm;
{
    public partial class Form1 : Form
    {
        public double[] splinex = new double[1001];
        public double[] spliney = new double[1001];
        public point[] pt = new point[6];
        public int no_of_points = 0;

        /// <summary>
        /// Prints a dot at the place whrere the mouseup event occurs
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            Graphics g = pictureBox1.CreateGraphics();
            Color cl = Color.DarkBlue;
            g.DrawLine(new Pen(cl, 2), e.X-3, e.Y, e.X + 3, e.Y);
            g.DrawLine(new Pen(cl, 2), e.X, e.Y-3, e.X, e.Y + 3);
            g.DrawString(no_of_points+"", new Font("宋体",12), new SolidBrush(Color.Red), e.X, e.Y);

        }

        /// <summary>
        /// At each mousedown event the the no of points is calculated
        /// if the value is more than 3 then the curve is drawn
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
           if (no_of_points > 3)
            {
                pt[0] = pt[1];
                pt[1] = pt[2];
                pt[2] = pt[3];
                pt[3].X = e.X;
                pt[3].Y = e.Y;

                double temp = Math.Sqrt(Math.Pow(pt[2].X - pt[1].X, 2F) + Math.Pow(pt[2].Y - pt[1].Y, 2F));
                int interpol = System.Convert.ToInt32(temp);
                bspline(pt[0], pt[1], pt[2], pt[3], interpol);

                int width = 2;
                Graphics g = pictureBox1.CreateGraphics();
                Color cl = Color.Blue;
                int x, y;
                for (int i = 0; i <= interpol - 1; i++)
                {
                    x = System.Convert.ToInt32(splinex[i]);
                    y = System.Convert.ToInt32(spliney[i]);
                    g.DrawLine(new Pen(cl, width), x - 1, y, x + 1, y);
                    g.DrawLine(new Pen(cl, width), x, y - 1, x, y + 1);
                }
            }
            else
            {
                pt[no_of_points].X = e.X;
                pt[no_of_points].Y = e.Y;
            }
            no_of_points++;
        }

        /// <summary>
        /// calculating the values using the algorithm 
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <param name="p4"></param>
        /// <param name="divisions"></param>
        public void bspline(point p1, point p2, point p3, point p4, int divisions)
        {
            double[] a = new double[5];
            double[] b = new double[5];
            a[0] = (-p1.X + 3 * p2.X - 3 * p3.X + p4.X) / 6.0;
            a[1] = (3 * p1.X - 6 * p2.X + 3 * p3.X) / 6.0;
            a[2] = (-3 * p1.X + 3 * p3.X) / 6.0;
            a[3] = (p1.X + 4 * p2.X + p3.X) / 6.0;
            b[0] = (-p1.Y + 3 * p2.Y - 3 * p3.Y + p4.Y) / 6.0;
            b[1] = (3 * p1.Y - 6 * p2.Y + 3 * p3.Y) / 6.0;
            b[2] = (-3 * p1.Y + 3 * p3.Y) / 6.0;
            b[3] = (p1.Y + 4 * p2.Y + p3.Y) / 6.0;

            splinex[0] = a[3];
            spliney[0] = b[3];

            for (int i = 1; i <= divisions - 1; i++)
            {
                double t = System.Convert.ToSingle(i) / System.Convert.ToSingle(divisions);
                splinex[i] = (a[2] + t * (a[1] + t * a[0])) * t + a[3];
                spliney[i] = (b[2] + t * (b[1] + t * b[0])) * t + b[3];
            }
        }
    }
}
 

2 代码格式

using System;
using System.Data;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Legalsoft.Truffer.Algorithm;
{
    public partial class Form1 : Form
    {
        public double[] splinex = new double[1001];
        public double[] spliney = new double[1001];
        public point[] pt = new point[6];
        public int no_of_points = 0;

        /// <summary>
        /// Prints a dot at the place whrere the mouseup event occurs
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            Graphics g = pictureBox1.CreateGraphics();
            Color cl = Color.DarkBlue;
            g.DrawLine(new Pen(cl, 2), e.X-3, e.Y, e.X + 3, e.Y);
            g.DrawLine(new Pen(cl, 2), e.X, e.Y-3, e.X, e.Y + 3);
            g.DrawString(no_of_points+"", new Font("宋体",12), new SolidBrush(Color.Red), e.X, e.Y);

        }

        /// <summary>
        /// At each mousedown event the the no of points is calculated
        /// if the value is more than 3 then the curve is drawn
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
           if (no_of_points > 3)
            {
                pt[0] = pt[1];
                pt[1] = pt[2];
                pt[2] = pt[3];
                pt[3].X = e.X;
                pt[3].Y = e.Y;

                double temp = Math.Sqrt(Math.Pow(pt[2].X - pt[1].X, 2F) + Math.Pow(pt[2].Y - pt[1].Y, 2F));
                int interpol = System.Convert.ToInt32(temp);
                bspline(pt[0], pt[1], pt[2], pt[3], interpol);

                int width = 2;
                Graphics g = pictureBox1.CreateGraphics();
                Color cl = Color.Blue;
                int x, y;
                for (int i = 0; i <= interpol - 1; i++)
                {
                    x = System.Convert.ToInt32(splinex[i]);
                    y = System.Convert.ToInt32(spliney[i]);
                    g.DrawLine(new Pen(cl, width), x - 1, y, x + 1, y);
                    g.DrawLine(new Pen(cl, width), x, y - 1, x, y + 1);
                }
            }
            else
            {
                pt[no_of_points].X = e.X;
                pt[no_of_points].Y = e.Y;
            }
            no_of_points++;
        }

        /// <summary>
        /// calculating the values using the algorithm 
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <param name="p4"></param>
        /// <param name="divisions"></param>
        public void bspline(point p1, point p2, point p3, point p4, int divisions)
        {
            double[] a = new double[5];
            double[] b = new double[5];
            a[0] = (-p1.X + 3 * p2.X - 3 * p3.X + p4.X) / 6.0;
            a[1] = (3 * p1.X - 6 * p2.X + 3 * p3.X) / 6.0;
            a[2] = (-3 * p1.X + 3 * p3.X) / 6.0;
            a[3] = (p1.X + 4 * p2.X + p3.X) / 6.0;
            b[0] = (-p1.Y + 3 * p2.Y - 3 * p3.Y + p4.Y) / 6.0;
            b[1] = (3 * p1.Y - 6 * p2.Y + 3 * p3.Y) / 6.0;
            b[2] = (-3 * p1.Y + 3 * p3.Y) / 6.0;
            b[3] = (p1.Y + 4 * p2.Y + p3.Y) / 6.0;

            splinex[0] = a[3];
            spliney[0] = b[3];

            for (int i = 1; i <= divisions - 1; i++)
            {
                double t = System.Convert.ToSingle(i) / System.Convert.ToSingle(divisions);
                splinex[i] = (a[2] + t * (a[1] + t * a[0])) * t + a[3];
                spliney[i] = (b[2] + t * (b[1] + t * b[0])) * t + b[3];
            }
        }
    }
}

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

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

相关文章

Java Web(三)--CSS

介绍 为什么需要&#xff1a; 在没有 CSS 之前&#xff0c;想要修改 HTML 元素的样式需要为每个 HTML 元素单独定义样式属性&#xff0c;费心费力&#xff1b;CSS 可以让 html 元素(内容) 样式(CSS)分离&#xff0c;提高web 开发的工作效率(针对前端开发)&#xff0c;从而…

【Vue】父组件如何调用子组件的函数

【Vue】父组件如何调用子组件的函数 在Vue中&#xff0c;父组件可以通过多种方式调用子组件的函数。下面是几种常见的方法&#xff1a; 使用 ref 属性 这是调用子组件方法的最直接方式。首先&#xff0c;在父组件的模板中给子组件添加一个 ref 属性。然后&#xff0c;你可以通…

MongoDB之概述、命令

基础知识 是什么 概念 分布式文件存储数据库&#xff0c;提供高可用、可扩展、易部署的数据存储解决方案。 结构 BSON存储类型 类似JSON的一种二进制存储格式。相比于JSON&#xff0c;提供更丰富的类型支持。 优点是灵活&#xff0c;缺点是空间利用率不佳。 类型说明解释…

【极数系列】Flink环境搭建(02)

【极数系列】Flink环境搭建&#xff08;02&#xff09; 引言 1.linux 直接在linux上使用jdk11flink1.18.0版本部署 2.docker 使用容器部署比较方便&#xff0c;一键启动停止&#xff0c;方便参数调整 3.windows 搭建Flink 1.18.0版本需要使用Cygwin或wsl工具模拟unix环境…

数字图像处理(实践篇)二十六 使用cvlib进行人脸检测、性别检测和目标检测

目录 1 安装cvlib 2 涉及的函数 3 实践 4 其他 cvlib一个简单,高级,易于使用的开源Python计算机视觉库。 1 安装cvlib # 安装依赖pip install opencv-python tensorflow# 安装cvlibpip install cvlib</

macOS跨进程通信: TCP Socket 创建实例

macOS跨进程通信: TCP Socket 创建实例 一&#xff1a; 简介 Socket 是 网络传输的抽象概念。 一般我们常用的有Tcp Socket和 UDP Scoket&#xff0c; 和类Unix 系统&#xff08;包括Mac&#xff09;独有的 Unix Domain Socket&#xff08;UDS&#xff09;。 Tcp Socket 能够…

(2)(2.4) CRSF/ELRS Telemetry

文章目录 前言 1 ArduPilot 参数编辑器 前言 &#xff01;Note ELRS&#xff08;ExpressLRS&#xff09;遥控系统使用穿越火线协议&#xff0c;连接方式类似。不过&#xff0c;它不像穿越火线那样提供双向遥测。 TBS CRSF 接收机与 ArduPilot 的接口中包含遥测和遥控信息。…

【K8S 云原生】K8S之HPA自动扩缩容、命名空间资源限制、容器抓包

目录 一、HPA概述 1、概念 2、两个重要的组件&#xff1a; 3、HPA的规则&#xff1a; 4、pod的副本数扩容有两种方式&#xff1a; 4.1、手动扩缩容&#xff0c;修改副本数&#xff1a; 4.2、自动扩缩容HPA 二、实验部署&#xff1a; 1、部署HPA 2、实现自动扩缩容 三…

Studio One 6 mac 6.5.2 激活版 数字音乐编曲创作

PreSonus Studio One是PreSonus出品的一款功能强大的音乐创作软件。主要为用户提供音乐创作、录音、编辑、制作等功能。它可以让你创造音乐&#xff0c;无限的轨道&#xff0c;无限的MIDI和乐器轨道&#xff0c;虚拟乐器和效果通道&#xff0c;这些都是强大和完美的。 软件下载…

JVM工作原理与实战(二十五):堆的垃圾回收-垃圾回收算法

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、垃圾回收算法介绍 1.垃圾回收算法的历史和分类 2.垃圾回收算法的评价标准 二、垃圾回收算法详解 1.标记清除算法 2.复制算法 3.标记整理算法 4.分代垃圾回收算法 总结 前言…

打开json文件,读取里边的每一行数据,每一行数据是一个字典,使用matplotlib画图

这段代码的目的是读取 JSON 文件&#xff0c;提取关键信息&#xff0c;然后使用 Matplotlib 绘制四个子图&#xff0c;分别显示不同的指标随着 iter 变化的情况。这种图形化分析有助于直观地了解模型的性能。 画图结果如下&#xff1a; json文件格式如下&#xff1a;下面只粘贴…

Nacos源码下载与运行

早先在linux环境下搭建过nacos环境 即Centos安装部署nacos实战&#xff0c;本次是从官网上下载源码&#xff0c;本地运行看看&#xff0c;记录过程&#xff0c;方便备查。 第一步、Nacos源码下载 推荐到nacos官网下载 Github地址&#xff0c;本次选择最新版&#xff0c;1.4.7…

计算机毕业设计 基于SpringBoot的民宿租赁系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

解决vue 2.6通过花生壳ddsn(frp内网穿透)实时开发报错Invalid Host header和websocket

请先核对自己的vue版本&#xff0c;我的是2.6.14&#xff0c;其他版本未测试 起因 这两天在维护一个基于高德显示多个目标&#xff08;门店&#xff09;位置的项目&#xff0c;由于高德要求定位必须使用https服务&#xff0c;遂在本地无法获取到定位坐标信息&#xff0c;于是…

数藏潮玩开启元宇宙新空间(定制开发)

元宇宙给我们带来了很多的可能性&#xff0c;对于一个品牌或者是平台来说&#xff0c;越早抓住数藏也就越早抓住了元宇宙的早起红利&#xff0c;就能在未来式这个超空间里面占住商机。 而数藏潮玩的想象空间是巨大的&#xff0c;所以能创造的生态也是无限大。在通过对数藏平台…

一文读懂:D3.js的前世今生,以及与echarts的对比

D3.js&#xff08;Data-Driven Documents&#xff09;是一种用于创建动态、交互式数据可视化的JavaScript库。它通过使用HTML、CSS和SVG等Web标准&#xff0c;将数据与文档结合&#xff0c;使得数据可以以一种直观和易于理解的方式进行呈现。D3.js的重要性在于它赋予了开发者更…

SSM:Spring + Spring MVC + MyBatis 的整合

SSM 前言整合 前言 在完成 Spring 、Spring MVC 与 MyBatis 基础知识的学习后&#xff0c;下面简单介绍 SSM 框架的整合使用。 整合 SSM&#xff0c;是 Java 开发中常用的一个 Web 框架组合&#xff0c;用于构建基于 Spring 和 MyBatis 的 Web 应用&#xff08; Spring MVC …

桌面型物联网智能机器人设计(预告)

相关资料 桌面级群控机器人CoCube探索-2022--CSDN博客 视频&#xff1a; 能&#xff01;有&#xff01;多&#xff01;酷&#xff01;CoCube桌面级群控机器人 让我看看谁在SJTU里划水… 简要介绍 设计一个桌面型物联网智能机器人&#xff0c;以ESP32芯片为核心&#xff0c;配…

Spring Security 6 学习-1

什么是 Spring Security Spring Security文档 Spring Security中文文档 Spring Security 是 Spring 家族中的安全型开发框架&#xff0c;主要解决三大方面问题&#xff1a;认证&#xff08;你是谁&#xff09;、授权&#xff08;你能干什么&#xff09;、常见攻击保护&#xff…

vue项目中使用Element多个Form表单同时验证

一、项目需求 在项目中一个页面中需要实现多个Form表单&#xff0c;并在页面提交时需要对多个Form表单进行校验&#xff0c;多个表单都校验成功时才能提交。 二、实现效果 三、多个表单验证 注意项&#xff1a;多个form表单&#xff0c;每个表单上都设置单独的model和ref&am…