php三D立体模拟,【HTML5】3D模型--百行代码实现旋转立体魔方实例

最近研究魔方的玩法,就突然想用HMTL5写一个魔方的模型,由于魔方是一个3D的立方体,这次就试着用HTML5写了一个简单的3D模型。

下面是预览画面。

cfaaa617e07838e7f034bd46157d3d3e.png

制作流程

首先你需要下载Html5开源库件lufylegend-1.4.0

魔方分为6个面,每个面由9个小矩形组成,现在我把每个小矩形当做一个类封装起来,

因为现在建立的是一个3D魔方,所以要画出每个小矩形,需要知道小矩形的4个定点,而这4个定点会根据空间的旋转角度而变换,所以为了计算出这4个定点坐标,需要知道魔方绕x轴和z轴旋转的角度。

所以,建立矩形类如下

function Rect(pointA,pointB,pointC,pointD,angleX,angleZ,color){

base(this,LSprite,[]);

this.pointZ=[(pointA[0]+pointB[0]+pointC[0]+pointD[0])/4,(pointA[1]+pointB[1]+pointC[1]+pointD[1])/4,(pointA[2]+pointB[2]+pointC[2]+pointD[2])/4];

this.z = this.pointZ[2];

this.pointA=pointA,this.pointB=pointB,this.pointC=pointC,this.pointD=pointD,this.angleX=angleX,this.angleZ=angleZ,this.color=color;

}

Rect.prototype.setAngle = function(a,b){

this.angleX = a;

this.angleZ = b;

this.z=this.getPoint(this.pointZ)[2];

};

pointA,pointB,pointC,pointD是小矩形的四个顶点,angleX,angleZ分别是x轴和z轴旋转的角度,color是小矩形的颜色。

魔方分为6个面,先看一下最前面的一面,如果以立方体的中心作为3D坐标系的中心,那么9个小矩形的各个定点所对应的坐标如下图所示

ac9347dcbee92f453988996b78fd6fe7.png

所以,前面这个面的9个小矩形可以由下面的代码来建立for(var x=0;x<3;x++){

for(var y=0;y<3;y++){

z = 3;

var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],

[-step + x*2*step,-step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#FF0000");

backLayer.addChild(rect);

}

}

其中backLayer是一个LSprite类,step是半个小矩形的长,同样的道理,可以也得到其他5个面。

6个面都建立了,在绘制这6个面之前,首先要根据旋转的角度来计算各个定点的坐标,看下面的图

fe9f242db2dc0d994019868a52ec173c.png

根据上面的图,用下面的公式即可得到变换后的定点坐标Rect.prototype.getPoint = function(p){

var u2,v2,w2,u=p[0],v=p[1],w=p[2];

u2 = u * Math.cos(this.angleX) - v * Math.sin(this.angleX);

v2 = u * Math.sin(this.angleX) + v * Math.cos(this.angleX);

w2 = w;

u = u2; v = v2; w = w2;

u2 = u;

v2 = v * Math.cos(this.angleZ) - w * Math.sin(this.angleZ);

w2 = v * Math.sin(this.angleZ) + w * Math.cos(this.angleZ);

u = u2; v = v2; w = w2;

return [u2,v2,w2];

};

最后根据小矩形的四个定点坐标,来绘制这个矩形,Rect.prototype.draw = function(layer){

this.graphics.clear();

this.graphics.drawVertices(1,"#000000",[this.getPoint(this.pointA),this.getPoint(this.pointB),

this.getPoint(this.pointC),this.getPoint(this.pointD)],true,this.color);

};

其中drawVertices是lufylegend.js库件中LGraphics类的一个方法,它可以根据传入的定点坐标数组来绘制一个多边形。

最后,给出完整代码,代码很少,JS代码一共91行。

一,index.html

3D魔方

loading……

二,Rect类function Rect(pointA,pointB,pointC,pointD,angleX,angleZ,color){

base(this,LSprite,[]);

this.pointZ=[(pointA[0]+pointB[0]+pointC[0]+pointD[0])/4,(pointA[1]+pointB[1]+pointC[1]+pointD[1])/4,(pointA[2]+pointB[2]+pointC[2]+pointD[2])/4];

this.z = this.pointZ[2];

this.pointA=pointA,this.pointB=pointB,this.pointC=pointC,this.pointD=pointD,this.angleX=angleX,this.angleZ=angleZ,this.color=color;

}

Rect.prototype.draw = function(layer){

this.graphics.clear();

this.graphics.drawVertices(1,"#000000",[this.getPoint(this.pointA),this.getPoint(this.pointB),

this.getPoint(this.pointC),this.getPoint(this.pointD)],true,this.color);

};Rect.prototype.setAngle = function(a,b){

this.angleX = a;

this.angleZ = b;

this.z=this.getPoint(this.pointZ)[2];

};

Rect.prototype.getPoint = function(p){

var u2,v2,w2,u=p[0],v=p[1],w=p[2];

u2 = u * Math.cos(this.angleX) - v * Math.sin(this.angleX);

v2 = u * Math.sin(this.angleX) + v * Math.cos(this.angleX);

w2 = w;

u = u2; v = v2; w = w2;

u2 = u;

v2 = v * Math.cos(this.angleZ) - w * Math.sin(this.angleZ);

w2 = v * Math.sin(this.angleZ) + w * Math.cos(this.angleZ);

u = u2; v = v2; w = w2;

return [u2,v2,w2];

};

三,Main.jsinit(50,"mylegend",400,400,main);

var a = 0,b=0,backLayer,step = 20,key = null;

function main(){

backLayer = new LSprite();

addChild(backLayer);

backLayer.x = 120,backLayer.y = 120;

//后

for(var x=0;x<3;x++){

for(var y=0;y<3;y++){

z = 0;

var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],

[-step + x*2*step,-step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#FF4500");

backLayer.addChild(rect);

}

}

//前

for(var x=0;x<3;x++){

for(var y=0;y<3;y++){

z = 3;

var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],

[-step + x*2*step,-step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#FF0000");

backLayer.addChild(rect);

}

}

//上

for(var x=0;x<3;x++){

for(var z=0;z<3;z++){

y = 0;

var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],

[-step + x*2*step,-3*step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step],0,0,"#FFFFFF");

backLayer.addChild(rect);

}

}

//下

for(var x=0;x<3;x++){

for(var z=0;z<3;z++){

y = 3;

var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],

[-step + x*2*step,-3*step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step],0,0,"#FFFF00");

backLayer.addChild(rect);

}

}

//左

for(var y=0;y<3;y++){

for(var z=0;z<3;z++){

x = 0;

var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step],

[-3*step + x*2*step,-step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#008000");

backLayer.addChild(rect);

}

}

//右

for(var y=0;y<3;y++){

for(var z=0;z<3;z++){

x = 3;

var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step],

[-3*step + x*2*step,-step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#0000FF");

backLayer.addChild(rect);

}

}

backLayer.addEventListener(LEvent.ENTER_FRAME,onframe);

}

function onframe(){

a += 0.1 , b += 0.1;

backLayer.childList = backLayer.childList.sort(function(a,b){return a.z - b.z;});

for(key in backLayer.childList){

backLayer.childList[key].setAngle(a,b);

backLayer.childList[key].draw(backLayer);

}

}

以上就是【HTML5】3D模型--百行代码实现旋转立体魔方实例 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值