`
duoerbasilu
  • 浏览: 1479604 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

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

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

http://lufy.netne.net/lufylegend-js/lufylegend-1.4/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模型,多谢大家捧场。

分享到:
评论

相关推荐

    大、小断层矿井小波SVM融合智能故障预测matlab代码.zip

    1.版本:matlab2014/2019a/2021a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    垂直SeekBar(拖动条).zip

    android 源码学习. 资料部分来源于合法的互联网渠道收集和整理,供大家学习参考与交流。本人不对所涉及的版权问题或内容负法律责任。如有侵权,请通知本人删除。感谢CSDN官方提供大家交流的平台

    libADLMIDI1-1.5.0-bp153.1.1.x86-64.rpm

    libADLMIDI1-1.5.0-bp153.1.1.x86_64.rpm 是用于在 x86_64 架构的设备上安装的 RPM 包,具体功能如下: 名称:libADLMIDI1 版本:1.5.0 摘要:带有 OPL3 (YMF262) 模拟器的软件 MIDI 合成器库 许可证:GPL-3.0-only 和 LGPL-3.0-only 该库提供了一个基于 ADLMIDI 的软件 MIDI 合成器,它模拟了 OPL3 音源芯片(FM 合成)。它可以通过使用 ADLMIDI 库来实现多平台的 MIDI 播放和 OPL3 模拟。 该 RPM 包适用于 x86_64 架构,用于在相关设备上安装 libADLMIDI1 库文件。库文件包括: /usr/lib64/libADLMIDI.so.1 和 /usr/lib64/libADLMIDI.so.1.5.0:库文件 /usr/share/doc/packages/libADLMIDI1/AUTHORS、/usr/share/doc/packages/libADLMIDI1/README.md 等文档文件:文档文件

    基于qt+C++实现u盘插拔检测.+源码(毕业设计&课程设计&项目开发)

    基于qt+C++实现u盘插拔检测.+源码,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 基于qt+C++实现u盘插拔检测.+源码,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 基于qt+C++实现u盘插拔检测.+源码,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 基于qt+C++实现u盘插拔检测.+源码,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~

    Quectel_Product_Brochure_CN_V7.9.pdf

    Quectel_Product_Brochure_CN_V7.9.pdf

    更换软件主题(apk方式).zip

    android 源码学习. 资料部分来源于合法的互联网渠道收集和整理,供大家学习参考与交流。本人不对所涉及的版权问题或内容负法律责任。如有侵权,请通知本人删除。感谢CSDN官方提供大家交流的平台

    chepai-reg-main (2).zip

    phpstudy

    Python 入门详细教程-1天学会 Python.docx

    python入门

    二维码扫描的实现.zip

    android 源码学习. 资料部分来源于合法的互联网渠道收集和整理,供大家学习参考与交流。本人不对所涉及的版权问题或内容负法律责任。如有侵权,请通知本人删除。感谢CSDN官方提供大家交流的平台

    移动机器人机械臂的设计开题报告.doc

    移动机器人机械臂的设计开题报告.doc

    基于QT+C++开发的智能平台访客系统+源码

    用法链接:https://menghui666.blog.csdn.net/article/details/137977678?spm=1001.2014.3001.5502 基于QT+C++开发的智能平台访客系统+源码,包含主界面、系统设置、警情查询、调试帮助、用户退出功能。 基于QT+C++开发的智能平台访客系统+源码,包含主界面、系统设置、警情查询、调试帮助、用户退出功能。 基于QT+C++开发的智能平台访客系统+源码,包含主界面、系统设置、警情查询、调试帮助、用户退出功能。

    三菱机械臂校点说明.pptx

    三菱机械臂校点说明.pptx

    按字母索引滑动.zip

    android 源码学习. 资料部分来源于合法的互联网渠道收集和整理,供大家学习参考与交流。本人不对所涉及的版权问题或内容负法律责任。如有侵权,请通知本人删除。感谢CSDN官方提供大家交流的平台

    激光推送客户端demo.zip

    android 源码学习. 资料部分来源于合法的互联网渠道收集和整理,供大家学习参考与交流。本人不对所涉及的版权问题或内容负法律责任。如有侵权,请通知本人删除。感谢CSDN官方提供大家交流的平台

    c语言入门,小白进军C语言.zip

    C语言诞生于美国的贝尔实验室,由丹尼斯·里奇(Dennis MacAlistair Ritchie)以肯尼斯·蓝·汤普森(Kenneth Lane Thompson)设计的B语言为基础发展而来,在它的主体设计完成后,汤普森和里奇用它完全重写了UNIX,且随着UNIX的发展,c语言也得到了不断的完善。为了利于C语言的全面推广,许多专家学者和硬件厂商联合组成了C语言标准委员会,并在之后的1989年,诞生了第一个完备的C标准,简称“C89”,也就是“ANSI C”,截至2020年,最新的C语言标准为2018年6月发布的“C18”。 [5] C语言之所以命名为C,是因为C语言源自Ken Thompson发明的B语言,而B语言则源自BCPL语言。 1967年,剑桥大学的Martin Richards对CPL语言进行了简化,于是产生了BCPL(Basic Combined Programming Language)语言。

    Python入门到精通.zip

    python入门 单元测试和测试用例 Python标准库中的模块unittest提供了代码测试工具。 单元测试用于核实函数的某个防霾呢没有问题; 测试用例是一组单元测试,这些单元测试仪器一起核实函数在各种情形下的行为都符合要求。良好的测试用例考虑到了函数可能收到的各种收入,包含所有针对这些情形的测试。 全覆盖式测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。 对于大型项目,要实现全覆盖可能很难。通常,最初只要对针对代码的重要行为编写测试即可,等项目给广泛使用时再考虑全覆盖。 可通过的测试 创建测试用例的语法需要一段时间才能习惯,但测试用例创建后,再添加针对函数的单元测试就很简单了。要为函数编写测试用例,可先导入模块unittest以及要测试的函数,在创建一个继承unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。 下面test_name_function.py一个只包含一个方法的测试用例,它检查函数get_formatted_name()在给定名和姓时能否正确的工作。

    基于matlabbenders分解算法.zip

    基于matlabbenders分解算法.zip

    dsp工程设计讲座.ppt

    dsp工程设计讲座.ppt

    Adams空间复杂机械臂动力学仿真研究.doc

    Adams空间复杂机械臂动力学仿真研究.doc

    基于Android+OpenCV的车牌识别系统源码+使用文档+全部资料(优秀项目).zip

    【资源说明】 基于Android+OpenCV的车牌识别系统源码+使用文档+全部资料(优秀项目).zip基于Android+OpenCV的车牌识别系统源码+使用文档+全部资料(优秀项目).zip基于Android+OpenCV的车牌识别系统源码+使用文档+全部资料(优秀项目).zip 【备注】 1、该项目是个人高分毕业设计项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(如软件工程、计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

Global site tag (gtag.js) - Google Analytics