在二次贝塞尔曲线上面获取点坐标


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

声明:小小博客|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 在二次贝塞尔曲线上面获取点坐标


Carpe Diem and Do what I like