问题:如何将一个三阶贝塞尔曲线打断生成两个三阶贝塞尔曲线,生成的两条贝塞尔曲线与原来的贝塞尔曲线重合?
输入:一条贝塞尔曲线的四个控制点P1,C1,C2,P2,和一个打断点E(E在曲线上)
输出:两条贝塞尔曲线:
P1,F,I,E
E,J,H,P2
解决大致分为两步
第一步:求出E点对应的贝塞尔曲线的参数e
第二步:根据e计算出四个控制点F,I,J,H

依次多个点打断,红色线表示原始贝塞尔,蓝色线是打断的两个贝塞尔曲线,效果如下:蓝色线和红色线基本重合。

源码

原理解析:
如图的红色曲线就是原始贝塞尔曲线,加入打断点就是E点,因为E在曲线上,所以必存在一个时刻e。

根据贝塞尔曲线的特征我们可以得到以下结论

根据上式可以得到以下式子

E也可以通过I和J来定义

所以,如果知道断点E对应的时刻e,计算F,I,J,H相对比较简单。
下面介绍如何计算e
方法1 解方程

可以看到求解e就是解关于e的一元三次方程,数学相对简单,但是工程上实现较为复杂。
方法2 迭代
从0开始迭代t,设置一个步长d,计算Pi = P(ti) ti = ti+d,每次迭代时计算Pi和E的欧式距离,并记录距离最小时的时刻e = ti,就可以粗略计算出e。经测试,步长设置为0.01,效果良好。

下面给出QML代码示例:

import QtQuick 2.15
import QtQuick.Window 2.15Window {visible: truewidth: 1920height: 1080title: qsTr("Hello World")//测试点property var testP1: Qt.vector2d(1909, 12)property var testC1: Qt.vector2d(1910, 998)property var testC2: Qt.vector2d(31, 15.233737999999903)property var testP2: Qt.vector2d(11, 4)//三次贝塞尔曲线//a1 * (1 - t) * (1 - t) * (1 - t) + 3 * a2 * t * (1 - t) * (1 - t) + 3 * a3 * t * t * (1 - t) + a4 * t * t * t;/*t:时间变量 [0-1]p1:首端点p2:末端点c1:首端点控制点c2:末端点控制点返回值:t时刻贝塞尔曲线上的点控制点、端点和返回值的数据类型为:vector2d*/function  thirdOrderBeziercurve(t, p1, c1, c2, p2) {if(t<0 || t>1)return;var p = p1.times(Math.pow(1 - t,3))p = p.plus(c1.times(3 * t * Math.pow(1-t,2)))p = p.plus(c2.times(3 * (1-t) * Math.pow(t,2)))p = p.plus(p2.times(Math.pow(t,3)))return p//return}// 计算两个点指点的距离,点的数据类型可以是vector2d或者Qt.pointfunction distance(p1,p2){return Math.sqrt(Math.pow(p1.x-p2.x,2)+Math.pow(p1.y-p2.y,2))}//根据时间t获取打断后的两条贝塞尔曲线的控制点/*return  [c11,c21,c22,c31]*/function getControlPointByT(p1, c1, c2, p2,t){//辅助点gvar g = c1.times(1-t).plus(c2.times(t))var c11 = p1.times(1-t).plus(c1.times(t))var c21 = c11.times(1-t).plus(g.times(t))var c31 = c2.times(1-t).plus(p2.times(t))var c22 = g.times(1-t).plus(c31.times(t))return [c11,c21,c22,c31]}//判断点是否在贝塞尔曲线上,如果在(误差范围内),返回时间t和逼近点/*输入:p1,c1,c2,p2:是贝塞尔曲线的参数p:特定点坐标errorValue:误差值输出:1.如果p点在贝塞尔曲线上,返回打断后的两条贝塞尔曲线的控制点和纠正点[c11,c21,c22,c31,rightPoint]2.否则,返回[]*/function getControlPointByPoint(p1, c1, c2, p2, p, errorValue){var m = 1000000;var t = 0var pt = Qt.vector2d(-1,-1)for(var i = 0;i<=1;i=i+0.01){var pi = thirdOrderBeziercurve(i,p1, c1, c2, p2)var d = distance(pi,p)if(d< m){m =dt = ipt = pi}}if(m < errorValue){console.log(t)var ctrlsPoints = getControlPointByT(p1, c1, c2, p2,t)//ctrlsPoints.push(pt)return ctrlsPoints}return []}Canvas{id:cvsanchors.fill: parentproperty var c: testP1property var ctrs:[]onPaint:{var ctx = cvs.getContext('2d')ctx.reset()ctx.save()ctx.clearRect(0,0,width,height)ctx.beginPath()ctx.moveTo(testP1.x,testP1.y)ctx.lineWidth="4"ctx.strokeStyle="red"ctx.bezierCurveTo(testC1.x,testC1.y,testC2.x,testC2.y,testP2.x,testP2.y)ctx.stroke()//ctx.closepath()//ctx.save()ctx.beginPath()ctx.arc(c.x,c.y,10,0,360,true)ctx.stroke()if(ctrs.length != 0){ctx.lineWidth="1"ctx.strokeStyle="blue"ctx.beginPath()ctx.moveTo(testP1.x,testP1.y)ctx.bezierCurveTo(ctrs[0].x,ctrs[0].y,ctrs[1].x,ctrs[1].y,cvs.c.x,cvs.c.y)ctx.bezierCurveTo(ctrs[2].x,ctrs[2].y,ctrs[3].x,ctrs[3].y,testP2.x,testP2.y)ctx.stroke()}}}Timer{interval: 100;running: true;repeat: trueproperty var t: 0.0onTriggered: {cvs.c = thirdOrderBeziercurve(t,testP1,testC1,testC2,testP2)cvs.ctrs = getControlPointByPoint(testP1,testC1,testC2,testP2,cvs.c,100)cvs.requestPaint()t = t+0.01if(t >1)t = 0}}
}

