精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

純Javascript實現平滑曲線生成

開發 前端
很多時候,我們都需要通過繪制一些折線,然后讓計算機平滑的連接起來,或者是生成一些平滑的面。

純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 < num; i++) {
const point = this.getBezierNowPoint2P(p0, p1, p2, i, t);
points.push({x: point.x, y: point.y});
}
return points;
}

三階

/**
? 三次方塞爾曲線公式
?
? @param {number} p0
? @param {number} p1
? @param {number} p2
? @param {number} p3
? @param {number} t
? @return {*}
? @memberof Path
*/
bezier3P(p0: number, p1: number, p2: number, p3: number, t: number) {
const P0 = p0 * Math.pow(1 - t, 3);
const P1 = 3 * p1 * t * Math.pow(1 - t, 2);
const P2 = 3 * p2 * Math.pow(t, 2) * (1 - t);
const P3 = p3 * Math.pow(t, 3);
return P0 + P1 + P2 + P3;
}
/**
? 獲取坐標
?
? @param {Point} p0
? @param {Point} p1
? @param {Point} p2
? @param {Point} p3
? @param {number} num
? @param {number} tick
? @return {*}
? @memberof Path
*/
getBezierNowPoint3P(
p0: Point,
p1: Point,
p2: Point,
p3: Point,
num: number,
tick: number,
) {
return {
x: this.bezier3P(p0.x, p1.x, p2.x, p3.x, num * tick),
y: this.bezier3P(p0.y, p1.y, p2.y, p3.y, num * tick),
};
}
/**
? 生成三次方貝塞爾曲線頂點數據
?
? @param {Point} p0 起始點 { x : number, y : number}
? @param {Point} p1 控制點1 { x : number, y : number}
? @param {Point} p2 控制點2 { x : number, y : number}
? @param {Point} p3 終止點 { x : number, y : number}
? @param {number} [num=100]
? @param {number} [tick=1]
? @return {Point []}
? @memberof Path
*/
create3PBezier(
p0: Point,
p1: Point,
p2: Point,
p3: Point,
num: number = 100,
tick: number = 1,
) {
const pointMum = num;
const _tick = tick;
const t = _tick / (pointMum - 1);
const points = [];
for (let i = 0; i < pointMum; i++) {
const point = this.getBezierNowPoint3P(p0, p1, p2, p3, i, t);
points.push({x: point.x, y: point.y});
}
return points;
}

擬合算法

問題在于如何得到控制點,我們以比較簡單的方法:

  • 取p1-pt-p2的角平分線,c1c2垂直于該條角平分線c2為p2的投影點。
  • 取短邊作為c1-pt c2-pt的長度。
  • 對該長度進行縮放,這個長度可以大概理解為曲線的彎曲程度。 

ab線段:這里簡單處理,只使用了二階的曲線生成。

PS:這里可以按照個人想法處理。

bc線段:使用abc計算出來的控制點c2和bcd計算出來的控制點c3以此類推。

/**
? 生成平滑曲線所需的控制點
?
? @param {Vector2D} p1
? @param {Vector2D} pt
? @param {Vector2D} p2
? @param {number} [ratio=0.3]
? @return {*}
? @memberof Path
*/
createSmoothLineControlPoint(
p1: Vector2D,
pt: Vector2D,
p2: Vector2D,
ratio: number = 0.3,
) {
const vec1T: Vector2D = vector2dMinus(p1, pt);
const vecT2: Vector2D = vector2dMinus(p1, pt);
const len1: number = vec1T.length;
const len2: number = vecT2.length;
const v: number = len1 / len2;
let delta;
if (v > 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 < 3) return;
for (let i = 0; i < len - 2; i++) {
const {control1, control2} = this.createSmoothLineControlPoint(
new Vector2D(points[i].x, points[i].y),
new Vector2D(points[i + 1].x, points[i + 1].y),
new Vector2D(points[i + 2].x, points[i + 2].y),
ratio,
);
controlPoints.push(control1);
controlPoints.push(control2);
let points1;
let points2;
// 首端控制點只用一個
if (i === 0) {
points1 = this.create2PBezier(points[i], control1, points[i + 1], 50);
} else {
console.log(controlPoints);
points1 = this.create3PBezier(
points[i],
controlPoints[2 * i - 1],
control1,
points[i + 1],
50,
);
}
// 尾端部分
if (i + 2 === len - 1) {
points2 = this.create2PBezier(
points[i + 1],
control2,
points[i + 2],
50,
);
}
if (i + 2 === len - 1) {
resultPoints = [...resultPoints, ...points1, ...points2];
} else {
resultPoints = [...resultPoints, ...points1];
}
}
return resultPoints;
}

