Catmull-Rom在奇异点处的扭曲问题

引言

在计算机图形学和动画中,我们经常需要在已知点之间创建平滑的过渡。Catmull-Rom样条是一种流行的插值方法,它以简单直观的方式生成经过所有控制点的平滑曲线。本文将深入探讨Catmull-Rom插值的原理、实现和应用。

什么是Catmull-Rom样条?

Catmull-Rom样条是一种三次插值样条,由Edwin Catmull和Raphael Rom在1974年提出。它具有以下特点:

  • 曲线经过所有控制点(插值性)
  • 只需要四个点即可定义一段曲线
  • C¹连续(一阶导数连续)
  • 局部控制性:移动一个点只影响相邻曲线段

数学原理

基本公式

给定四个控制点P₀, P₁, P₂, P₃,在P₁和P₂之间的曲线段由以下参数方程定义:

P ( t ) = [ 1 t t 2 t 3 ] [ 0 1 0 0 − τ 0 τ 0 2 τ τ − 3 3 − 2 τ − τ − τ 2 − τ τ − 2 τ ] [ P 0 P 1 P 2 P 3 ] \mathbf{P}(t) = \begin{bmatrix} 1 & t & t^2 & t^3 \end{bmatrix} \begin{bmatrix} 0 & 1 & 0 & 0 \\ -\tau & 0 & \tau & 0 \\ 2\tau & \tau-3 & 3-2\tau & -\tau \\ -\tau & 2-\tau & \tau-2 & \tau \end{bmatrix} \begin{bmatrix} \mathbf{P}_0 \\ \mathbf{P}_1 \\ \mathbf{P}_2 \\ \mathbf{P}_3 \end{bmatrix} P(t)=[1tt2t3] 0τ2ττ10τ32τ0τ32ττ200ττ P0P1P2P3

其中:

  • t ∈ [0,1] 是插值参数
  • τ (tau) 是张力参数,通常取0.5(默认值)

简化形式

展开后可以得到更直观的表达式:

P ( t ) = 1 2 [ − t 3 + 2 t 2 − t 3 t 3 − 5 t 2 + 2 − 3 t 3 + 4 t 2 + t t 3 − t 2 ] T [ P 0 P 1 P 2 P 3 ] \mathbf{P}(t) = \frac{1}{2} \left[ \begin{matrix} -t^3 + 2t^2 - t \\ 3t^3 - 5t^2 + 2 \\ -3t^3 + 4t^2 + t \\ t^3 - t^2 \end{matrix} \right]^T \begin{bmatrix} \mathbf{P}_0 \\ \mathbf{P}_1 \\ \mathbf{P}_2 \\ \mathbf{P}_3 \end{bmatrix} P(t)=21 t3+2t2t3t35t2+23t3+4t2+tt3t2 T P0P1P2P3

C#代码实现

public static Vector2 CatmullRomInterpolate(Vector2 p0,Vector2 p1,Vector2 p2,Vector2 p3,double t)
{double t2 = t * t;double t3 = t2 * t;double x = 0.5 * ((-p0.X + 3 * p1.X - 3 * p2.X + p3.X) * t3 +(2 * p0.X - 5 * p1.X + 4 * p2.X - p3.X) * t2 +(-p0.X + p2.X) * t +(2 * p1.X));double y = 0.5 * ((-p0.Y + 3 * p1.Y - 3 * p2.Y + p3.Y) * t3 +(2 * p0.Y - 5 * p1.Y + 4 * p2.Y - p3.Y) * t2 +(-p0.Y + p2.Y) * t +(2 * p1.Y));return new Vector2((float)x, (float)y);
}public static List<Vector2> CatmullRomSmooth(List<Vector2> controlPoints,int segmentPerInterval = 10)
{List<Vector2> result = new List<Vector2>();if (controlPoints.Count < 4){return result;}Vector2 virtualFirst = new Vector2(2 * controlPoints[0].X - controlPoints[1].X,2 * controlPoints[0].Y - controlPoints[1].Y);Vector2 virtualLast = new Vector2(2 * controlPoints[controlPoints.Count - 1].X - controlPoints[controlPoints.Count - 2].X,2 * controlPoints[controlPoints.Count - 1].Y - controlPoints[controlPoints.Count - 2].Y);List<Vector2> extendedPoints = new List<Vector2>{virtualFirst,controlPoints[0]};extendedPoints.AddRange(controlPoints);extendedPoints.Add(virtualLast);for (int i = 0; i < extendedPoints.Count - 3; i++){Vector2 p0 = extendedPoints[i];Vector2 p1 = extendedPoints[i + 1];Vector2 p2 = extendedPoints[i + 2];Vector2 p3 = extendedPoints[i + 3];for (int j = 0; j <= segmentPerInterval; j++){double t = (double)j / segmentPerInterval;Vector2 interpolatedPoint = CatmullRomInterpolate(p0, p1, p2, p3, t);result.Add(interpolatedPoint);}}return result;
}

