`
haoningabc
  • 浏览: 1478044 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

webgl的贝塞尔曲线

阅读更多
BezierCurve
webgl的贝塞尔曲线
webgl例子
https://www.khronos.org/webgl/wiki/Demo_Repository

参考
http://jsdo.it/Biske/A07Y
http://jsdo.it/kimmy/Z9z6

(function(d, w){
    var FPS = 30;//FPS ,Frames Per Second
    var F = 300;//焦点距离
    var N = 1;//轨迹的个数
    var VERTEX_MAX = 5;//轨迹长度
    var TRAIL_QUALITY = 4000;//轨迹的品质,越小越直
    var mu = 0.5;//前的主持人点的依赖程度
    var bmRandom = function(mu, sigma){
        var x, y, r, tmp=null, tmp2;
        return function(){
            if(tmp !== null){
                tmp2 = tmp;
                tmp = null;
                return y*tmp2+mu;
            }
            do{
                x = Math.random()*2-1;
                y = Math.random()*2-1;
                r = x*x+y*y;
            }while(r>=1);
            tmp = sigma*Math.sqrt(-2*Math.log(r)/r);
            return x*tmp+mu;
        };
    };
    pointCopy = function(src, dst){
        dst.x = src.x;
        dst.y = src.y;
        dst.z = src.z;
        return dst;
    };
    Trail = function(pos, t, color_f){
        this.pos={x:0,y:0,z:0};
        this.start={x:0,y:0,z:0};
        this.goal={x:0,y:0,z:0};
        this.anchor_1={x:0,y:0,z:0};
        this.anchor_2={x:0,y:0,z:0};
        this.start_time = 0;
        this.take_time = 1;
        this.vertexes = [];
        this.anchors_1 = [];
        this.anchors_2 = [];
        this.color_f = color_f;
        pointCopy(pos, this.pos);
        pointCopy(pos, this.start);
        pointCopy(pos, this.goal);
        this.setNextGoal(t);
    };
    Trail.prototype.setNextGoal = function(t, target){
        pointCopy(this.goal, this.start);
        this.anchor_1.x = this.start.x+(this.start.x-this.anchor_2.x)*mu;
        this.anchor_1.y = this.start.y+(this.start.y-this.anchor_2.y)*mu;
        this.anchor_1.z = this.start.z+(this.start.z-this.anchor_2.z)*mu;
        if(target){
            this.anchor_2.x = (this.anchor_1.x+target.x)/2+myrand();
            this.anchor_2.y = (this.anchor_1.y+target.y)/2+myrand();
            this.anchor_2.z = (this.anchor_1.z+target.z)/2+myrand();
            this.goal.x = target.x;
            this.goal.y = target.y;
            this.goal.z = target.z;
        }else{
            this.anchor_2.x = this.anchor_1.x+myrand();
            this.anchor_2.y = this.anchor_1.y+myrand();
            this.anchor_2.z = this.anchor_1.z+myrand();
            this.goal.x = this.anchor_2.x+myrand();
            this.goal.y = this.anchor_2.y+myrand();
            this.goal.z = this.anchor_2.z+myrand();
        }
        this.start_time = t;
        this.take_time = 200+Math.random()*200;
        this.vertexes.push(pointCopy(this.start, {x:0,y:0,z:0}));
        this.anchors_1.push(pointCopy(this.anchor_1, {x:0,y:0,z:0}));
        this.anchors_2.push(pointCopy(this.anchor_2, {x:0,y:0,z:0}));
        if(this.vertexes.length > VERTEX_MAX){
            this.vertexes.splice(0,this.vertexes.length-VERTEX_MAX);
            this.anchors_1.splice(0,this.anchors_1.length-VERTEX_MAX);
            this.anchors_2.splice(0,this.anchors_2.length-VERTEX_MAX);
        }
    };
    Trail.prototype.update = function(t, target){
        bezier3(
            t-this.start_time,
            this.start,
            this.anchor_1,
            this.anchor_2,
            this.goal,
            this.take_time,
            this.pos
            );
        if(t-this.start_time > this.take_time){
            this.setNextGoal(this.start_time+this.take_time, target);
            this.update(t, target);
        }
    };
    Trail.prototype.draw = function(ctx, camera, t){
        var i, dz, dt, ddt, rt, a, v={x:0, y:0, z:0};
        var ps = {x:0, y:0};
        ctx.beginPath();
        if(perspective(this.vertexes[0], camera, ps)){
             ctx.moveTo(ps.x, ps.y);
        }
        var x0 = ps.x;
        rt = (t-this.start_time)/this.take_time;
        for(i=1; i<this.vertexes.length; i++){
            ddt = 0.01;
            for(dt=0; dt<1; dt+=ddt){
                bezier3(dt,
                        this.vertexes[i-1],
                        this.anchors_1[i-1],
                        this.anchors_2[i-1],
                        this.vertexes[i],
                        1,
                        v);
                if(perspective(v, camera, ps)){
                    dz = v.z-camera.z;
                    a = 1-(this.vertexes.length-i+1-dt+rt)/VERTEX_MAX;
                    this.color_f(ctx, a, dz);
                    ctx.lineTo(ps.x, ps.y);
                    ctx.stroke();
                    ctx.beginPath();
                    ctx.moveTo(ps.x, ps.y);
                    ddt = dz/TRAIL_QUALITY+0.01;
                }
            }
        }
        ddt = 0.01;
        for(dt=0; dt<rt; dt+=ddt){
            bezier3(dt,
                    this.start,
                    this.anchor_1,
                    this.anchor_2,
                    this.goal,
                    1,
                    v);
            if(perspective(v, camera, ps)){
                dz = v.z-camera.z;
                a = 1-(1-dt+rt)/VERTEX_MAX;
                this.color_f(ctx, a, dz);
                ctx.lineTo(ps.x, ps.y);
                ctx.stroke();
                ctx.beginPath();
                ctx.moveTo(ps.x, ps.y);
                ddt = dz/TRAIL_QUALITY+0.01;
            }
        }
        if(perspective(this.pos, camera, ps)){
            dz = this.pos.z-camera.z;
            a = 1-1/VERTEX_MAX;
            this.color_f(ctx, a, dz);
            ctx.lineTo(ps.x, ps.y);
            ctx.stroke();
        }
    };
    bezier3 = function(t, a, b, c, d, e, dst){
        t /= e;
        dst.x =
            a.x*(1-t)*(1-t)*(1-t)+
            b.x*3*t*(1-t)*(1-t)+
            c.x*3*t*t*(1-t)+
            d.x*t*t*t;
        dst.y =
            a.y*(1-t)*(1-t)*(1-t)+
            b.y*3*t*(1-t)*(1-t)+
            c.y*3*t*t*(1-t)+
            d.y*t*t*t;
        dst.z =
            a.z*(1-t)*(1-t)*(1-t)+
            b.z*3*t*(1-t)*(1-t)+
            c.z*3*t*t*(1-t)+
            d.z*t*t*t;
    };
    perspective = function(point, camera, dst){
        var dx = point.x-camera.x;
        var dy = point.y-camera.y;
        var dz = point.z-camera.z;
        if(dz > 0){
            dst.x = F*dx/dz;
            dst.y = F*dy/dz;
            return true;
        }
        return false;
    };
    updateScene = function(ctx){
        var i, goal;
        time_now = new Date().getTime();
        var time_d = time_now-time_pre;
        trails[0].update(time_now);
        for(i=1; i<trails.length; i++){
              trails[i].update(time_now, trails[i-1].pos);
        }
        camera.x += (trails[0].pos.x-camera.x)*0.0005*time_d;
        camera.y += (trails[0].pos.y-camera.y)*0.0005*time_d;
        camera.z += (trails[0].pos.z-camera.z-100)*0.0005*time_d;
        time_pre = time_now;
    };
    drawScene = function(ctx){
        var i;
        ctx.clearRect(-canvas.width/2, -canvas.height/2, canvas.width, canvas.height);
        for(i=0; i<trails.length; i++){
              trails[i].draw(ctx, camera, time_now);
        }
    };
    var myrand = bmRandom(0,20);
    var canvas = d.getElementById("world");
    var ctx = canvas.getContext("2d");
    var trails = [];
    var i;
    var time_now = new Date().getTime();
    var time_pre = time_now;
    var camera = {x:0, y:0, z:-200};
    for(i=0; i<N; i++){
        trails.push(new Trail({x:myrand(), y:myrand(), z:myrand()},
                              time_now,
                              function(a,z){return "#FFFFFF";}));
    }
    for(i=0; i<N; i++){
        switch(i%3){
            case 0:
                trails[i].color_f=function(ctx, a, dz){
                    var b = dz<10?0:a*F/dz;
                    b = (b>1?1:b)*(dz<30?(dz-10)/20:1);
                    ctx.strokeStyle = "rgba(255,"+Math.floor(255*a)+",0,"+b+")";
                    ctx.lineWidth = F/dz;
                    ctx.lineCap = b>0.8?"round":"butt";
                };
                break;
            case 1:
                trails[i].color_f=function(ctx, a, dz){
                    var b = dz<10?0:a*F/dz;
                    b = (b>1?1:b)*(dz<30?(dz-10)/20:1);
                    ctx.strokeStyle = "rgba(0, 255,"+Math.floor(255*a)+","+b+")";
                    ctx.lineWidth = F/dz;
                    ctx.lineCap = b>0.8?"round":"butt";
                };
                break;
            default:
                trails[i].color_f=function(ctx, a, dz){
                    var b = dz<10?0:a*F/dz;
                    b = (b>1?1:b)*(dz<30?(dz-10)/20:1);
                    ctx.strokeStyle = "rgba("+Math.floor(255*a)+",0,255,"+b+")";
                    ctx.lineWidth = F/dz;
                    ctx.lineCap = b>0.8?"round":"butt";
                };
                break;
        }
    }
    canvas.width = w.innerWidth;
    canvas.height = w.innerHeight;
    ctx.translate(canvas.width/2, canvas.height/2);
    setInterval(function(){
        updateScene();
        drawScene(ctx);
    }, 1000/FPS);
})(document, window);


html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>forked: 3D Bezier Curve - js do it</title>
<meta name="Description" content="" />
<meta name="Keywords"  content="" />

<link rel="stylesheet" type="text/css" media="screen,print" href="style.css" />
</head>
<body>

<canvas id='world'></canvas>

<script type="text/javascript" src="index.js"></script>
</body>
</html>

body{
    padding: 0;
    margin: 0;
}
#world{
    display: block;
    background-color: #000000;
    
}

enjoy it
http://haoning.net/webs/webgl/BezierCurve/



最简单的实现方式
<script type="text/javascript">
window.onload = function(){    
    var canvas = document.getElementById("myCanvas");    
    var context = canvas.getContext("2d");    
     
    context.moveTo(188, 130);    
     
    var controlX1 = 140;    
    var controlY1 = 10;    
    var controlX2 = 388;    
    var controlY2 = 10;    
    var endX = 388;    
    var endY = 170;    
     
    context.bezierCurveTo(controlX1, controlY1, controlX2,     
        controlY2, endX, endY);    
     
    context.lineWidth = 1;    
    context.strokeStyle = "black"; // line color    
    context.stroke();    
}; 
</script>
<canvas id='myCanvas'></canvas>


  • 大小: 33.7 KB
分享到:
评论

相关推荐

    贝塞尔曲线

    贝塞尔曲线是计算机图形学中广泛使用的一种数学工具,它在二维和三维图形设计、动画、游戏开发以及工业设计等领域有着重要应用。本项目旨在实现一个可以交互操作的n阶贝塞尔曲线,允许用户通过鼠标生成和调整控制点...

    多段贝塞尔/B样条曲线绘制与鼠标交互控制

    在计算机图形学中,贝塞尔曲线(Bézier curves)和B样条(B-Splines)曲线是两种广泛使用的数学工具,它们被用来创建平滑、连续的曲线,尤其在2D和3D建模、游戏开发、CAD设计等领域应用广泛。本文将围绕“多段...

    bezier:在浏览器中绘制更高阶的贝塞尔曲线

    WebGL允许在浏览器中进行3D图形绘制,而SVG则是用于创建矢量图形的XML格式,两者都支持贝塞尔曲线的绘制。 总结来说,"bezier"项目是一个探索和实现高阶贝塞尔曲线在浏览器环境中的绘制的实验。通过JavaScript和...

    水波球效果

    这种效果的核心在于使用贝塞尔曲线来创建动态的、流畅的波纹动画。贝塞尔曲线是计算机图形学中的一个重要工具,它允许我们精确地控制曲线的形状和路径,因此在游戏开发、UI设计等领域应用广泛。 贝塞尔曲线的数学...

    画橡皮筋线

    在画橡皮筋线时,我们通常使用二维的贝塞尔曲线,如线性贝塞尔曲线或二次贝塞尔曲线。线性贝塞尔曲线由两个端点和两个控制点定义,而二次贝塞尔曲线则涉及三个点:起始点、结束点以及一个控制点。 实现橡皮筋线的...

    CurSur-WebGL中的几何设计中的3D曲线和曲面

    本主题将深入探讨如何使用Three.js库,一种基于JavaScript的WebGL库,来实现三维几何设计中的三次曲线、贝塞尔曲线以及B样条曲线。 首先,让我们了解一下三次曲线。三次曲线是一种在几何图形中广泛应用的线性构造,...

    bezier-surface-master.rar

    对于二维贝塞尔曲线,可能使用二阶或三阶贝塞尔曲线;对于三维贝塞尔曲面,则可能涉及四阶贝塞尔曲线,需要对每一对参数计算对应的曲线,并组合成曲面。 4. **渲染**:利用HTML5的Canvas API或者WebGL,将计算出的...

    计算机软件-商业源码-实例049-跳跃的曲线.zip

    在计算机图形学中,曲线通常通过数学方程来描述,如贝塞尔曲线、样条曲线或者B-Spline曲线。这些曲线能够创建出平滑、连续的形状,广泛应用于UI设计、3D建模等领域。 源码中的实现可能包括以下几个关键部分: 1. *...

    ThreeJS使用Curve曲线让物体沿轨迹运动DEMO

    通过继承这个类,我们可以创建各种形状的曲线,如直线、圆弧、贝塞尔曲线等。这些曲线可以用来定义物体运动的轨迹。 创建一个Curve子类需要重写`getPoint(t)`方法,其中`t`是一个介于0和1之间的参数,表示沿着曲线...

    particles-on-bezier-curves:http

    【标题】"粒子系统在贝塞尔曲线上的应用:http服务" 【内容】 ...通过这个项目,开发者可以提升在JavaScript、WebGL、Canvas以及贝塞尔曲线运用等方面的能力,同时也能体验到创造动态视觉艺术的乐趣。

    计算机图形学源代码(实现各种图形绘制和变换)

    贝塞尔曲线是通过控制点来定义的,源代码中可能会有实现不同阶数贝塞尔曲线的函数,如二阶、三阶或更高阶。样条曲线常用于动画和建模,如Catmull-Rom样条,源代码可能包括插值算法的实现。 变换在计算机图形学中至...

    sketches:使用canvas-sketch的代码草图

    可能的话题和有用的东西灵感与教程黄洁仪(Jamie Wong)签名的距离功能杰米·黄(Jamie Wong)的贝塞尔曲线弗雷亚·霍尔梅(FreyaHolmér)的贝塞尔曲线虚假的样条线,安德斯·霍夫(Anders Hoff) 牧养随机网格,由...

    hedgehog-engine:基于WebGL的渲染引擎https

    特征顶点和片段着色器编译灵活的着色器程序编译绘制不同的模型无需重新加载场景即可编辑场景的小部件可互换相机2D和3D图形伽玛校正和光衰减麦克风录音鼠标输入支持(仅单击) 键盘输入支持(仅按键) 贝塞尔曲线旋转...

    InteractiveBezierSurface

    2. **贝塞尔曲线理论**:理解贝塞尔曲线的基本原理,如贝塞尔方程,以及控制点对曲线形状的影响。 3. **贝塞尔曲面**:由二维贝塞尔曲线通过交织或堆叠构建,用于创建更复杂的表面。 4. **交互性实现**:使用...

    书籍翻页3D特效

    这通常涉及到复杂的数学算法,如四边形变形、贝塞尔曲线、法线贴图等。 2. **几何变换**: - **平移(Translation)**: 书页从静止位置移动到翻页的位置。 - **旋转(Rotation)**: 书页在翻页过程中会沿着特定轴...

    Bezier曲面旋转动画

    在二维空间中,我们有贝塞尔曲线,而在三维空间中,这些曲线可以被扩展成曲面。Bezier曲面的特性在于其可以通过线性组合控制点来计算出曲面上任意点的位置,这使得它具有良好的可控制性和灵活性。 贝塞尔曲线的基本...

    ShadowEditor-v0.5.2源码

    线段、CatmullRom曲线、二次贝塞尔曲线、三次贝塞尔曲线、椭圆曲线;点标注;箭头帮助器、轴帮助器;精灵。 4. 内置光源:环境光、平行光、点光源、聚光灯、半球光、矩形光。 5. 内置组件:背景音乐、粒子发射器、...

    3DChart(全部源码)

    开发者可能利用了如贝塞尔曲线、样条函数等数学工具,以确保曲线的平滑度和真实性。源码中可能包含处理数据点、计算曲线路径和渲染曲线的代码。 在"3DChart"这个压缩包中,你可以找到实现这些3D图表的关键代码,...

    javascript经典特效---图形显示特效.rar

    4. 数学算法:许多图形特效涉及几何变换和运动模拟,这往往需要运用到数学知识,如向量运算、矩阵变换、贝塞尔曲线等。例如,通过矩阵变换可以实现2D或3D的旋转、缩放,贝塞尔曲线则常用于平滑的路径动画。 5. ...

    three.js符号线动画

    `bezier.js`可能包含贝塞尔曲线的实现,这是一种在计算机图形学中广泛使用的数学工具,用于创建平滑的曲线路径。在three.js中,贝塞尔曲线可以用于定义线的路径,从而创建动态的流动效果。 `arrow.png`可能是一个...

Global site tag (gtag.js) - Google Analytics