贝塞尔曲线打断生成两个贝塞尔曲线相关推荐

  1. R语言deLong‘s test:通过统计学的角度来比较两个ROC曲线、检验两个ROC曲线的差异是否具有统计显著性

    R语言deLong's test:通过统计学的角度来比较两个ROC曲线.检验两个ROC曲线的差异是否具有统计显著性 目录

  2. python语言deLong‘s test:通过统计学的角度来比较两个ROC曲线、检验两个ROC曲线的差异是否具有统计显著性

    python语言deLong's test:通过统计学的角度来比较两个ROC曲线.检验两个ROC曲线的差异是否具有统计显著性 目录

  3. 计算机图形学曲线生成原理,计算机图形学_曲线及生成.ppt

    计算机图形学_曲线及生成 华中理工大学计算机学院 陆枫 99-7 1999年7月 7.2.1 曲线的表示要求 1)唯一性 2)几何不变性 3)易于定界 4)统一性 5)易于实现光滑连接 6)几何直观 ...

  4. 贝塞尔曲线 弯曲动画ios_用贝塞尔曲线弯曲

    贝塞尔曲线 弯曲动画ios by Nash Vail 由Nash Vail 用贝塞尔曲线弯曲 (Nerding Out With Bezier Curves) Since the past few d ...

  5. android贝塞尔曲线,一文解析 Android 贝塞尔曲线

    原标题:一文解析 Android 贝塞尔曲线 相信很多同学都知道"贝塞尔曲线"这个词,我们在很多地方都能经常看到.利用"贝塞尔曲线"可以做出很多好看的UI效果, ...

  6. java 贝塞尔曲线_贝塞尔曲线:原理、自定义贝塞尔曲线View、使用!!!

    一.原理 转自:http://www.2cto.com/kf/201401/275838.html Android动画学习Demo(3) 沿着贝塞尔曲线移动的Property Animation Pr ...

  7. css贝塞尔曲线 多个点_贝塞尔曲线实践

    贝塞尔曲线: 贝塞尔曲线本质上是由线段和节点组成的,形象的说节点是可拖动的支点,线段像可伸缩的皮筋.一个常规的曲线往往由4个控制点构成(p0,p1,p2,p3),曲线经过起点(p0)和终点(p1). ...

  8. 绘制二次贝塞尔曲线(二次贝兹曲线)等距线:让 IE 支持 canvas接口 isPointInPath

    一.背景: 在使用 canvas 做知识图谱的时,实体关系使用线宽为 1px 的线绘制, 用户必须点在线上, 才能正常拾取到点击的边. 边关系,有些是直线边,有些是二次贝塞尔曲线.产品提议,线不能加粗 ...

  9. 多项式曲线——搞清楚贝塞尔曲线、B样条曲线、Nurbs曲线的区别

    多项式曲线--搞清楚贝塞尔曲线.B样条曲线.nurbs曲线的区别 贝塞尔曲线 Bezier曲线定义 Bernstein基函数的性质 Bezier曲线的性质 B样条曲线 B样条曲线定义 B样条基函数的性 ...

最新文章

  1. python无向加权图_图:无向图(Graph)基本方法及Dijkstra算法的实现 [Python]
  2. [vue]data数据属性及ref获取dom
  3. Linux服务器的gou,开源跨平台移动项目Langou【简介】
  4. post大小限制_作为一个程序员,面试中常问的get和post的区别,你真的知道吗
  5. DELPHI PROTOBUF免费的开源支持库fundamentals5
  6. Docker学习总结(50)——Docker 微服务优雅关闭
  7. 设系统中有三种类型的资源(A,B,C)的五个进程(P1,P2,P3,P4,P5)。A资源的数量为17,B资源的数量为5,C资源的数量为20。在T0时刻系统状态如表所示。
  8. 如何用iMazing备份恢复贪婪洞窟
  9. vue使用echarts地图数据分析
  10. 「机箱」酷冷至尊 影音先锋 250
  11. 系统设计(二)如何写技术设计文档
  12. 给js对象定义属性的方法
  13. 在linux上运行爬虫任务报错:Overridden settings******
  14. This Week in Spring - July 15, 2013
  15. LTE中的RSRP、RSSI、RSRQ、SINR、MCS介绍
  16. idea开发SSM框架的高校大学学生社团管理网站bootstrap自适应响应式前端(javaweb-php-asp.netC#-j2ee)包含公告管理-社团活动管理-社团申请管理-社团审核-活动报名
  17. 8.排序——数据结构(严蔚敏C语言版)
  18. 激光测距仪行业报告-产能、产量、销量、销售额、价格及未来趋势
  19. PP实施经验分享(5)——SAP中MD04显示常用函数(读取SAP MRP运行数据)
  20. jQuery学习教程二十: jQuery 遍历 - 后代

热门文章

  1. 我的世界虚拟服务器架设,我的世界Minecraft服务器架设教程_服务器怎么建立
  2. mfc快捷键设置 | vc++6.0热键设置
  3. testdisk windows mac linux,TestDisk for Mac-TestDisk Mac版下载 V7.2-PC6苹果网
  4. AI+Science系列(二):国内首个基于AI框架的CFD工具组件!赛桨v1.0 Beta API介绍以及典型案例分享!
  5. LNMP架构的源码编译
  6. 外卖平台的设计与实现
  7. 搜索跳出率:了解并优化用户体验
  8. 无线网没有服务器,无线网络连接没有有效的ip配置怎么办?
  9. 在arm64平台kkfileview和LibreOffice的编译使用
  10. [projecteuler]Counting Sundays