以一个DXF图像作为示例:
未经过Catmull-Rom平滑处理的图像
j经过CatmullRom平滑处理后的图像
可以看出黄色部分做完处理平滑了很多,但是作为代价在多段线导数变化剧烈的地方出现了扭曲的现象,这是因为Catmull-Rom 样条作为三次插值样条,在控制点处保证 C1 连续性(位置和切线连续),但在尖锐拐角处:

  • 算法会平滑地连接前后线段
  • 切线方向在拐点处突然变化
  • 导致曲线在拐点附近产生"过冲"现象

下一篇博客会着重介绍如何消除这种现象

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SX8652IWLTRT Semtech升特超低功耗触控芯片 12通道+I²C接口 重新定义人机交互!

SX8652IWLTRT&#xff08;Semtech&#xff09;产品解析与推广文案一、产品定位SX8652IWLTRT是Semtech&#xff08;升特半导体&#xff09;推出的低功耗电容式触摸控制器&#xff0c;采用IC接口&#xff0c;专为便携式设备和小家电的触摸交互设计&#xff0c;支持多点触控和手势…

第02章 MySQL环境搭建

1.MySQL的卸载 步骤1&#xff1a;停止MySQL服务 在卸载之前&#xff0c;先停止MySQL8.0的服务。按键盘上的“Ctrl Alt Delete”组合键&#xff0c;打开“任务管理器”对话框&#xff0c;可以在“服务”列表找到“MySQL8.0”的服务&#xff0c;如果现在“正在运行”状态&#…

实战Linux进程状态观察:R、S、D、T、Z状态详解与实验模拟

前言 在Linux系统中&#xff0c;进程状态是系统管理和性能调优的核心知识。一个进程从诞生到终止&#xff0c;会经历运行&#xff08;R&#xff09;、可中断睡眠&#xff08;S&#xff09;、不可中断睡眠&#xff08;D&#xff09;、停止&#xff08;T&#xff09;、僵尸&#…

数据库与关系数据库的区别是什么

数据库&#xff0c;简单来说&#xff0c;就是一个存储数据的地方&#xff0c;就像一个超级大仓库&#xff0c;能把各种各样的数据都收纳进来。它可以是一个简单的文本文件&#xff0c;用来记录一些基本信息&#xff1b;也可以是一个复杂的系统&#xff0c;存储着企业的大量业务…

如何解决微信小程序出现两个下拉刷新样式?

在微信小程序中&#xff0c;如果出现两个下拉刷新的情况&#xff0c;可能是因为在多个地方启用了下拉刷新功能&#xff0c;或者在同一个页面中多次调用了下拉刷新的API。以下是一些可能的原因和解决方法&#xff1a; 多次调用下拉刷新API&#xff1a; 确保在页面的生命周期中只…

(3)手摸手-学习 Vue3 之 变量声明【ref 和 reactive】区别

手摸手-学习 Vue3 之 变量声明【ref 和 reactive】区别前言ref 扩展ref 和 reactive 区别前言 ref 扩展 在之前博文《&#xff08;2&#xff09;手摸手-学习 Vue3 之 变量声明【ref 和 reactive】》中有提到&#xff1a; 当时已基本类型 进行演练说明&#xff0c;此时以 对象…

机器视觉运动控制一体机在SCARA机器人柔振盘上下料的应用

市场应用背景 SCARA机器人是一种高效、高精度的圆柱坐标系工业机器人&#xff0c;专精于装配任务。其独特的机械结构赋予其在特定方向&#xff08;通常是XY平面&#xff09;高度顺应性&#xff0c;同时在垂直方向保持优异刚性。 SCARA机器人本体通常包含三个轴线平行的旋转关…

3D 演示动画在汽车培训与教育领域中的应用

在企业培训这一至关重要的领域中&#xff0c;3D 演示动画犹如一颗璀璨的明星&#xff0c;发挥着无可替代的关键作用&#xff0c;大显身手。以某知名汽车制造企业为例&#xff0c;当对新入职员工开展汽车装配培训工作时&#xff0c;企业精心利用先进的 3D 演示动画技术制作了极为…

华锐视点 VR 污水处理技术对激发学习兴趣的作用​

