两条平滑曲线相乘_对三次贝塞尔曲线过点平滑中尖角和交叉现象的优化

目前在做等值线等值面相关的功能,用户可拖拽控制点修改等值线,再用等值线生成等值面。因为初始的等值线点数据太多,不利于用户操作,所以先使用道格拉斯-普克算法(Douglas–Peucker)进行等值线抽稀,再将抽稀后的控制点使用贝塞尔曲线算法进行平滑。

对于贝塞尔曲线算法的平滑过程,有人做了很详细的示意图,推荐大家看下贝塞尔曲线算法之JS获取点

可以了解到贝赛尔曲线算法平滑得到的曲线是经过起始点的,同时二阶算法需要三个点,三阶算法需要四个点,四阶算法需要五个点,以此类推。

一般的来说,三阶贝塞尔曲线就已经够用了,而且效果还不错,所以我选择了三次贝塞尔曲线平滑算法来进行控制点的平滑处理。

贝塞尔曲线平滑后的等值线是基本不经过控制点的,考虑到用户操作逻辑,以及点线关系(我的控制点是等值线抽稀得到的,所以等值线是经过控制点的),所以采用三次贝塞尔曲线过点平滑算法来进行控制点的平滑处理。

过点平滑的原理就是以相邻两个控制点为起始点,然后往起始点中间插入其他过程点(不是在起始点直线上选择点),这样平滑得到的曲线是经过起始点的,而曲线如何平滑是由插入的点来控制的,三次贝塞尔曲线需要四个点,那就需要在起始点中间插入两个点。

大致思路就是,先算出相邻原始点的中点,在把相邻中点连成的线段平移到对应的原始点,以平移后的中点作为控制点,相邻原始点为起始点画贝塞尔曲线,这样就保证了连接处的光滑。而贝塞尔曲线本身是光滑的,所以就把这些原始点用光滑曲线连起来了。具体代码及示意图如下:

15ae516f6ccf82f77e114bf4f1d5b165.png

代码:function createCurve(originPoint, option){

//控制点收缩系数 ,经调试0.6较好

let scale = option.tension || 0.6;

//平滑插值插入的最大点数

let maxpoints = option.pointsPerSeg

let originCount = originPoint.length

let curvePoint = []

let midpoints = []

//生成中点

for(let i = 0 ;i < originCount - 1 ; i++){

midpoints.push([

(originPoint[i][0] + originPoint[i + 1][0])/2.0,

(originPoint[i][1] + originPoint[i + 1][1])/2.0

])

}

//平移中点

let extrapoints = []

for(let i = 1 ;i < originCount - 1 ; i++){

let backi = i - 1;

let midinmid = [

(midpoints[i][0] + midpoints[backi][0])/2.0,

(midpoints[i][1] + midpoints[backi][1])/2.0

]

let offsetx = originPoint[i][0] - midinmid[0];

let offsety = originPoint[i][1] - midinmid[1];

let extraindex = 2 * i;

extrapoints[extraindex] = [

midpoints[backi][0] + offsetx,

midpoints[backi][1] + offsety

]

//朝 originPoint[i]方向收缩

let addx = (extrapoints[extraindex][0] - originPoint[i][0]) * scale;

let addy = (extrapoints[extraindex][1] - originPoint[i][1]) * scale;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值