来源:未知 时间:2023-02-13 16:57 作者:小飞侠 阅读:次
[导读] 今天带来JS贝塞尔曲线公式代码。 贝塞尔又称贝塞尔曲线,是为了解决计算机中特殊曲线而诞生的。根据数学公式我们先看下1阶,2阶,3阶贝塞尔曲线公式,对应如下图: 1阶贝塞尔 又...
今天带来JS贝塞尔曲线公式代码。 贝塞尔又称贝塞尔曲线,是为了解决计算机中特殊曲线而诞生的。根据数学公式我们先看下1阶,2阶,3阶贝塞尔曲线公式,对应如下图: 1阶贝塞尔又称线性公式,是由2个点组成的,给定点P0、P1,线性贝兹曲线只是一条两点之间的直线。这条线由下式给出: $B(t) = P0 + \left( p1 - p0 \right) * t = \left( 1-t \right) * P0 + t * P1, t \in [0,1]$ 根据数学公式得出JS代码: // 一次贝塞尔 function oneBsl() { //t var t = 0; // 初始参数 var p0 = { x: 200, y: 300 }; var p1 = { x: 300, y: 200 } var timer = setInterval(function(){ toDraw(); },1000/60) function toDraw() { t += 0.01; if(t >= 1) { clearInterval(timer) } var nowX = (1-t)*p0.x + t * p1.x; var nowY = (1-t)*p0.y + t * p1.y; testNode.style.left = nowX + 'px'; testNode.style.top = nowY + "px"; var boxNode = document.createElement("div"); boxNode.classList.add("box"); boxNode.style.left=testNode.offsetLeft+"px"; boxNode.style.top=testNode.offsetTop+"px"; document.body.appendChild(boxNode); } } oneBsl(); 2阶贝塞尔二次方贝兹曲线的路径由给定点P0、P1、P2的函数B(t)追踪: $B(t) = \left( 1-t \right)^{2}P0 + 2t\left( 1-t \right)P1 + t^{2}P2, t \in [0,1]$ 根据数学公式得出JS代码: // 二次贝塞尔 function twoBsl() { //t var t = 0; // 初始参数 var p0 = { x: 500, y: 300 }; var p1 = { x: 700, y: 150 } var p2 = { x: 900, y: 300 } var timer = setInterval(function(){ toDraw(); },1000/60) function toDraw() { t += 0.01; if(t >= 1) { clearInterval(timer) } var nowX = Math.pow((1-t), 2) * p0.x + 2 * t * (1 - t) * p1.x + Math.pow((t), 2) * p2.x; var nowY = Math.pow((1-t), 2) * p0.y + 2 * t * (1 - t) * p1.y + Math.pow((t), 2) * p2.y; testNode.style.left = nowX + 'px'; testNode.style.top = nowY + "px"; var boxNode = document.createElement("div"); boxNode.classList.add("box"); boxNode.style.left=testNode.offsetLeft+"px"; boxNode.style.top=testNode.offsetTop+"px"; document.body.appendChild(boxNode); } } twoBsl(); 3阶贝塞尔曲线P0、P1、P2、P3四个点在平面或在三维空间中定义了三次方贝兹曲线。曲线起始于P0走向P1,并从P2的方向来到P3。一般不会经过P1或P2;这两个点只是在那里提供方向资讯。P0和P1之间的间距,决定了曲线在转而趋进P3之前,走向P2方向的“长度有多长”。 曲线的参数形式为: 根据数学公式得出JS代码: // 三次贝塞尔 function threeBsl() { //t var t = 0; // 初始参数 var p0 = { x: 500, y: 600 }; var p1 = { x: 700, y: 350 } var p2 = { x: 900, y: 350 } var p3 = { x: 900, y: 600 } var timer = setInterval(function(){ toDraw(); },1000/60) function getYh() { var yhArr = []; var n = 4; for(i=0; i < n; i++) { if (typeof yhArr[i] === 'undefined') { yhArr[i] = []; // 初始化二维 } var secondN = i + 1; // 二行长度 // 遍历二行 for(j=0; j<secondN; j++) { // 当前值 var nowNum = 1; // 校验父级前后存在并相加 if (yhArr[i - 1] && yhArr[i - 1][j-1] && yhArr[i - 1][j]) { nowNum = yhArr[i - 1][j-1] + yhArr[i - 1][j]; } yhArr[i][j] = nowNum; } } console.log(yhArr) return yhArr; } function toDraw(cf) { t += 0.01; if(t >= 1) { clearInterval(timer) } var nowX = Math.pow((1-t), 3) * p0.x + (3 * p1.x * t * Math.pow((1-t), 2)) + (3 * p2.x * Math.pow((t), 2)) * (1-t) + p3.x *Math.pow((t), 3); var nowY = Math.pow((1-t), 3) * p0.y + (3 * p1.y * t * Math.pow((1-t), 2)) + (3 * p2.y * Math.pow((t), 2)) * (1-t) + p3.y *Math.pow((t), 3); testNode.style.left = nowX + 'px'; testNode.style.top = nowY + "px"; var boxNode = document.createElement("div"); boxNode.classList.add("box"); boxNode.style.left=testNode.offsetLeft+"px"; boxNode.style.top=testNode.offsetTop+"px"; document.body.appendChild(boxNode); } } threeBsl(); n阶贝塞尔曲线:根据多阶的规律,可以得出如下结果: a * (1 - t)^b * t^c * Pn; 其中:
其中: a 则可以用杨辉三角表达,杨慧三角可以看我上一篇文章 https://www.zixuephp.com/wzqd/jsjiheshuxuezhishi/20230208_46004.html 具体思路如下: 构造杨辉三角二维数组,然后遍历得a,分别带入 b , c 的关系到公式中,对所有结果累加即可。 多阶公式效果预览:多阶公式JS代码:<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>贝塞尔canvas</title> <style type="text/css"> *{ margin: 0px; padding: 0px; } </style> </head> <body> <canvas id="canvas" width="400" height="400"></canvas> <script type="text/javascript"> var t = 0; // 初始化t // 初始化控制点 var points = [ { x: 10, y: 100 }, { x: 100, y: 300 }, { x: 150, y: 350 }, { x: 200, y: 120 }, { x: 300, y: 350 }, { x: 350, y: 100 } ]; function getYh(ponts) { var yhArr = []; var n = ponts.length; for(i=0; i < n; i++) { if (typeof yhArr[i] === 'undefined') { yhArr[i] = []; // 初始化二维 } var secondN = i + 1; // 二行长度 // 遍历二行 for(j=0; j<secondN; j++) { // 当前值 var nowNum = 1; // 校验父级前后存在并相加 if (yhArr[i - 1] && yhArr[i - 1][j-1] && yhArr[i - 1][j]) { nowNum = yhArr[i - 1][j-1] + yhArr[i - 1][j]; } yhArr[i][j] = nowNum; } } console.log(yhArr[n-1]) return yhArr[n-1]; } // n次贝塞尔 function nBsl() { // 获得当a组 var as = getYh(points); t += 0.01; if(t >= 1) { clearInterval(timer) } var tempX = 0; var tempY = 0; // N 为控制点数量 for(var i=0; i<as.length;i++) { var a = as[i]; var b = as.length - (i+1); // (N - 1) 递减到 0 (b 为 1-t 的幂) var c = i; // 0 递增到 (N - 1) (c 为 t 的幂) tempX += getTemp(a, b, c, points[i].x); tempY += getTemp(a, b, c, points[i].y); // 绘制控制点 draw(points[i].x, points[i].y, 'red', 5); } function getTemp(a, b, c, Pn) { var _temp = a * Math.pow(1 - t, b) * Math.pow(t, c) * Pn; return _temp; } draw(tempX, tempY); console.log('tempX',tempX, 'tempY', tempY) } // 绘制 function draw(x, y, color, w) { var canvas = document.querySelector("#canvas"); var context = canvas.getContext("2d"); var w = w ? w : 1; context.beginPath(); context.strokeStyle = color ? color : 'black'; // context.moveTo(x, y); // context.lineTo(x, y); context.rect(x, y, w, w); context.stroke(); } var timer = setInterval(function(){ nBsl(); },1000/60) </script> </body> </html> 以上就是js贝塞尔曲线公式代码全部内容,感谢大家支持自学php网。 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com