案例代碼

const input = [
{ x: 0, y: 0 },
{ x: 150, y: 150 },
{ x: 300, y: 0 },
{ x: 400, y: 150 },
{ x: 500, y: 0 },
{ x: 650, y: 150 },
]
const s = path.createSmoothLine(input);
let ctx = document.getElementById('cv').getContext('2d');
ctx.strokeStyle = 'blue';
ctx.beginPath();
ctx.moveTo(0, 0);
for (let i = 0; i < s.length; i++) {
ctx.lineTo(s[i].x, s[i].y);
}
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, 0);
for (let i = 0; i < input.length; i++) {
ctx.lineTo(input[i].x, input[i].y);
}
ctx.strokeStyle = 'red';
ctx.stroke();
document.getElementById('btn').addEventListener('click', () => {
let app = document.getElementById('app');
let index = 0;
let move = () => {
if (index < s.length) {
app.style.left = s[index].x - 10 + 'px';
app.style.top = s[index].y - 10 + 'px';
index++;
requestAnimationFrame(move)
}
}
move()
})
責任編輯:龐桂玉 來源: 得物技術
相關推薦

2020-08-13 06:56:57

Javascript插件前端

2014-12-08 10:56:24

JavaScript

2013-04-02 13:04:07

ListView平滑滾

2024-08-29 08:13:58

2021-10-19 22:23:47

CSSBeautiful按鈕

2011-11-03 09:13:27

JavaScript

2022-02-21 07:02:16

CSSbeautiful按鈕

2022-08-10 16:08:38

鴻蒙CSS

2013-04-08 14:07:28

CSS

2020-11-04 13:55:06

CSS密室逃脫前端

2012-06-28 10:21:37

JavaScript

2009-04-01 10:41:00

GSMWCDMA的

2021-05-07 09:18:04

CSS 文字動畫技巧

2017-09-18 16:13:59

前端圖像處理人臉識別

2022-08-29 17:39:53

應用開發css動畫

2021-01-19 12:16:10

CSS前端UI

2011-03-14 13:10:43

jQueryscroll滾動

2021-12-03 06:02:19

CSS濾鏡前端

2017-02-24 12:00:35

iOS代碼AutoLayout

2015-04-24 10:05:15

HTML+CSS阿童木頭像
點贊
收藏

51CTO技術棧公眾號

