Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

高次贝塞尔曲线的绘制轨迹

  看维基百科上的贝塞尔曲线的绘制过程GIF动画感觉好带感,不得不感叹 de Casteljau 算法是一个美丽而且稳定的算法,只是性能上不太好罢了。维基百科上只提供了最高5次贝塞尔曲线的绘制轨迹。于是咱自己也来做一个这个绘制轨迹吧?画个32次的够不够?
  效果截图:

  下面是代码:
<!DOCTYPE html>
<base href="http://www.web-tinker.com" />
<script src="/share/LinearAlgebra.1.0.js"></script>
<canvas></canvas>
<script>
//各种初始化
document.body.style.margin="0px";
var canvas=document.querySelector("canvas");
canvas.style.position="fixed";
canvas.width=document.documentElement.clientWidth;
canvas.height=document.documentElement.clientHeight;
var w=canvas.width,h=canvas.height;
var g=canvas.getContext("2d");

//准备一组随机顶点
function rw(){return Math.random()*w;}
function rh(){return Math.random()*h;}
var points=[];
for(var i=0;i<32;i++)
  points.push(new Vector(rw(),rh()));

//准备一个插值函数
var f=Bezier(points);

//主过程
void function(){
  var i=0;
  var r=[];
  void function callee(){
    g.fillRect(0,0,w,h);
    var p=f(i);
    r.push(p);
    g.save();
    g.strokeStyle="red";
    g.lineWidth="3";
    g.beginPath();
    g.moveTo.apply(g,r[0]);
    for(var j=1;j<r.length;j++)
      g.lineTo.apply(g,r[j]);
    g.stroke();
    g.restore();
    if(i==1)return;
    i+=0.005;
    if(i>1)i=1;
    setTimeout(callee,16);
  }();
}();

//定义贝塞尔曲线函数的构造器
function Bezier(points){
  return function(x){
    g.beginPath();
    g.moveTo.apply(g,points[0]);
    for(var i=1;i<points.length;i++)
      g.lineTo.apply(g,points[i]);
    g.strokeStyle="hsl("+points.length*64+",50%,30%)";
    g.stroke();
    var result=[];
    for(var i=1;i<points.length;i++)
      result.push(interpolate(points[i-1],points[i],x));
    if(result.length==1)return result[0];
    return Bezier(result)(x);
  };
};

//定义线性插值函数
function interpolate(v1,v2,x){
  return v2.add(v1.multiply(-1)).multiply(x).add(v1);
};
</script>
网名:
3.80.32.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^