睿美印象网络欢迎您的到来,并真诚的希望能与您合作!
睿美印象网络
返回上一页
客服QQ
点击这里给我发消息
客服QQ
点击这里给我发消息
一切从沟通开始……

HTML5版3D实验三:JavaScript玩转3D粒子系统

作者:睿美印象网站建设工作室  发布日期:2012-11-07
 

一.简介
这里所说的粒子系统,指得是大量的物体的聚集,我就把它叫做Particle Sytem。下面这个例子主要展示了物体的旋转运动,你应该可以看到一个大量分子(400个位置随机产生的星星)组成的旋转球体。

二.球体模拟
在三维笛卡尔坐标系当中,球心在原点(0,0,0)的球方程如下:

JavaScript Code复制内容到剪贴板
X2 +Y2+Z2=R2  
在模拟球体之前,我们先定义一个三维矢量,

JavaScript Code复制内容到剪贴板
Vector3 = function (x, y, z) {  
    this.x = x || 0;  
    this.y = y || 0;  
    this.z = z || 0;  
};  
 

 

利用上面的球方程,我们可以随机生成半径为250的球上面的240个点的坐标

JavaScript Code复制内容到剪贴板
var starPositions = [];  
                var j = -1;  
                for (var i = 0; i < 240; i++) {  
                    var xTemp = getRandomNumber(-250, 250);  
                    var yTemp = getRandomNumber(-250, 250);  
                    j *= -1;  
                    if (xTemp * xTemp + yTemp * yTemp <= r * r) {  
                        var zTemp = j * Math.sqrt(Math.abs(r * r - xTemp * xTemp - yTemp * yTemp));  
                        starPositions.push(new Vector3(xTemp, yTemp, zTemp));  
                    }  
                }  
三.投影
要想出现3D效果,我们要进行透视投影,本篇暂时用简单粗暴的转换方式。

以后利用齐次坐标技术来描述空间各点的坐标,用4*4的矩阵来解决空间各点的变换。

JavaScript Code复制内容到剪贴板
//集体投影  
function PositionsProjection() {  
    for (var i = 0; i < starPositions.length; i++) {  
        var tempV = projection(starPositions[i]);  
        starPositionsForShow.push(tempV);  
    }  
}  
//投影  
function projection(v) {  
    var v1=new Vector3();  
    v1.x = v.x * distance / Math.abs(cameraPosition.z - v.z);  
    v1.y = v.y * distance / Math.abs(cameraPosition.z - v.z);  
    v1.z = v.z;  
    return v1;  
}  
 

我们把投影之后的点都push进入另外一个数组用于显示。

然后我们根据这个数组,在每个点上挂上一颗星星。星星的x,y比例和透明度都根据摄像机或者点的Z坐标的位置决定。

 

这里用了easel.js,在以前已经提过。使用easel.js能够让Canvas编程更加OO,代码更加直观易懂。

JavaScript Code复制内容到剪贴板
for (var i = 0; i < starPositionsForShow.length; i++) {  
   
                        tempStar = new Bitmap("image/star.png");  
                        tempStar.x = centreOfCirclePosition.x + starPositionsForShow[i].x;  
                        tempStar.y = centreOfCirclePosition.x + starPositionsForShow[i].y;  
                        tempStar.scaleX = tempStar.scaleY = 0.5 * distance / Math.abs(cameraPosition.z - starPositionsForShow[i].z);  
                        if (starPositionsForShow[i].z > 50) tempStar.alpha = 1;  
                        if (starPositionsForShow[i].z < 50) tempStar.alpha = 0.5;  
                        stage.addChild(tempStar);  
                    }  
四.旋转(跟上篇一样)
JavaScript Code复制内容到剪贴板
//旋转  
          function rotate(angle) {  
        
              for (var i = 0; i < starPositions.length; i++) {  
                  var tempX = starPositions[i].x;  
                  var tempZ = starPositions[i].z;                     starPositions[i].x = starPositions[i].x * Math.cos(angle) - starPositions[i].z * Math.sin(angle);  
                  starPositions[i].z = starPositions[i].z * Math.cos(angle) + tempX * Math.sin(angle);  
              }  
          }  
五.旋转动画
由于是Jscex控,所以只要是动画我都交给Jscex了。

JavaScript Code复制内容到剪贴板
var roundAsync = eval(Jscex.compile("async", function () {  
   
               while (true) {  
                   stage.removeAllChildren();  
                   starPositionsForShow.length = 0;  
   
   
                   currentAngle += 0.0005;  
                   rotate(degToRad(currentAngle));  
                   PositionsProjection();  
   
                   for (var i = 0; i < starPositionsForShow.length; i++) {  
   
                       tempStar = new Bitmap("image/star.png");  
                       tempStar.x = centreOfCirclePosition.x + starPositionsForShow[i].x;  
                       tempStar.y = centreOfCirclePosition.x + starPositionsForShow[i].y;  
                       tempStar.scaleX = tempStar.scaleY = 0.5 * distance / Math.abs(cameraPosition.z - starPositionsForShow[i].z);  
                       if (starPositionsForShow[i].z > 50) tempStar.alpha = 1;  
                       if (starPositionsForShow[i].z < 50) tempStar.alpha = 0.5;  
                       stage.addChild(tempStar);  
                   }  
                   stage.update();  
   
                   $await(Jscex.Async.sleep(50));  
               }  
           }))  
 
六.完整代码及演示

  提示:可以修改后运行.
八.总结及预告
在3D编程的中,我们利用向量与矩阵的运算可以简化空间坐标变换的计算,比如求出某立方体绕任意轴旋转后的坐标,再比如计算旋转+缩放+切变+投影后的坐标变换,如果抛弃矩阵,将陷入大量的复杂计算当中。利用齐次坐标技术来描述空间各点的坐标,用4*4的矩阵来解决空间各点的变换,已经成了计算机图形学的一个标准。在以后,我们将利用和介绍3D编程利器----矩阵以及矩阵在计算机图形学中的应用!

转载请注明:睿美印象网站建设工作室www.ruimeiyx.com
分享到:
已有 0 条评论
暂无评论
睿美印象在线客服
客服部小睿:
点击这里给我发消息
设计部小美:
点击这里给我发消息
技术海绵哥:
点击这里给我发消息
在线淘客服:
睿美印象网络
淘客服小睿:
睿美印象小睿
淘客服小美:
睿美印象小美