找回密码
 会员注册
查看: 18|回复: 0

纯Javascript实现平滑曲线生成

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
69864
发表于 2024-10-9 02:41:29 | 显示全部楼层 |阅读模式
纯Javascript实现平滑曲线生成前言平滑曲线生成是一个很实用的技术。很多时候,我们都需要通过绘制一些折线,然后让计算机平滑的连接起来,或者是生成一些平滑的面。先来看下最终效果(红色为我们输入的直线,蓝色为拟合过后的曲线) 首尾可以特殊处理让图形看起来更好)。实现思路是利用贝塞尔曲线进行拟合。?贝塞尔曲线简介贝塞尔曲线(英语:Bézier curve)是计算机图形学中相当重要的参数曲线。二次贝塞尔曲线?二次方贝塞尔曲线的路径由给定点P0、P1、P2的函数B(t)追踪:?三次贝塞尔曲线?对于三次曲线,可由线性贝塞尔曲线描述的中介点Q0、Q1、Q2,和由二次曲线描述的点R0、R1所建构:贝塞尔曲线计算函数根据上面的公式我们可以得到计算函数。二阶/** ? * ? * ? * @param {number} p0 ? * @param {number} p1 ? * @param {number} p2 ? * @param {number} t ? * @return {*} ? * @memberof Path ? */ ?bezier2P(p0: number, p1: number, p2: number, t: number) { ? ?const P0 = p0 * Math.pow(1 - t, 2); ? ?const P1 = p1 * 2 * t * (1 - t); ? ?const P2 = p2 * t * t; ? ?return P0 + P1 + P2; ?} ? ? ?/** ? * ? * ? * @param {Point} p0 ? * @param {Point} p1 ? * @param {Point} p2 ? * @param {number} num ? * @param {number} tick ? * @return {*} ?{Point} ? * @memberof Path ? */ ?getBezierNowPoint2P( ? ? ?p0: Point, ? ? ?p1: Point, ? ? ?p2: Point, ? ? ?num: number, ? ? ?tick: number, ?): Point { ? ?return { ? ? ?x: this.bezier2P(p0.x, p1.x, p2.x, num * tick), ? ? ?y: this.bezier2P(p0.y, p1.y, p2.y, num * tick), ? ?}; ?} ? ? ?/** ? * 生成二次方贝塞尔曲线顶点数据 ? * ? * @param {Point} p0 ? * @param {Point} p1 ? * @param {Point} p2 ? * @param {number} [num=100] ? * @param {number} [tick=1] ? * @return {*} ? * @memberof Path ? */ ?create2PBezier( ? ? ?p0: Point, ? ? ?p1: Point, ? ? ?p2: Point, ? ? ?num: number = 100, ? ? ?tick: number = 1, ?) { ? ?const t = tick / (num - 1); ? ?const points = []; ? ?for (let i = 0; i 1) { ? ? ?delta = vector2dMinus( ? ? ? ? ?p1, ? ? ? ? ?vector2dPlus(pt, vector2dMinus(p2, pt).scale(1 / v)), ? ? ?); ? ?} else { ? ? ?delta = vector2dMinus( ? ? ? ? ?vector2dPlus(pt, vector2dMinus(p1, pt).scale(v)), ? ? ? ? ?p2, ? ? ?); ? ?} ? ?delta = delta.scale(ratio); ? ?const control1: Point = { ? ? ?x: vector2dPlus(pt, delta).x, ? ? ?y: vector2dPlus(pt, delta).y, ? ?}; ? ?const control2: Point = { ? ? ?x: vector2dMinus(pt, delta).x, ? ? ?y: vector2dMinus(pt, delta).y, ? ?}; ? ?return {control1, control2}; ?} ? ? ?/** ? * 平滑曲线生成 ? * ? * @param {Point []} points ? * @param {number} ratio ? * @return {*} ? * @memberof Path ? */ ?createSmoothLine(points: Point[], ratio: number = 0.3) { ? ?const len = points.length; ? ?let resultPoints = []; ? ?const controlPoints = []; ? ?if (len { ? ? ? ?let app = document.getElementById('app'); ? ? ? ?let index = 0; ? ? ? ?let move = () => { ? ? ? ? ? ?if (index
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-7 07:33 , Processed in 0.451659 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表