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

使用Python实现图形学曲线和曲面的NURBS算法

目录

    • 使用Python实现图形学曲线和曲面的NURBS算法
      • 引言
      • NURBS曲线的数学原理
        • 1. NURBS曲线定义
        • 2. 权重的作用
      • NURBS曲线的Python实现
        • 1. 类结构设计
        • 2. 代码实现
        • 3. 代码详解
        • 使用示例
      • NURBS曲面的扩展
        • NURBS曲面类实现
      • 总结

使用Python实现图形学曲线和曲面的NURBS算法

引言

NURBS(Non-Uniform Rational B-Splines,非均匀有理B样条)是一种广泛应用于计算机图形学、CAD、动画设计和3D建模的数学表示方法。它是B样条(B-spline)的推广,能够表示直线、圆弧、椭圆以及更复杂的自由曲线和曲面。NURBS通过增加权重,赋予了控制点不同的影响力,从而能够精确表示圆形等几何形状。

本文将介绍NURBS曲线和曲面的基本原理,并使用Python面向对象的思想实现NURBS算法。

NURBS曲线的数学原理

1. NURBS曲线定义

NURBS曲线由控制点、权重和节点向量定义。给定 n + 1 n+1 n+1 个控制点 P 0 , P 1 , . . . , P n P_0, P_1, ..., P_n P0,P1,...,Pn,每个控制点对应一个权重 w 0 , w 1 , . . . , w n w_0, w_1, ..., w_n w0,w1,...,wn,NURBS曲线在参数 t t t 处的点 C ( t ) C(t) C(t) 的表达式为:

C ( t ) = ∑ i = 0 n N i , p ( t ) w i P i ∑ i = 0 n N i , p ( t ) w i C(t) = \frac{\sum_{i=0}^{n} N_{i,p}(t) w_i P_i}{\sum_{i=0}^{n} N_{i,p}(t) w_i} C(t)=i=0nNi,p(t)wii=0nNi,p(t)wiPi

其中:

  • N i , p ( t ) N_{i,p}(t) Ni,p(t) 是B样条基函数,和B样条曲线的定义一致。
  • w i w_i wi 是控制点的权重,控制点对曲线的影响力大小。
  • 节点向量 t t t 决定参数空间的分布。
2. 权重的作用

权重 w i w_i wi 决定了每个控制点对曲线的影响力。若所有权重相等,则NURBS曲线退化为普通的B样条曲线;而如果控制点的某些权重远大于其他权重,则这些控制点对曲线形状的影响力会更大。

NURBS曲线的Python实现

1. 类结构设计

我们将设计以下几个类:

  • Point2D:表示二维平面上的点。
  • NURBSCurve:用于计算和绘制NURBS曲线的类。
2. 代码实现
import numpy as np# 定义二维点类
class Point2D:def __init__(self, x, y):self.x = xself.y = ydef __repr__(self):return f"({self.x}, {self.y})"# 定义NURBS曲线类
class NURBSCurve:def __init__(self, control_points, weights, degree, knot_vector=None):"""初始化NURBS曲线:param control_points: 控制点的列表,每个控制点是一个 Point2D 对象:param weights: 控制点的权重列表:param degree: NURBS的阶数(degree):param knot_vector: 节点向量,若为None,则使用均匀节点向量"""self.control_points = control_pointsself.weights = weightsself.degree = degreeself.num_control_points = len(control_points)# 生成均匀节点向量if knot_vector is None:self.knot_vector = self._generate_uniform_knot_vector()else:self.knot_vector = knot_vectordef _generate_uniform_knot_vector(self):"""生成均匀的节点向量:return: 均匀节点向量"""n = self.num_control_points - 1p = self.degreereturn [0] * (p + 1) + list(range(1, n - p + 1)) + [n - p + 1] * (p + 1)def _basis_function(self, i, k, t):"""计算B样条基函数:param i: 控制点索引:param k: 当前阶数:param t: 参数值:return: 基函数值"""if k == 0:return 1.0 if self.knot_vector[i] <= t < self.knot_vector[i+1] else 0.0else:# 计算两个部分coef1 = 0.0if self.knot_vector[i+k] != self.knot_vector[i]:coef1 = (t - self.knot_vector[i]) / (self.knot_vector[i+k] - self.knot_vector[i]) * self._basis_function(i, k-1, t)coef2 = 0.0if self.knot_vector[i+k+1] != self.knot_vector[i+1]:coef2 = (self.knot_vector[i+k+1] - t) / (self.knot_vector[i+k+1] - self.knot_vector[i+1]) * self._basis_function(i+1, k-1, t)return coef1 + coef2def calculate_point(self, t):"""计算曲线在参数t处的点:param t: 参数值 t, 范围 [0, 1]:return: 返回曲线在 t 处的 Point2D 点"""numerator_x = 0.0numerator_y = 0.0denominator = 0.0for i in range(self.num_control_points):b = self._basis_function(i, self.degree, t)numerator_x += b * self.weights[i] * self.control_points[i].xnumerator_y += b * self.weights[i] * self.control_points[i].ydenominator += b * self.weights[i]return Point2D(numerator_x / denominator, numerator_y / denominator)def generate_curve_points(self, num_points=100):"""生成NURBS曲线上的点:param num_points: 生成的曲线上点的数量:return: 返回点列表,表示NURBS曲线"""curve_points = []for t in np.linspace(self.knot_vector[self.degree], self.knot_vector[-self.degree-1], num_points):curve_points.append(self.calculate_point(t))return curve_points# 使用示例
if __name__ == "__main__":# 定义控制点control_points = [Point2D(0, 0), Point2D(1, 2), Point2D(3, 3), Point2D(4, 0)]# 定义权重weights = [1, 0.5, 0.5, 1]# 创建NURBS曲线对象,阶数为3(三次NURBS)nurbs_curve = NURBSCurve(control_points, weights, degree=3)# 生成并输出曲线上的点curve_points = nurbs_curve.generate_curve_points()print("NURBS曲线上的点:")for point in curve_points:print(point)
3. 代码详解
  • Point2D 类:表示二维平面上的一个点,包含点的 x x x y y y 坐标。

  • NURBSCurve 类:该类用于计算NURBS曲线,主要包括以下方法:

    • __init__():初始化NURBS曲线,包括控制点、权重、阶数和节点向量。如果未提供节点向量,将自动生成一个均匀节点向量。
    • _generate_uniform_knot_vector():生成均匀节点向量。
    • _basis_function():递归计算B样条基函数。
    • calculate_point():计算曲线在参数 t t t 处的点,权重会影响控制点对曲线的贡献。
    • generate_curve_points():生成NURBS曲线上的多个点,用于近似表示曲线的形状。
