摘要:使用canvas实现可交互的3D魔方

一、简单分析

魔方物理性质:

1.中心块(6个):中心块与中心轴连接在一起,但可以顺着轴的方向自由的转动。

2.棱块(12个):棱块的表面是两个正方形,结构类似一个长方体从立方体的一个边凸出来。

3.角块(8个):角块的表面是三个正方形,结构类似一个小立方体从立方体的一个边凸出来,这样的结构可以让角块嵌在三个棱块之间。

4.可见方块(26个):魔方对于我们可见的方块有26块。

5.魔方六个面,每个面九个方块,转动时每个面绕着自己面的中心块旋转。

6.在观察魔方时,我们将整个魔方绕着三维空间中的某个点旋转

7.在人的视野范围内,魔方可见的部分只有三个面,19个方块。

二、实现方式

1)完成方块的旋转

  通过简略的类图,先了解一下实现的思路。在一个三维空间中,最基础的就是点(Vertex),点组成了面(Face),面组成了空间立方体(Cube)。魔方(MagicCube)由26个Cube组成,同时将26个Cube单组不重复的分为6组(MagicFace)。当旋转观察魔方时,26个Cube绕着魔方的中心旋转。当转动魔方的某一面时,MagicFace上所有的Cube围绕以原点为起点,面的中心为终点的矢量旋转。只需要掌握点在空间中的旋转,即可完成整个魔方的旋转。三维空间中点的旋转主要用到了数学上的旋转公式。关于如何将一个三维空间的立方体投影到平面并实现旋转请看我的上一篇随笔。

Canvas实现3D效果-可旋转的立方体

2)完成方块的上色
  第一步只是完成了一个透明魔方旋转。我们需要给魔方上色。初始化时为每个cube的face上色,我们不可见的面设置为白色。就像我们在现实中绘画一样,在canvas上绘制图像时后渲染的图像会把之前的覆盖掉,因此魔方的渲染顺序我们需要从后往前渲染。

  我们通过面的中心距离原点的Y值(本例以Y轴垂直与屏幕作为参考轴),来确定渲染顺序。单个方块的渲染如上图,6个面(*代表看不见的面),渲染顺序为1*,2*,3*,4,5,6,后渲染的面将前面渲染的面盖住。

  整个魔方的渲染,举例标了数字的三个方块,也是通过方块中点距离原点的Y值来确定渲染顺序。渲染顺序先是方块1,然后方块2把1的上半部分盖住,然后方块3把方块二的上半部分盖住。

3)完成鼠标的点击事件
  交互是本例中比较难的一个点,canvas 没有提供为其内部元素添加事件监听的方法,因此如果要使 canvas 内的元素能够响应事件,需要自己动手实现。通过获得鼠标在 canvas 上的坐标,计算当前坐标在哪些元素内部,然后对元素进行相应的操作。配合自定义事件,我们就可以实现为 canvas 内的元素添加事件监听的效果。

  在上图中,可旋转的面投影到二维平面的区域共有6个,图中只标识了三个。如何确定投影的区域呢?想了很多方法,最终采用了建立参考点的方法。

  1.获取到3个可视面MagicFace(F1F2F3)---6个面中中心Y值最大的3个

  2.获取到3个可视面无穷远的参考点(V1V2V3)--6个参考点中Y值最大的3个

  4.我们循环6个面,例如循环到图中的F2面,我们过滤离F2中心最近的参考点(过滤掉与F2中心空间距离最小的点),剩下V1V3

  5.获取到F2面中离V1最最近的三个方块(即上方红色区域的三个方块) -- 离参考点的空间距离

  6.获取三个方块中里F2这个面中点最远的4个点(即上方红色区域的4个顶点)

  通过3层循环,即可获取到所有可视面的投影。当我们鼠标点击并滑动一段距离时(图中黑点),我们就可以判断两个点所在的投影的位置是哪一个面的,获取到面之后就可以旋转那个面。

PS:我们通过建立参考点,6个无穷远的点(分别在X,Y,Z轴的正负方向上,魔方整体旋转时参考点也会旋转)。使用他与各个元素中点的距离用于判断一些特殊位置的点和面的方法。滑动部分的投影的8个点就是用参考点辅助求出的。

判断点是否在面中使用的是pnpoly算法   https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html

三、最终效果

PS:面积投影越小事件效果就不灵敏了,有待优化

源码下载:https://github.com/sincw/sinwProject/blob/master/webContent/src/main/webapp/work/magiccube/index.html

