1、需求:用 canvas 在上面的曲线上划线
2、问题:这个曲线我是第一次见,搞半天还发现不是圆的弧,是一种很奇怪的弧形,于是我就上网查 quadraticCurveTo 方法,才知道这个二次贝塞尔曲线的秘密
3、定义:它的形状由三个点决定:P0(起始点) , P1(控制点), P2 (终点),起始点和终点顾名思义,而控制点则控制了这个弧形的扭曲方向和扭曲程度,该曲线的发明是为了方便大家在电脑上画各种圆滑的弧线
令P0(x1,y1),P2(x2,y2), P1(cx,cy)
那么就是弧线上的点满足的方程就是
x = Math.pow(1-t, 2) * x1 + 2 * t * (1-t) * cx + Math.pow(t, 2) * x2
y = Math.pow(1-t, 2) * y1 + 2 * t * (1-t) * cy + Math.pow(t, 2) * y2
4、画弧线的主要代码:
ctx.moveTo(x1, y1);
ctx.quadraticCurveTo(cx, cy, x2, y2);
5、划线:设我现在要数量是 arrowNum,而且我要均匀地点缀到弧线上面去
arrowNum数量x1,y1起始坐标cx,cy控制点坐标x2,y2终点坐标
/**
* 在二次贝塞尔曲线上获取点数
* @param arrowNum 获取的数量
* @param x1 起始坐标x
* @param y1 起始坐标y
* @param cx 控制点坐标x
* @param cy 控制点坐标y
* @param x2 终点坐标x
* @param y2 终点坐标y
*/
const oneOrderBezier=(arrowNum:number, x1:number, y1:number, cx:number, cy:number, x2:number, y2:number)=>{
let tmp = []
arrowNum = arrowNum + 1;
let share = 1 / arrowNum;
for (let i = 1; i < arrowNum; i++) {
let t = i * share;
let x = Math.pow(1 - t, 2) * x1 + 2 * t * (1 - t) * cx + Math.pow(t, 2) * x2;
let y = Math.pow(1 - t, 2) * y1 + 2 * t * (1 - t) * cy + Math.pow(t, 2) * y2;
tmp.push({
x,
y
})
}
return tmp
}
参考链接:https://blog.csdn.net/m0_37738114/article/details/87987506
Comments | NOTHING