来源:未知 时间: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