使用示例

假设我们有4个控制点 ( 0 , 0 ) , ( 1 , 2 ) , ( 3 , 3 ) , ( 4 , 0 ) (0, 0), (1, 2), (3, 3), (4, 0) (0,0),(1,2),(3,3),(4,0),并为其中两个控制点设置较小的权重 0.5 0.5 0.5,这将影响曲线的形状。生成的曲线在权重较大的控制点附近会更接近这些点。

NURBS曲面的扩展

NURBS曲线可以扩展为NURBS曲面。NURBS曲面是由二维控制点网格、权重矩阵以及两个方向的节点向量控制的。

NURBS曲面类实现
# 定义NURBS曲面类
class NURBSSurface:def __init__(self, control_points_grid, weights_grid, degree_u, degree_v, knot_vector_u=None, knot_vector_v=None):"""初始化NURBS曲面:param control_points_grid: 控制点的二维网格,每个点是Point2D 对象:param weights_grid: 权重的二维网格:param degree_u: u方向的NURBS阶数:param degree_v: v方向的NURBS阶数:param knot_vector_u: u方向的节点向量:param knot_vector_v: v方向的节点向量"""self.control_points_grid = control_points_gridself.weights_grid = weights_gridself.degree_u = degree_uself.degree_v = degree_vself.num_control_points_u = len(control_points_grid)self.num_control_points_v = len(control_points_grid[0])# 生成均匀节点向量if knot_vector_u is None:self.knot_vector_u = self._generate_uniform_knot_vector(self.num_control_points_u, self.degree_u)else:self.knot_vector_u = knot_vector_uif knot_vector_v is None:self.knot_vector_v = self._generate_uniform_knot_vector(self.num_control_points_v, self.degree_v)else:self.knot_vector_v = knot_vector_vdef _generate_uniform_knot_vector(self, num_control_points, degree):"""生成均匀的节点向量:param num_control_points: 控制点数量:param degree: NURBS阶数:return: 均匀节点向量"""return [0] * (degree + 1) + list(range(1, num_control_points - degree)) + [num_control_points - degree] * (degree + 1)def calculate_point(self, u, v):"""计算NURBS曲面在参数 (u, v) 处的点:param u: u方向参数值:param v: v方向参数值:return: 返回曲面在 (u, v) 处的 Point2D 点"""numerator_x = 0.0numerator_y = 0.0denominator = 0.0for i in range(self.num_control_points_u):for j in range(self.num_control_points_v):b_u = NURBSCurve._basis_function(self, i, self.degree_u, u)b_v = NURBSCurve._basis_function(self, j, self.degree_v, v)numerator_x += b_u * b_v * self.weights_grid[i][j] * self.control_points_grid[i][j].xnumerator_y += b_u * b_v * self.weights_grid[i][j] * self.control_points_grid[i][j].ydenominator += b_u * b_v * self.weights_grid[i][j]return Point2D(numerator_x / denominator, numerator_y / denominator)def generate_surface_points(self, num_points_u=10, num_points_v=10):"""生成NURBS曲面上的点:param num_points_u: u方向点的数量:param num_points_v: v方向点的数量:return: 返回二维点列表,表示NURBS曲面"""surface_points = []for u in np.linspace(self.knot_vector_u[self.degree_u], self.knot_vector_u[-self.degree_u-1], num_points_u):row = []for v in np.linspace(self.knot_vector_v[self.degree_v], self.knot_vector_v[-self.degree_v-1], num_points_v):row.append(self.calculate_point(u, v))surface_points.append(row)return surface_points

