一.简介
这里所说的粒子系统,指得是大量的物体的聚集,我就把它叫做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