Bezier曲线快速相交计算(含代码)
Bezier曲线快速相交计算
- 背景介绍
- 算法思路
- 解释和分析
- 示例
- 参考资料
背景介绍
很多时候,需要计算曲线段与曲线段是否有交点。常规的思路是直接联立方程求解。不过,直接求方程的解这种思路通常在计算上开销较大。
针对任意曲线,曲线的方程阶次可能较高,无论是求导还是求根都比较困难。当曲线无交点时,并不能快速判断并停止计算。因此,本文介绍一种快速计算贝塞尔(Bezier)曲线的方法。这个方法的中心思想是化曲为直,分段判断。通过快速排除条件,可以节省计算时间。
算法思路
具体针对两条曲线(2D平面)进行说明:
1)采用AABB模型(Aixe Align Bounding Box)构建每条曲线的包围盒,对构建好的包围盒进行干涉判断,若空间干涉,进行下一步,否者退出本次判断;
2)对干涉空间内的曲线进行二分,即分成2段,2条曲线则分成四段。针对两两进行检测,执行步骤 1) ;
3)退出条件:曲线线段小于某一阈值或到达其他检测精度。
以上就是全部的思路,针对具体工程问题可以针对优化,进行加速计算。
解释和分析
不相交的曲线,在形成包围盒进行相交测试中可能会由于包围盒的范围太大而出现干涉,因此需要进一步二分,减少空间大小以排除或者确定。相交的曲线在该段内形成的包围盒一定会干涉,因此只需要收缩包围盒大小(也即曲线段范围缩小),就能找到交点(当然是一个近似结果,但一般能满足工程需要)。
为什么要用AABB模型而不是OBB(Oriented Bounding Box)?
当然从实际角度考虑,曲线是有方向和走向的,使用OBB模型更符合实际。但是OBB的计算比较复杂,需要计算切线方向,涉及到求导等。另外OBB的干涉检测也比较复杂,需要用到分离轴SAT或者GJK算法进行判断,这无疑加大了计算量,每一步的OBB干涉判断耗时太大了。当然,不在乎实时性的可以采用该方法,进一步也可以采用基于OBB的紧包围盒(都不在乎计算量了,直接精确求解它不香嘛)。
AABB包围盒如何计算,如何判断干涉?
如果曲线的x,y从起点出发到终点,x及y的变化呈现递增or递减的情况,则可以简单处理。此时AABB可以由该曲线的两个点确定(起点和终点,其中一个是最大点,一个是最小点)。
左边这个包围盒就只需要起点(70,250)和终点(220,60)就能确定了。右边这个则需要计算单调性改变处的坐标,并与起点和终点比较,最终构成AABB。具体确定单调性的方法,可以采用计算曲线导数(贝塞尔曲线的一阶导数为低一阶贝塞尔曲线),根据它确定根。
AABB的干涉判断比较简单了,x,y最大最小值直接判断就行了,可以参考其他教程。
以下两张图是搜索过程展示(资源来自于链接)
示例
此代码片段来自于python-bezier包
>>> import bezier
>>> import numpy as np
>>> nodes1 = np.asfortranarray([
... [0.0, 0.5, 1.0],
... [0.0, 1.0, 0.0],
... ])
>>> curve1 = bezier.Curve(nodes1, degree=2)
>>> nodes2 = np.asfortranarray([
... [0.0, 0.25, 0.5, 0.75, 1.0],
... [0.0, 2.0 , -2.0, 2.0 , 0.0],
... ])
>>> curve2 = bezier.Curve.from_nodes(nodes2)
>>> intersections = curve1.intersect(curve2)
>>> intersections
array([[0.31101776, 0.68898224, 0. , 1. ],[0.31101776, 0.68898224, 0. , 1. ]])
>>> s_vals = np.asfortranarray(intersections[0, :])
>>> points = curve1.evaluate_multi(s_vals)
>>> points
array([[0.31101776, 0.68898224, 0. , 1. ],[0.42857143, 0.42857143, 0. , 0. ]])
下图四个交点的位置,t1=0.31101776, 0.68898224, 0. , 1,对应t2=0.42857143, 0.42857143, 0. , 0.
此方法的优点在于不需要计算导数及根,可以快速排除离得较远的曲线段。
参考资料
贝塞尔曲线的介绍:https://pomax.github.io/bezierinfo/
python代码:https://github.com/dhermes/bezier
欢迎留言交流,如果觉得有帮助,点个赞呗。
Bezier曲线快速相交计算(含代码)相关推荐
- Bezier曲线(附Python实现代码)
上一讲讲解了伯恩斯坦多项式,现在就开始对Bezier曲线进行研究.Bezier曲线采用伯恩斯坦多项式作为基函数. 首先,我们定义Bezier曲线的表达式: C(t)=∑k=0nPkBkn(t)(1)\ ...
- Bezier曲线 OpenCV
大致要求是这样,已知数个点,需要穿过这数个点的Bezier曲线的一组控制点.代码思路主要是参照[AGG贝塞尔插值](http://www.antigrain.com/research/bezier_i ...
- 【四足机器人--摆动相足端位置速度轨迹规划】(4.1)FootSwingTrajectory(bezier曲线计算脚的摆动轨迹)代码解析
系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录 前言 一.FootSwingTrajectory(bezier曲线)的内容 ...
- bezier曲线解析与代码(c++)
前言: 作为rhino重度用户,我对于nurbs建模早有耳闻,但对于何为nurbs却不得其解.最近借上<计算机辅助设计>课程的机会,对此作了一些深入的学习,于是在此记录一下一些课程笔记和课 ...
- Bezier曲线的公式推导及代码实现
本文仅简述Bezier曲线的公式推导,并给出了一种代码实现.在阅读本文之前,请确保你已经对Bezier曲线的背景知识有所了解.相关知识可以通过以下课程进行学习:MOOC-计算机图形学-中国农业大学-赵 ...
- 使用快速傅里叶变换计算大整数乘法-代码
在上一篇随笔"使用快速傅里叶变换计算大整数乘法"中,已经讲述了使用快速傅里叶变换计算大整数乘法的原理.在这一篇随笔中,我们就使用快速傅里叶变换来实现一个提供任意精度的算术运算的静态 ...
- 边缘检测的评价指标:PR曲线,OIS,ODS,AP的计算与代码实现
文章目录 一.Precision(精确率)与Recall(召回率) 二.PR曲线:精确率--召回率曲线 三. OIS.ODS.AP的计算 1. ODS 2. OIS 3. AP 四.代码实现 1. 注 ...
- Simpson积分方法计算NURBS曲线弧长,详细原理+代码实现
Simpson积分方法计算NURBS曲线弧长,详细原理+代码实现 Simpson 积分方法是一种数值积分方法,可以用于计算曲线的弧长.它的基本思想是将曲线分成若干小段,对每一小段采用 Simpson ...
- [CGAL] 3D快速相交和距离计算(AABB_tree)- 三角形碰撞检测
文章目录 AABB Tree简介 接口 构造 由Triangle构造 由Polyhedron构造 相交测试 构造出结果(Constructions) 距离计算 简单例子 三角形碰撞检测 更多CGAL文 ...
最新文章
- [Unity3D]总结使用Unity 3D优化游戏运行性能的经验
- cisco 系列时间修改
- 2.6 multimap
- html中图片响应式怎么写,如何使用 HTML5 的picture元素处理响应式图片
- java返回fail_Java集合中的fail-fast(快速失败)机制详解
- koa2 仿知乎笔记
- tensorflow tensorboard summary的工作特点
- Java网络编程之通过代码实现Socket通信
- matlab分析傅里叶级数
- Web安全扫描器Netsparker v3.5发布
- 过来领你的Bug之“缺陷分析“篇
- Rayman的绝顶之路——Leetcode每日一题打卡2
- 网站域名如何接入腾讯云CDN业务详细步骤!
- 自学-CAD零基础视频教程网站
- 量子加密通信与量子传感技术相关精简介绍
- 计算机相关知识小故事,转一个有意思的计算机小故事
- 微信小程序轮播图swiper详细代码介绍
- 配置iphone邮箱服务器,iPhone配置腾讯邮箱
- oracle 主要特点是,Oracle PL/sql 主要特点
- java单机麻将_cocos2dx 制作单机麻将(五)
热门文章
- 2021-11-18 WinFrom面试题 Winform中,怎么实现Form2中点击打开按钮,打开Form1,输入文本,再点击Form1中的“确定”按钮,把输入的值显示到Form2的文本框中?
- Photoshop文字之——制作木板雕刻字
- PairWork-电梯调度程序结对编程【附加题】
- android企业级商城源码、360°全景图VR源码、全民直播源码等
- 计算机应用技术探析,计算机技术应用的现状及分析
- 【Bzoj3668】起床困难综合症
- mysql索引工作原理btree_MySQL:索引工作原理
- 油腻老爷们,你是有多久没化过妆了?
- excel利用公式提取括号前、括号中的数据
- 利用免费Excel控件来制作Excel报表