精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

欧洲亚洲一区| 久久久久女教师免费一区| 久久婷婷综合色| 快射av在线播放一区| 国产麻豆一精品一av一免费| 欧美激情奇米色| 免费a级黄色片| jizz亚洲女人高潮大叫| 亚洲欧美日韩电影| 女女同性女同一区二区三区91| 亚洲欧美日韩激情| 亚洲国产精品成人| 亚洲精品久久久久国产| 午夜久久久精品| 午夜伦理在线视频| 久久久久久久免费视频了| 91美女福利视频高清| 日本污视频在线观看| 色乱码一区二区三区网站| 日韩午夜av一区| 99免费视频观看| 中文字幕有码在线视频| 久久久www成人免费无遮挡大片| 国产欧美中文字幕| 51国产偷自视频区视频| 99久久夜色精品国产亚洲1000部| 亚洲国产成人在线播放| 日韩精品视频一二三| 日韩精品极品| 一区二区三区在线高清| 日韩偷拍一区二区| 污视频在线免费观看| 国内精品不卡在线| 国产精品成人在线| 9i看片成人免费看片| 欧美日韩精品| 久久久电影免费观看完整版| 免费毛片视频网站| 第四色中文综合网| 日韩视频一区二区三区| 少妇一级淫免费放| 三级成人在线| 欧美日韩亚洲一区二| 一本久道高清无码视频| 精精国产xxxx视频在线| 国产精品人人做人人爽人人添 | ww久久综合久中文字幕| 亚洲国产aⅴ天堂久久| 日韩精品第1页| 中文日本在线观看| 国产三级精品视频| 日韩av一区二区三区美女毛片| 三级网站免费观看| 国产成人福利片| 亚洲一区二区三区久久| 97免费观看视频| 蜜桃免费网站一区二区三区| 国产成人激情小视频| 日日夜夜狠狠操| 丝袜诱惑制服诱惑色一区在线观看| 性色av一区二区三区免费| 黄色小视频在线免费看| 激情欧美一区| 69av在线视频| 日日噜噜噜噜人人爽亚洲精品| 亚洲欧美日韩专区| 日韩美女视频免费看| 91丨九色丨海角社区| 日本视频中文字幕一区二区三区| 国产精品夫妻激情| 96日本xxxxxⅹxxx17| 老色鬼精品视频在线观看播放| 国产精品老女人视频| 在线观看免费视频a| 精品亚洲国产成人av制服丝袜| 国产欧美精品xxxx另类| 国产女人18毛片水真多| 高清在线不卡av| 久久婷婷开心| 成人综合影院| 亚洲视频在线观看三级| 亚洲中文字幕无码一区二区三区| 岛国av在线网站| 在线影院国内精品| 亚洲天堂av一区二区| 亚洲va欧美va人人爽成人影院| 亚洲精品一线二线三线| 久久成人激情视频| 久久久精品久久久久久96| 欧美精品性视频| 国产精品第5页| 久久99热99| 含羞草久久爱69一区| 国产日韩精品在线看| 亚洲欧美激情在线| 日本精品www| 亚洲免费一区| 日韩精品免费观看| 黄色裸体一级片| 国内视频精品| 国产精品美女久久久久久免费| 国产精品自偷自拍| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 中文另类视频| 日韩欧美国产一区二区三区| 亚洲调教欧美在线| 亚洲成av人片乱码色午夜| 国内自拍欧美激情| 国产免费黄色大片| 久久精品亚洲精品国产欧美| 亚洲中文字幕无码一区二区三区| 欧美韩国亚洲| 亚洲精品www久久久| 熟女av一区二区| 男人的天堂亚洲| 99三级在线| 日本黄色片在线观看| 欧美日韩在线视频一区| 无套白嫩进入乌克兰美女| 激情五月色综合国产精品| 欧美—级高清免费播放| 91成品人影院| 欧美高清在线一区| 免费在线a视频| 超碰地址久久| 欧美床上激情在线观看| 在线观看中文字幕网站| 久久久久久综合| 成人免费播放器| 久久99成人| 日日摸夜夜添一区| 五月激情丁香网| 91麻豆视频网站| 日韩欧美精品免费| 欧美激情三级| 欧美成年人网站| 国产美女主播在线观看| 亚洲国产精品ⅴa在线观看| 国产1区2区在线| 蜜臀久久99精品久久一区二区| 午夜精品久久久久久99热软件| 午夜精品久久久久久久99热黄桃| 亚洲色图制服诱惑| 又色又爽又黄视频| 久久精品亚洲欧美日韩精品中文字幕| 国产精品永久免费在线| 国产高清视频在线观看| 色综合天天视频在线观看| 亚洲永久无码7777kkk| 99精品视频免费观看| 国内一区二区在线视频观看| www在线看| 亚洲精品国产精品国自产在线| 国产香蕉在线视频| www.亚洲人| 亚洲欧洲日产国码无码久久99| 欧美毛片免费观看| 欧美怡春院一区二区三区| 欧美日韩在线精品一区二区三区激情综 | 91精品黄色片免费大全| 日本一二三区在线观看| 国产资源在线一区| www.激情网| 欧美jizz19性欧美| 日韩av快播网址| av在线收看| 欧美日韩国产片| 国产67194| 国产成人精品免费视频网站| 亚洲 自拍 另类小说综合图区| 鲁大师精品99久久久| 日韩美女视频中文字幕| 麻豆电影在线播放| 欧美本精品男人aⅴ天堂| 日本天堂网在线观看| 久久久久久亚洲综合| 欧美黄色性生活| 一区二区三区在线| 国产精品免费看一区二区三区 | 68精品久久久久久欧美| 国产女人在线观看| 91精品国产高清一区二区三区 | 亚洲高清网站| 欧美性色黄大片人与善| 亚洲高清国产拍精品26u| 欧美猛少妇色xxxxx| av女名字大全列表| 欧美视频一区二区| 欧美人妻精品一区二区免费看| 不卡在线观看av| 亚洲36d大奶网| 激情综合在线| 亚洲一区二区三区精品动漫| 亚洲国产精品免费视频| 欧美亚洲国产日本| 免费在线看黄| 亚洲精品美女免费| 99国产揄拍国产精品| 精品日韩美女的视频高清| 激情无码人妻又粗又大| proumb性欧美在线观看| 午夜精品中文字幕| 亚洲欧美网站| 欧美另类videosbestsex日本| 伊人成综合网伊人222| 51国偷自产一区二区三区| 日韩中文影院| 97在线免费观看| а√资源新版在线天堂| 精品国产百合女同互慰| 国产精品欧美久久久久天天影视| 欧美视频裸体精品| 国产一级做a爰片在线看免费| 国产精品美女www爽爽爽| 在线免费播放av| 国产综合色视频| 成人亚洲视频在线观看| 99国产精品| 男人添女人下部视频免费| 色爱综合网欧美| 日韩精品久久久| 欧美大片网址| 91麻豆蜜桃| 亚洲精品第一| 国产精品免费视频xxxx| 625成人欧美午夜电影| 色综合久久精品亚洲国产| av影片在线看| 亚洲片国产一区一级在线观看| 黄色美女一级片| 日韩一区二区精品| 91福利免费视频| 欧美视频你懂的| 国产真人无遮挡作爱免费视频| 粉嫩av一区二区三区免费野| 国产在线观看你懂的| 亚洲天堂免费看| 少妇高潮一区二区三区喷水| 国产农村妇女毛片精品久久麻豆 | av男人天堂网| 欧美顶级少妇做爰| 一级黄色片在线看| 欧美日韩亚洲国产综合| 在线免费观看av网址| 欧美视频在线观看免费| 青青草免费观看视频| 亚洲va天堂va国产va久| 精品人妻在线播放| 亚洲图片欧美视频| 国产一级淫片免费| 精品福利在线观看| 日韩在线视频免费播放| 欧美日韩国产在线| 亚洲成人av影片| 91久久精品网| 一级黄色av片| 欧美日韩亚洲综合| 精品久久国产视频| 欧美一级xxx| 亚洲第一第二区| 亚洲精品aⅴ中文字幕乱码| 欧美女子与性| 色午夜这里只有精品| 2020国产在线视频| 久久久久久国产免费| 久久免费电影| 午夜美女久久久久爽久久| 电影一区二区三区| 国产精品自产拍在线观| 奇米一区二区| 精品免费日产一区一区三区免费| 国产亚洲精品美女久久久久久久久久| 一本久道久久综合狠狠爱亚洲精品| 中文乱码免费一区二区三区下载| 国产乱淫av片杨贵妃| 免费永久网站黄欧美| 九九精品久久久| 成人夜色视频网站在线观看| 久久久无码人妻精品一区| 中文字幕免费一区| 免费在线观看黄色av| 狠狠躁夜夜躁人人爽天天天天97| 国产在线观看第一页| 欧美一区二区视频在线观看2022| 日韩一级免费毛片| 国产午夜精品一区二区三区| 好了av在线| 2019亚洲男人天堂| 亚洲男男av| 久久偷看各类wc女厕嘘嘘偷窃| 天天影视综合| 国产中文字幕免费观看| 国产在线精品国自产拍免费| 日韩aaaaa| 国产精品电影院| 亚洲综合一二三| 7777精品伊人久久久大香线蕉经典版下载| 亚洲精品久久久久久无码色欲四季| 亚洲人成电影在线播放| 欧美人与性动交α欧美精品济南到| 欧美在线中文字幕| 日韩三级av高清片| 亚洲电影一二三区| 亚洲国产网站| 天天综合天天添夜夜添狠狠添| 91视频你懂的| 妺妺窝人体色www婷婷| 91国产成人在线| 欧美性受xxxx狂喷水| 日韩视频欧美视频| 欧美××××黑人××性爽| 2014亚洲精品| 欧美韩日一区| www日韩视频| av亚洲精华国产精华精华 | 免费a在线观看| 欧美第一黄色网| 亚洲精品大片| 亚洲一区二区三区欧美| 亚洲免费中文| 91丨porny丨对白| 亚洲天堂2016| 中文字幕视频二区| 亚洲色图欧美制服丝袜另类第一页| 蜜臀av在线| 51国偷自产一区二区三区的来源 | 成年人网站免费视频| 国内成人精品2018免费看| 女人十八毛片嫩草av| 一本到不卡免费一区二区| 天堂av资源网| 欧美激情视频一区| 亚洲综合网站| 97碰在线视频| 国产福利一区二区三区视频| 91传媒免费观看| 欧美日韩亚州综合| 成人在线免费公开观看视频| 日韩免费在线观看视频| 亚洲8888| 日韩精品免费播放| 国产色综合一区| 亚洲精品无码久久久久| 一区二区三区国产视频| 成人毛片免费| 五月婷婷一区| 欧美aaaaa成人免费观看视频| 国产免费一区二区三区网站免费| 一本一道综合狠狠老| 久久精品色图| 国产精品扒开腿做爽爽爽男男| 精品视频97| 成人日韩在线视频| 中文字幕日本乱码精品影院| 国产日韩欧美视频在线观看| 另类色图亚洲色图| 福利欧美精品在线| 欧美成人一区二区在线观看| 91美女在线观看| 欧美国产一级片| 色偷偷88888欧美精品久久久| 9999精品| 黄页网站在线观看视频| 久久亚洲二区三区| 伦av综合一区| 深夜福利国产精品| 国产专区精品| 成人免费在线网| 久久久久久久免费视频了| 中文字幕 视频一区| 久久久精品999| 精品三级av| www.99在线| 亚洲精品国产品国语在线app| 天堂网av2014| 国产精品欧美在线| 欧美日韩蜜桃| 91精品人妻一区二区三区| 欧美人牲a欧美精品| 欧美黄色视屏| 欧美日韩综合久久| 六月丁香婷婷色狠狠久久| 麻豆视频在线观看| 亚洲美女视频网站| avtt久久| 无码人妻丰满熟妇区毛片18| 中文字幕一区二区三区四区不卡| 亚洲乱码国产乱码精品精软件| 日韩美女主播视频| 欧美1区免费| 久久午夜福利电影| 欧美刺激脚交jootjob| 亚洲精品在线影院| www.亚洲成人网| 亚洲国产精品ⅴa在线观看| 亚洲av色香蕉一区二区三区| 日本道色综合久久影院| 欧美va天堂| 亚洲国产日韩一区无码精品久久久| 日韩女优毛片在线|