总结

NURBS通过引入权重使得在精确描述几何图形(如圆和椭圆)时更加灵活。本文通过面向对象的思想,详细介绍了NURBS曲线和曲面的实现原理,并给出了Python的具体实现。

相关文章:

使用Python实现图形学曲线和曲面的NURBS算法

目录 使用Python实现图形学曲线和曲面的NURBS算法引言NURBS曲线的数学原理1. NURBS曲线定义2. 权重的作用 NURBS曲线的Python实现1. 类结构设计2. 代码实现3. 代码详解使用示例 NURBS曲面的扩展NURBS曲面类实现 总结 使用Python实现图形学曲线和曲面的NURBS算法 引言 NURBS&a…...

SpringBoot3

文章目录 一、为什么要学习SpringBoot二、SpringBoot介绍2.1 约定优于配置2.2 SpringBoot中的约定三、SpringBoot快速入门3.1 快速构建SpringBoot3.1.1 选择构建项目的类型3.1.2 项目的描述3.1.3 指定SpringBoot版本和需要的依赖3.1.4 导入依赖3.1.5 编写了Controller3.1.6 测试…...

【Text2SQL】领域优质论文分享

解读论文&#xff1a;Enhancing Few-shot Text-to-SQL Capabilities of Large Language Models: A Study on Prompt Design Strategies 1. 重要贡献 这篇论文的主要贡献在于提出了一种新的方法来增强大型语言模型&#xff08;LLMs&#xff09;在少量样本&#xff08;Few-shot…...

2024全国研究生数学建模竞赛(数学建模研赛)ABCDEF题深度建模+全解全析+完整文章

全国研究生数学建模竞赛&#xff08;数学建模研赛&#xff09;于9月21日8时正式开赛&#xff0c;赛程4天半&#xff0c;咱这边会在开赛后第一时间给出对今年的6道赛题的评价、分析和解答。包括ABCDEF题深度建模全解全析完整文章&#xff0c;详情可以点击底部的卡片来获取哦。 …...

Java项目中异常处理的最佳实践

1. 异常分类 首先&#xff0c;理解异常的不同类型是合理处理异常的基础。Java中的异常大致可以分为两大类&#xff1a; 受检异常&#xff08;Checked Exceptions&#xff09;&#xff1a;这些异常必须被捕获或声明抛出&#xff0c;例如IOException。非受检异常&#xff08;Un…...

CSS基本概念以及CSS的多种引入方式

CSS基本概念 CSS是层叠样式表&#xff0c;又叫级联样式表&#xff0c;简称样式表。CSS的文件后缀为.css&#xff0c;CSS用于HTML文档中元素样式的定义。 CSS的基本语法 CSS的规则由2个主要的部分构成&#xff1a;选择器以及一条或者多条声明。 选测器通常是你血药改变样式的…...

TiDB 简单集群部署拓扑文件

TiDB集群部署 服务器环境部署拓扑 都2024了还在为分库分表烦恼吗&#x1f618;&#xff0c;用分布式数据库TiDB、OceanBase、华为 GaussDB&#xff0c;你就使劲往里存数据。 早下班、少脱发、脱单&#xff01; &#x1f64f;&#x1f3fb;&#x1f64f;&#x1f3fb;&#x1f6…...

十三 系统架构设计(考点篇)

1 软件架构的概念 一个程序和计算系统软件体系结构是指系统的一个或者多个结构。结构中包括软件的构件&#xff0c;构件 的外部可见属性以及它们之间的相互关系。 体系结构并非可运行软件。确切地说&#xff0c;它是一种表达&#xff0c;使软件工程师能够&#xff1a; (1)分…...

Java-数据结构-二叉树-习题(三)  ̄へ ̄

文本目录&#xff1a; ❄️一、习题一(前序遍历非递归)&#xff1a; ▶ 思路&#xff1a; ▶ 代码&#xff1a; ❄️二、习题二(中序遍历非递归)&#xff1a; ▶ 思路&#xff1a; ▶ 代码&#xff1a; ❄️三、习题三(后序遍历非递归)&#xff1a; ▶ 思路&#xff1a; …...