华锐视点的 VR 虚拟仿真平台&#xff0c;尤其是 VR 污水处理模块&#xff0c;不仅仅是让学生观察&#xff0c;还设置了丰富多样的互动操作环节&#xff0c;充分激发学生的学习兴趣和主动性。​在平台的 VR 污水处理模拟中&#xff0c;学生可以模拟操作各种污水处理设备。比如&a…

百度斩获大模型中标第一,股价上涨5%

7月7日&#xff08;周一&#xff09;&#xff0c;百度&#xff08;BIDU.US&#xff09;股价上涨 5%&#xff0c;收报 90.68美元。最新数据显示&#xff0c;2025上半年我国大模型相关项目呈现爆发式增长态势&#xff1a;中标项目累计达 1810个&#xff0c;金额突破 64亿元&#…

【计算机网络】4网络层②

概念是什么?以太网有线联网的标准LAN小范围网络(家里/公司)WAN大范围网络(跨城市)Internet全球公共互联网 🌍internet任意互联的网络 🔗子网将一个LAN通过路由器的硬件隔离分为多个LAN(广播域)VLAN将一个LAN通过交换机的软件方法分为多个VLAN(广播域)以太网和Wi-Fi建L…

微信小程序81~90

1. 配置分包加载以及打包、引用原则 小程序如果需要进行分包加载&#xff0c;需要在 app.json 中&#xff0c;通过 subPackages 或者 subpackages 定义分包结构 每个分包结构含三个常用字段&#xff1a; root&#xff1a;分包的根目录&#xff0c;该目录下的所有文件都会被打包…

深度学习——神经网络1

一、神经网络 1.神经网络定义&#xff1a;人工神经网络&#xff08;Artificial Neural Network&#xff0c;ANN&#xff09;也简称为神经网络&#xff08;NN&#xff09;&#xff0c;是一种模仿生物神经网络结构和功能的计算模型。人脑可以看作是一个生物神经网络&#xff0c;由…

ipmitool 使用简介(ipmitool sel list ipmitool sensor list)

常用IPMI命令扩展使用ipmitool查看传感器信息ipmitool是一个用于管理IPMI&#xff08;Intelligent Platform Management Interface&#xff09;设备的命令行工具&#xff0c;可用于监控服务器硬件状态&#xff0c;包括传感器数据。运行以下命令可以列出所有传感器信息&#xff…

小米YU7预售现象深度解析:智能电动汽车的下一个范式革命

小米YU7预售现象深度解析&#xff1a;智能电动汽车的下一个范式革命一、预售数据创造三项行业新纪录 2025年6月26日的小米YU7发布会&#xff0c;不仅刷新了智能汽车预售速度&#xff0c;更揭示了新时代的消费心理变迁&#xff1a; &#xff08;1&#xff09;订单爆发速度史无前…

xlog-Android15适配之16KB对齐

背景 前两天查看Google play控制台突然发现有告警&#xff0c;一看原来是要求必须尽快适配Android15。 过程 先看了一下网上的资料&#xff0c;Android15适配 发现对我的apk基本上没有什么影响&#xff0c;除了 动态库必须16KB对齐这一项。 最简单查看apk是否16KB对齐的方法…

Crazyflie支持MATLAB/Simulink控制 基于NOKOV度量动捕系统实现

Crazyflie支持MATLABSimulink控制 基于NOKOV度量动捕系统实现 一、动捕软件VRPN配置 以动捕软件版本XINGYING 4.2.0.5495为例&#xff0c;其他版本同理。打开动捕软件&#xff0c;连接上镜头。单击菜单栏下的视图->数据广播。在数据广播中的VRPN流下&#xff0c;将单位下拉…

Windows 系统安装与使用 Claude Code 全攻略

Claude Code 作为一款高效的 AI 编程辅助工具&#xff0c;深受开发者青睐&#xff0c;但由于其本身不支持 Windows 文件系统&#xff0c;在 Windows 系统上使用需要借助 WSL&#xff08;适用于 Linux 的 Windows 子系统&#xff09;。下面为你详细介绍在 Windows 系统上安装和使…

如何用Python编程计算权重?

1. 加权平均中的权重计算&#xff08;已知权重值&#xff09; 如果已知各元素的权重&#xff0c;直接用权重乘以对应值后求和。 # 示例&#xff1a;计算加权平均分&#xff08;权重之和为1&#xff09; scores [80, 90, 70] # 各项分数 weights [0.3, 0.5, 0.2] # 对应权重…

WinUI3入门16:Order自定义排序

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…