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

原创 2012年06月12日 01:42:35

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

下面是测试链接和预览画面。

http://lufylegend.com/demo/Rubik/index.html



制作流程

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

http://blog.csdn.net/lufy_legend/article/details/7644932


魔方分为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个小矩形的各个定点所对应的坐标如下图所示


所以,前面这个面的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个面之前,首先要根据旋转的角度来计算各个定点的坐标,看下面的图


根据上面的图,用下面的公式即可得到变换后的定点坐标

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>3D魔方</title>
</head>
<body>
<div id="mylegend">loading……</div>
<script type="text/javascript" src="../lufylegend-1.4.0.min.js"></script> 
<script type="text/javascript" src="./Main.js"></script> 
<script type="text/javascript" src="./Rect.js"></script> 
</body>
</html>
二,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.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([-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);
   }
}

这只是一个非常简陋的3D模型,多谢大家捧场。

Three.js之新手初学——构建魔方

Three.js之新手初学——构建魔方本人新手,第一次写blog。高手轻喷,新手共勉。效果展示例子:http://llwmj.tk/threejs/cube/groupcube/ Three.js入...
  • ll19930120
  • ll19930120
  • 2015年04月10日 19:20
  • 4110

js 实现一个非常漂亮的3D立体旋转效果h5

在线预览地址http://60.205.182.245:3000/rotating-3d/index.html (chrome 手机模式,或用手机浏览) github地址:https://githu...
  • qq_30456713
  • qq_30456713
  • 2018年01月08日 10:48
  • 465

Three.js快速入门

引言本文主要是讲解Three.js的相关概念,帮助读者对Three.js以及相关知识形成比较完整的理解,达到快速入门的目的。...
  • lijunfan1994
  • lijunfan1994
  • 2016年09月02日 11:48
  • 7539

2016 年谷歌开源了这些超酷炫的项目

2016 年谷歌开源了这些超酷炫的项目  收藏 两味真火   发表于 1周前 阅读 11154 收藏 184 点赞 13 评论 12 摘要: 人工智能可以可以创作艺术和谱写曲子...
  • zzwu
  • zzwu
  • 2016年12月28日 19:38
  • 1794

HTML魔方

*{ margin: 0; padding: 0; } #box{ width: 300px; ...
  • zhang_xiansen
  • zhang_xiansen
  • 2017年03月31日 01:15
  • 254

如何用CSS3+HTML5绘制一个3x3的3D魔方?

CSS3真的很强大,不仅能实现动画,还能绘制2D、3D图形。主流浏览器FIrefox、Chrome、Opera、Safari都能支持,遗憾的是市场占有率仍然很高的IE浏览器却无法支持。具体可查看CSS...
  • luojiandecsdn
  • luojiandecsdn
  • 2016年01月21日 12:06
  • 2671

HTML5 CSS3 : 3D立方体旋转动画实例源码

  • 2014年07月12日 09:58
  • 171KB
  • 下载

HTML5 WebGL Three.js 加载 3D模型文件

本文主要介绍一下如何使用Three.js框架加载本地的3D模型文件,有关于Three.js和WebGL的具体知识请参考http://www.khronos.org/webgl/ 在页面中,我们利用...
  • ForeverCjl
  • ForeverCjl
  • 2013年10月10日 13:02
  • 20061

HTML5+WEBGL+PHP实现3D模型

参考网站:http://www.mohou.com/moxingku 使用php操作stl文件,将3D模型文件stl上传,到HTML5来展示,并且发送请求打印模型...
  • stary1
  • stary1
  • 2017年07月13日 15:41
  • 741

基于 HTML5 的 WebGL 技术构建 3D 场景(一)

HT for Web 提供了多种基础类型供用户建模使用,不同于传统的 3D 建模方式,HT 的建模核心都是基于 API 的接口方式,通过 HT 预定义的图元类型和参数接口,进行设置达到三维模型的构建。...
  • u013161495
  • u013161495
  • 2016年07月13日 00:51
  • 5814
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【HTML5】3D模型--百行代码实现旋转立体魔方
举报原因:
原因补充:

(最多只允许输入30个字)