SpringBoot+Aop+注解方式 实现多数据源动态切换

整体思路&#xff1a; 引入基本依赖SpringBootAopMySqlMyBatislombok在配置文件中配置多个数据源创建数据源配置类用于读取配置编写用于标识切换数据源的注解创建数据源切换工具类DataSourceContextHolder编写切面类用于在注解生效处切换数据源编写配置类&#xff0c;加载数据…...

企业如何高效应对多类型知识产权事务的复杂挑战?

随着企业的发展和创新活动的不断推进&#xff0c;越来越多的企业拥有了大量的专利、商标和软著等知识产权&#xff0c;这些不仅关乎企业的技术创新成果&#xff0c;更直接影响到企业的品牌价值和市场竞争力。然而&#xff0c;当企业拥有多件知识产权时&#xff0c;复杂的申请、…...

openeuler22.03 LTS 源码编译安装nginx1.22.1

openeuler22.03 LTS 源码编译安装nginx1.22.1 下载安装包 #官网下载nginx1.22.1 wget http://nginx.org/download/nginx-1.22.1.tar.gz安装依赖包 #安装依赖包&#xff0c;NGINX是C语言写的&#xff0c;pcre-devel支持正则表达式&#xff0c;openssl 开启加密 [rootproxy ~]…...

图片压缩工具免费怎么找?归纳了这几个压缩工具

有哪些图片压缩工具免费&#xff1f;在数字化时代&#xff0c;图像已成为我们生活中不可或缺的一部分。无论是网站设计、社交媒体分享还是文件传输&#xff0c;高质量的图片都扮演着重要的角色。但高质量往往意味着大文件体积&#xff0c;这可能会导致加载速度变慢或存储空间不…...

【Kubernetes知识点】解读HPA的 thrashing(抖动)问题

【Kubernetes知识点】解读HPA的 thrashing&#xff08;抖动&#xff09;问题 目录 1 概念 1.1 什么是 Thrashing 现象&#xff1f;1.2 HPA 中 Thrashing 产生的原因1.3 解决 Thrashing 的优化措施 1.3.1 设置合适的阈值1.3.2 使用自定义指标和基于负载的自动扩缩1.3.3 增加扩…...

Unity 设计模式 之 结构型模式 -【装饰者模式】【外观模式】【享元模式】【代理模式】

Unity 设计模式 之 结构型模式 -【装饰者模式】【外观模式】【享元模式】【代理模式】 目录 Unity 设计模式 之 结构型模式 -【装饰者模式】【外观模式】【享元模式】【代理模式】 一、简单介绍 二、装饰者模式&#xff08;Decorator Pattern&#xff09; 1、什么时候使用装…...

Linux上Qt安装相关的内容及在QtCreator使用QChart模块需要的配置

引言 下面是Ubuntu上Qt安装相关的内容及在QtCreator使用QChart模块需要的配置。 关于Qt安装及环境 Qt的模块 查看已经安装的模块 sudo apt search qt5-安装新的模块 sudo apt install qt5-svg # 安装Qt SVG模块3.查看qt已经安装了哪些模块 dpkg -l | grep libqt安装qt,…...

lettuce引起的Redis command timeout异常

项目使用Lettuce&#xff0c;在自己的环境下跑是没有问题的。在给客户做售前压测时&#xff0c;因为客户端环境比较恶劣&#xff0c;service服务和中间件服务不在同一机房。服务启动后不一会就会出现Redis command timeout异常。 经过差不多两周的追查&#xff0c;最后没办法把…...

【Hadoop】一、Hadoop入门:基础配置、集群配置、常用脚本

基础设置 网络设置 创建好一个 centos 虚拟机&#xff0c;修改网络配置文件&#xff1a; /etc/sysconfig/network-scripts/ifcfg-ens33修改 BOOTPROTO 为 static 以及添加 IPADDR、GATEWAY、DNS1 TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY&quo…...

Ollama:本地运行大模型【含UI界面】

文章目录 Ollama 简介安装 ollamaWindows 安装Docker 安装其它平台安装支持的模型模型清单模型参数与运行内存快速启动 llama 模型llama 模型介绍运行 llama3.1 模型通过 HTTP API 访问ollama 命令语法常用示例特别示例自定义模型创建 Modelfile创建模型并运行集成 Web 页面Ope…...

【论文阅读】Grounding Language with Visual Affordances over Unstructured Data

Abstract 最近的研究表明&#xff0c;大型语言模型&#xff08;llms&#xff09;可以应用于将自然语言应用于各种各样的机器人技能。然而&#xff0c;在实践中&#xff0c;学习多任务、语言条件机器人技能通常需要大规模的数据收集和频繁的人为干预来重置环境或帮助纠正当前的…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露&#xff0c;数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据&#xff0c;严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能&#xff0c;但SEMR…...