【HTML5】三d实体模型

日期:2020-09-16 类型:科技新闻 

关键词:如何制作微信小程序,微信小程序源码,小程序码生成,凡科网微信小程序,微信公众号小程序

近期科学研究魔方的游戏玩法,就忽然想用HMTL5写1个魔方的实体模型,因为魔方是1个三d的立方体,这次就试着用HTML5写了1个简易的三d实体模型。

下面是预览画面。

制做步骤

最先你必须免费下载Html5开源系统库件lufylegend⑴.4.0

魔方分成6个面,每一个面由9个小矩形框构成,如今我把每一个小矩形框作为1个类封裝起来,

由于如今创建的是1个三d魔方,因此要画出每一个小矩形框,必须了解小矩形框的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是小矩形框的4个端点,angleX,angleZ各自是x轴和z轴转动的角度,color是小矩形框的色调。

魔方分成6个面,先看1下最前面的1面,假如以立方体的管理中心做为三d座标系的管理中心,那末9个小矩形框的各个定点所对应的座标以下图所示

因此,前面这个面的9个小矩形框能够由下面的编码来创建

for(var x=0;x<3;x++){  
    for(var y=0;y<3;y++){  
        z = 3;  
        var rect = new Rect([⑶*step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[-step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[-step + x*2*step,-step + y*2*step,⑶*step + z*2*step],[⑶*step + x*2*step,-step + y*2*step,⑶*step + z*2*step],0,0,"#FF0000");  
        backLayer.addChild(rect);  
    }  
}  

在其中backLayer是1个LSprite类,step是半个小矩形框的长,一样的道理,能够也获得别的5个面。

6个面都创建了,在绘图这6个面以前,最先要依据转动的角度来测算各个定点的座标,看下面的图

依据上面的图,用下面的公式便可获得转换后的定点座标

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];  
};  

最终依据小矩形框的4个定点座标,来绘图这个矩形框,

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类的1个方式,它能够依据传入的定点座标数字能量数组来绘图1个多边形。

最终,得出详细编码,编码非常少,JS编码1共91行。

1,index.html

<!DOCTYPE html>  
<html>  
<head>  
<meta charset="UTF⑻">  
<title>三d魔方</title>  
</head>  
<body>  
<div id="mylegend">loading……</div>  
<script type="text/javascript" src="../lufylegend⑴.4.0.min.js"></script>   
<script type="text/javascript" src="./Main.js"></script>   
<script type="text/javascript" src="./Rect.js"></script>   
</body>  
</html>  

2,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];  
};  

3,Main.js

init(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([⑶*step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[-step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[-step + x*2*step,-step + y*2*step,⑶*step + z*2*step],[⑶*step + x*2*step,-step + y*2*step,⑶*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([⑶*step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[-step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[-step + x*2*step,-step + y*2*step,⑶*step + z*2*step],[⑶*step + x*2*step,-step + y*2*step,⑶*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([⑶*step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[-step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[-step + x*2*step,⑶*step + y*2*step,-step + z*2*step],[⑶*step + x*2*step,⑶*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([⑶*step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[-step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[-step + x*2*step,⑶*step + y*2*step,-step + z*2*step],[⑶*step + x*2*step,⑶*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([⑶*step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[⑶*step + x*2*step,⑶*step + y*2*step,-step + z*2*step],[⑶*step + x*2*step,-step + y*2*step,-step + z*2*step],[⑶*step + x*2*step,-step + y*2*step,⑶*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([⑶*step + x*2*step,⑶*step + y*2*step,⑶*step + z*2*step],[⑶*step + x*2*step,⑶*step + y*2*step,-step + z*2*step],[⑶*step + x*2*step,-step + y*2*step,-step + z*2*step],[⑶*step + x*2*step,-step + y*2*step,⑶*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);  
   }  
}  

这只是1个十分简单的三d实体模型,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。