久久精品免费| jizzjizzjizz欧美| 1000精品久久久久久久久| 91在线视频成人| 国产真实的和子乱拍在线观看| 成人h动漫免费观看网站| 精品免费在线视频| 一区二区在线观看网站| 免费看黄网站在线观看| 久久一区二区三区四区五区| 久久综合伊人77777蜜臀| 中文字幕乱码一区| 高清在线一区| 午夜成人免费视频| 亚洲精品无人区| 国产成人手机在线| 裸体在线国模精品偷拍| 97精品国产97久久久久久免费| 中文字幕免费视频| 哺乳一区二区三区中文视频| 在线观看一区日韩| 极品粉嫩国产18尤物| av每日在线更新| 成人三级伦理片| 91精品中文在线| 国产成人无码专区| 亚洲视频一区| 久久久精品久久| 魔女鞋交玉足榨精调教| 综合久久成人| 91精品国产色综合久久ai换脸| 久久精品午夜福利| 电影k8一区二区三区久久| 国产精品二区一区二区aⅴ污介绍| 国产日韩欧美综合精品| 国产露脸无套对白在线播放| 久久久久久一区二区| 久久久久久久久综合| 日韩精品123区| 第一sis亚洲原创| 日韩精品中文字| 怡红院一区二区| 日本成人看片网址| 香蕉久久久久久久| 午夜精品影视国产一区在线麻豆| 日韩欧美亚洲一区二区| 亚洲欧美日韩一级| 黄瓜视频成人app免费| 偷窥少妇高潮呻吟av久久免费| 青青在线免费视频| 国产调教视频在线观看| 国产精品久久久久久久久图文区| 欧日韩一区二区三区| 亚洲av成人无码久久精品老人 | a网站在线观看| 美女在线观看视频一区二区| 国产精品久久久久久久久久久不卡 | 日韩三级毛片| 日韩av网站大全| 国产精品久久无码| 日韩精品福利一区二区三区| 亚洲韩国日本中文字幕| xxxx黄色片| 日韩美女毛片| 亚洲天堂网在线观看| 精品国产成人亚洲午夜福利| 精品美女在线视频| 一区二区三区高清国产| 麻豆视频免费在线播放| 日韩理论电影| 久久亚洲欧美日韩精品专区| 青草影院在线观看| 亚洲大胆av| 欧美一区第一页| 波多野结衣黄色网址| 免费久久精品视频| 91精品啪aⅴ在线观看国产| 国产女主播福利| 国产91高潮流白浆在线麻豆| 国产一区视频观看| 欧美日本网站| 日本一区二区不卡视频| 色哺乳xxxxhd奶水米仓惠香| 青春草视频在线| 一本一道综合狠狠老| 黄色一级免费大片| 韩日精品一区| 欧美大片拔萝卜| 素人fc2av清纯18岁| 日韩成人综合| 欧美放荡办公室videos4k| 日本一级淫片免费放| 天堂午夜影视日韩欧美一区二区| 国产欧美精品一区二区三区-老狼 国产欧美精品一区二区三区介绍 国产欧美精品一区二区 | 久久精品视频5| 国产综合色在线| 久久久一本精品99久久精品66| 国产乱子伦三级在线播放| 亚洲色图.com| 日av中文字幕| 一区二区三区四区精品视频 | 久久无码人妻精品一区二区三区 | 成人高清在线视频| 欧美激情视频一区二区三区| 国产视频中文字幕在线观看| 欧美性xxxx极品高清hd直播| 少妇愉情理伦片bd| 国产精品三级| 高清在线视频日韩欧美| 中文天堂在线视频| 99久久久久免费精品国产 | 欧美系列亚洲系列| 亚洲午夜久久久久久久久| 色婷婷热久久| 热久久视久久精品18亚洲精品| 国产日韩精品suv| 国产日韩欧美制服另类| 五十路熟女丰满大屁股| 中文字幕日韩亚洲| 国产一区二区三区高清在线观看| 日韩精品在线免费看| 久久99久久久久久久久久久| 久久综合毛片| 9lporm自拍视频区在线| 欧美精品在线观看播放| 免费网站在线高清观看| 午夜在线a亚洲v天堂网2018| 成人av资源网| 大地资源网3页在线观看| 91福利在线观看| 性久久久久久久久久| 国内精品美女在线观看| 国产欧美韩国高清| av资源在线观看免费高清| 图片区小说区区亚洲影院| 久久无码专区国产精品s| 日韩情爱电影在线观看| 国产精品成人av性教育| 青青久在线视频免费观看| 亚洲高清免费一级二级三级| 午夜免费视频网站| 98精品久久久久久久| 国产精品入口免费视频一| 国产中文字幕在线| 91国产成人在线| 91激情视频在线观看| 国产精品免费看| 国产一区二区三区四区hd| 金瓶狂野欧美性猛交xxxx| 日韩一级免费观看| 欧美黑吊大战白妞| 国产成人亚洲综合a∨婷婷图片| 色婷婷777777仙踪林| 久久三级毛片| 久久久精品久久久| www.香蕉视频| 午夜影视日本亚洲欧洲精品| 日本在线不卡一区二区| 夜夜爽av福利精品导航| 麻豆传媒一区| 婷婷综合六月| 丝袜亚洲欧美日韩综合| 伊人亚洲综合网| 亚洲人成小说网站色在线| 久久aaaa片一区二区| 欧美日韩第一区| 九色一区二区| 91精品韩国| 精品国模在线视频| 国产黄色免费大片| 午夜影院久久久| 九九九视频在线观看| 看片网站欧美日韩| 日本中文字幕一级片| 国产毛片久久久| 国产成人综合精品| 欧美日韩在线资源| 精品国产区一区| 亚洲不卡在线视频| 中文天堂在线一区| 免费高清视频在线观看| 国产亚洲午夜| 亚洲一二区在线| 凹凸成人在线| 国产成人亚洲综合91| wwwav在线| 亚洲精品网址在线观看| 在线观看色网站| 亚洲aaa精品| 成人一级片免费看| 成人免费视频视频| 青青草原国产在线视频| 国产综合欧美| 天堂av一区二区| 第四色在线一区二区| 国产精品com| 午夜av在线免费观看| 亚洲欧美国产精品专区久久| 一级做a爱片性色毛片| 午夜电影久久久| 少妇高潮在线观看| 91香蕉视频在线| 成人在线短视频| 美女爽到高潮91| 成人免费观看视频在线观看| 91精品国产91久久久久久密臀 | 亚洲深深色噜噜狠狠爱网站| 久久婷婷人人澡人人喊人人爽| 91精品网站在线观看| 欧美在线观看视频| 日本高清在线观看视频| 亚洲理论电影网| 日韩中文字幕免费| 色综合视频在线| 制服丝袜成人动漫| 不卡av电影在线| 五月天网站亚洲| 久久国产精品国语对白| 久久久久国产精品麻豆| 亚洲乱妇老熟女爽到高潮的片| 美女久久久精品| 可以免费观看av毛片| 亚洲大胆av| 亚洲精品天堂成人片av在线播放| 成人免费在线观看av| 国内精品国语自产拍在线观看| 欧美日本三级| 91精品久久久久久久久中文字幕| 丝袜美腿一区| 欧美中文字幕在线视频| 成人爽a毛片免费啪啪动漫| 久久久91精品国产一区不卡| 国产在线观看免费网站| 亚洲国产成人精品电影| www五月婷婷| 日韩限制级电影在线观看| 国产老妇伦国产熟女老妇视频| 欧美中文字幕一二三区视频| 精品免费囯产一区二区三区| 黄网站色欧美视频| 国产成人无码精品久久久久| 亚洲午夜免费福利视频| 久久久精品国产sm调教| 综合色天天鬼久久鬼色| 九九热视频在线免费观看| 国产精品久久夜| 成人欧美一区二区三区黑人一| 中文字幕精品三区| 精品免费一区二区三区| 黄色一级免费视频| 一区二区高清视频在线观看| 2021亚洲天堂| 亚洲一区二区三区四区在线观看 | 九九热视频在线观看| 日韩精品中文字幕在线| 视频在线观看你懂的| 亚洲乱码国产乱码精品精| 日韩精品视频在线观看一区二区三区| 亚洲黄页视频免费观看| 五月婷婷狠狠干| 亚洲欧美激情另类校园| h视频网站在线观看| 色香阁99久久精品久久久| 黄色av电影在线观看| 美女精品久久久| heyzo中文字幕在线| 欧美在线观看日本一区| 日韩中文影院| 91精品久久久久久久久不口人| 精品91福利视频| 国产亚洲精品久久飘花| 你微笑时很美电视剧整集高清不卡| 日韩免费三级| 亚洲欧美一级二级三级| 欧美啪啪免费视频| 日本一区中文字幕| 天天色天天干天天色| 成人高清视频在线观看| 真实乱视频国产免费观看| 亚洲欧洲av色图| 你懂的国产视频| 欧美性色黄大片手机版| 亚洲av无码一区二区乱子伦| 日韩精品在线第一页| 日本高清中文字幕在线| 欧美精品videosex极品1| 伊人久久av| 91亚洲午夜在线| 一区二区小说| 国产91视频一区| 日韩精品国产欧美| 欧洲成人午夜精品无码区久久| 久久久久久久久蜜桃| 久久久久久久久久97| 欧美日韩一区二区免费在线观看| 亚洲一区二区影视| 亚洲激情第一页| 婷婷在线视频| 日本91av在线播放| 国产麻豆精品| 欧美日本亚洲| 欧美视频不卡| 日本中文字幕观看| 91小视频免费观看| 免费人成年激情视频在线观看| 色婷婷一区二区| 黄色小视频免费观看| www.欧美三级电影.com| 日韩精品美女| 成人三级视频在线观看一区二区| 青青草原综合久久大伊人精品| 国产免费黄色小视频| 国产一区二区三区综合| www.狠狠爱| 精品欧美国产一区二区三区| www.97av| 精品国产视频在线| 免费污视频在线一区| 久久99精品久久久久久水蜜桃| 综合久久婷婷| 黄色小视频免费网站| 国产亚洲婷婷免费| 日韩 欧美 亚洲| 精品国产乱码久久久久久夜甘婷婷 | 日本在线成人| 亚洲永久激情精品| 日韩精品国产精品| 国产一二三四五区| 精品国产成人在线| 日韩中文字幕影院| 色综合91久久精品中文字幕| 成人在线日韩| 中文字幕中文字幕一区三区| 蜜臀精品一区二区三区在线观看| 亚洲欧美色图视频| 图片区日韩欧美亚洲| 欧美视频一二区| 国产69精品久久久久9999| 911精品国产| 男女日批视频在线观看| 成人黄色网址在线观看| 久久综合激情网| 精品国产乱子伦一区| 黄色成人在线网| 国产日韩在线一区二区三区| 在线欧美视频| 欧美 日本 国产| 狠狠躁夜夜躁久久躁别揉| 天堂91在线| 国产91精品在线播放| 精品久久影视| 亚洲精品午夜在线观看| 中文字幕一区二区日韩精品绯色| 亚洲一二区视频| 久热精品在线视频| 精品91福利视频| 男人添女荫道口图片| 91蜜桃网址入口| 亚洲黄网在线观看| 国产亚洲精品一区二区| 成人国产在线| 91视频成人免费| 成人国产精品免费网站| 欧美日韩一级黄色片| 中文字幕免费精品一区高清| 99精品视频在线免费播放| 久久久久久久久影视| 成人综合婷婷国产精品久久蜜臀| 国产黄色片免费看| 亚洲欧洲国产一区| 欧美天堂一区| 国产传媒久久久| 久久久久久免费网| 又色又爽又黄无遮挡的免费视频| 欧美成人h版在线观看| 大陆精大陆国产国语精品| 日本a级片免费观看| 国产日韩av一区| 国产高清免费观看| 国产91精品高潮白浆喷水| 不卡视频在线| 色诱av手机版| 91福利社在线观看| 97caopron在线视频| 久久久一本精品99久久精品| 精品一区二区三区久久久| 久久精品视频国产| 在线一区二区日韩| 日韩在线观看一区二区三区| 黄色免费视频大全| 综合久久综合久久| 你懂的在线观看| 91久久国产综合久久蜜月精品| 一本色道久久精品| 国产精品国产三级国产传播| 亚洲电影中文字幕| 欧美一级在线| www.玖玖玖| 一区二区三区在线不卡| 黄色影院在线播放|