原文地址: https://zhuanlan.zhihu.com/p/33193050
用到贝塞尔曲线公式来计算出顶点,从而生成贝塞尔曲线。
/** * 生成四阶贝塞尔曲线定点数据 * @param p0 起始点 { x : number, y : number, z : number } * @param p1 控制点1 { x : number, y : number, z : number } * @param p2 控制点2 { x : number, y : number, z : number } * @param p3 终止点 { x : number, y : number, z : number } * @param num 线条精度 * @param tick 绘制系数 * @returns {{points: Array, num: number}} */ function create3DBezier(p0, p1, p2, p3, num, tick) { let pointMum = num || 100; let _tick = tick || 1.0; let t = _tick / (pointMum - 1); let points = []; for (let i = 0; i < pointMum; i++) { let point = getBezierNowPoint(p0, p1, p2, p3, i, t); points.push(point.x); points.push(point.y); points.push(point.z); } return points; } /** * 四阶贝塞尔曲线公式 * @param p0 * @param p1 * @param p2 * @param p3 * @param t * @returns {*} * @constructor */ function Bezier(p0, p1, p2, p3, t) { let P0, P1, P2, P3; P0 = p0 * (Math.pow((1 - t), 3)); P1 = 3 * p1 * t * (Math.pow((1 - t), 2)); P2 = 3 * p2 * Math.pow(t, 2) * (1 - t); P3 = p3 * Math.pow(t, 3); return P0 + P1 + P2 + P3; } /** * 获取四阶贝塞尔曲线中指定位置的点坐标 * @param p0 * @param p1 * @param p2 * @param p3 * @param num * @param tick * @returns {{x, y, z}} */ function getBezierNowPoint(p0, p1, p2, p3, num, tick) { return { x : Bezier(p0.x, p1.x, p2.x, p3.x, num * tick), y : Bezier(p0.y, p1.y, p2.y, p3.y, num * tick), z : Bezier(p0.z, p1.z, p2.z, p3.z, num * tick), } } 如果我们只需要获取整条贝塞尔曲线上所有的顶点数据集,那么我们就需要调用create3DBezier()函数并填入指定参数即可。关于四阶贝塞尔曲线公式等数学知识请自行百度,本人也仅是照着公式将函数敲出来了→_→。 // 传入顶点数据 let bezierPoint = create3DBezier( { x : -0.7, y : 0, z : 0 }, // p0 { x : -0.25, y : 0.5, z : 0 }, // p1 { x : 0.25, y : 0.5, z : 0 }, // p2 { x : 0.7, y : 0, z : 0 }, // p3 20, 1.0 );