canvas实现3D魔方的更多相关文章

  1. css3之3D魔方动画(小白版)

      在这里分享一下3D魔方动画,html5+CSS3即可完成~无图无真相,先上效果图 第一步非常简单,就是先将魔方的结构画出来.大家都玩过魔方,知道魔方是一个有六个面的正方体.这里我们先写一个大的di ...

  2. Seen.js – 使用 SVG 或者 Canvas 渲染 3D 场景

    Seen.js 渲染3D场景为 SVG 或者 HTML5 画布.Seen.js 包含对于 SVG 和 HTML5 Canvas 元素的图形功能的最简单的抽象.所有这个库的其它组件都是不用关心将要渲染的 ...

  3. DirectX11--实现一个3D魔方(3)

    前言 (2019/1/9 09:23)上一章我们主要讲述了魔方的旋转,这个旋转真是有毒啊,搞完这个部分搭键鼠操作不到半天应该就可以搭完了吧... (2019/1/9 21:25)啊,真香 有人发这张图 ...

  4. DirectX11--实现一个3D魔方(2)

    前言 上一章我们主要讲述了魔方的构造和初始化.纹理的准备工作.目前我还没有打算讲Direct3D 11关于底层绘图的实现,因此接下来这一章的重点是魔方的旋转.因为我们要的是能玩的魔方游戏,而不是一个观 ...

  5. DirectX11--实现一个3D魔方(1)

    前言 可以说,魔方跟我的人生也有一定的联系. 在高中的学校接触到了魔方社,那时候的我虽然也能够还原魔方,可看到大神们总是可以非常快地还原,为此我也走上了学习高级公式CFOP的坑.当初学习的网站是在魔方 ...

  6. 如何用CSS3画出懂你的3D魔方?

    作者:首席填坑官∙苏南公众号:honeyBadger8,群:912594095,本文原创,著作权归作者所有,转载请注明原链接及出处. 前言 最近在写<每周动画点点系列>文章,上一期分享了& ...

  7. 用Canvas玩3D:点-线-面

    声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 玩Canvas玩了有两三个礼拜了,平面的东西玩来玩去也就那样,所以就开始折腾3D了. 因为Canvas画布终究还是平面的,所以要有3D就得 ...

  8. 基于 HTML5 Canvas 的 3D 模型贴图问题

    之前注意到的一个例子,但是一直没有沉下心来看这个例子到底有什么优点,总觉得就是一个 list 列表,也不知道右边的 3d 场景放两个节点是要干嘛,今天突然想起来就仔细地看了一下这个例子的代码,实际操作 ...

  9. 基于 HTML5 Canvas 的 3D 模型列表贴图

    少量图片对于我们赋值是没有什么难度,但是如果图片的量大的话,我们肯定希望能很直接地显示在界面上供我们使用,再就是排放的位置等等,这些都需要比较直观的操作,在实际应用中会让我们省很多力以及时间.下面这个 ...

随机推荐

  1. AngularJS进阶(十八)在AngularJS应用中集成科大讯飞语音输入功能

    在AngularJS应用中集成科大讯飞语音输入功能 注:请点击此处进行充电! 前言 根据项目需求,需要在首页搜索框中添加语音输入功能,考虑到科大讯飞语音业务的强大能力,遂决定使用科大讯飞语音输入第三方 ...

  2. 内核调试工具 — kdump & crash

    kdump简介 kdump是系统崩溃的时候,用来转储运行内存的一个工具. 系统一旦崩溃,内核就没法正常工作了,这个时候将由kdump提供一个用于捕获当前运行信息的内核, 该内核会将此时内存中的所有运行 ...

  3. Android绘图机制(一)——自定义View的基础属性和方法

    Android绘图机制(一)--自定义View的基础属性和方法 自定义View看起来,确实看起来高深莫测,很多Android开发都不是特别在行这一块,这里面的逻辑以及一些绘画都是有一点难的,说一下我目 ...

  4. myeclipse不编译

    错误: org.eclipse.core.internal.registry.configurationElementHandle cannot be cast to org.eclipse.jdt. ...

  5. Populating Next Right Pointers in Each Node(I and II)

    Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...

  6. subsets(子集)

    Given a set of distinct integers, nums, return all possible subsets (the power set). Note: The solut ...

  7. 关于MVC的特性(AuthorizeAttribute)的一些理解

    许多 Web 应用程序要求在用户登录之后才授予其对受限制内容的访问权限. 在某些应用程序中,即使是登录的用户,也会限制他们可以查看的内容或可以编辑的字段. 要限制对 ASP.NET MVC 视图的访问 ...

  8. Day7 面向对象和类的介绍

    面向对象讲解: ''' 面向过程: 核心是过程二字,过程指的是问题的解决步骤,基于过程去设计程序,就好比在设计一条流水线,是一种机械式的思维方式. 优点:复杂的问题流程化,进而简单化 缺点:可扩展性差 ...

  9. json.parseArray源码解析

    json.parseArray源码解析 public static <T> List<T> parseArray(String text, Class<T> cla ...

  10. 深度学习之 TensorFlow(二):TensorFlow 基础知识

    1.TensorFlow 系统架构: 分为设备层和网络层.数据操作层.图计算层.API 层.应用层.其中设备层和网络层.数据操作层.图计算层是 TensorFlow 的核心层. 2.TensorFlo ...