百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 软件资讯 > 正文

RubikFX:用JavaFX 3D解决魔方难题(1)

ninehua 2025-03-05 19:53 71 浏览

自从上一次出版到现在已经有一段时间了。但是其间,三次重要的会议让我远离了博客。我对自己说,针对我说过的题目,我必须写博客,但是我根本没有机会。

现在,离JavaOne发布还比较遥远,而且我已完成我的新书 《JavaFX8,Introduction by Example》,该书与我的朋友Carl Dea, Gerrit Grunwald, Mark Heckler and Sean Phillips共同编写完成,很快就会印刷出版。我有机会使用Java 8和JavaFX 3D几个星期,这篇文章就是我探索的结果。

很偶然我的孩子最近在家摆弄魔方,为了感谢源自David Gilday的这个令人惊讶的项目,我们建立一个乐高头脑风暴EV3处理机器人,David Gilday在CubeStormer3中最快复原了魔方,EV3见下图。



图一

在我玩魔方一段时间后,我在考虑创建JavaFX应用程序解决魔方难题的可行性,以及RubikFX如何诞生的问题。如果你急切地想了解RubikFX是怎么一回事,以下YouTube上的视频将向你展示大部分内容。
https://www.youtube.com/watch?v=ZVPIBkDgZV4

总体上讲,在这篇文章中我将讨论在一个Scene中导入3D模型,使用放大、旋转、缩放的功能,加入光线,移动摄像头等等。一旦我们有一个非常好的3D魔方模型,我们将努力找到一种独立于模型剩下的部分方式,移动模型层块,保留变化的轨迹。最后,我们将加入通过鼠标点击,选择面、转动层块。

如果你不熟悉魔方的概念和复原它的基本步骤,请阅读以下内容。

在我们开始以前

你也许知道Java8已经在3月18日发布了,所以本项目的代码是基于这个版本的。如果你还没有Java8,请下载新的SDK更新你的系统。我采用NetBeans8.0开发本项目,它支持lambdas表达式和新的Stream API。你可以从以下链接更新你的IDE。地址:
https://netbeans.org/downloads/

我使用了2个独立的构件,一个用来导入模型,它是OpenJFX项目的一部分,来源于一个实验性的项目3DViewer。我们需要下载和编译它。另一个来源于ControlsFX项目,它可以为应用程序添加酷炫的对话框。

下载地址:
http://fxexperience.com/downloads/controlsfx-8.0.5.zip

最后,我们的项目需要一个3D模型,你可以自己建立一个或者使用一个免费的,你可以从下面的地址下载,采用3ds或者OBJ的格式下载。

地址如下:

http://tf3dm.com/3d-model/rubik39s-cube-79189.html

(原作者提供的下载地址,据我尝试,该文件不能下载了。但是完整版的资源文件中,已经有这个3D模型了)

一旦你得到所有的组件,你可以很容易地得到这张图片。

用3DViewer程序打开3D模型



图二

解压文件,将‘Rubik's Cube.mtl'重命名为‘Cube.mtl',将'Rubik's Cube.obj'重命名为'Cube.obj',编辑该文件将第三行改为‘mtllib Cube.mtl',(用文本编辑器打开)然后保存。运行3DViewer应用程序,将'Cube.obj'拖到viewer中。打开设置面板,选择灯光,打开白色环境光源,关掉puntual(好像是拼错了)光源。你可以放大或者缩小(使用鼠标滚轮、右击、导航条)。旋转魔方用左键(编辑旋转速度用CTRL或者SHIFT),或者用鼠标按键全部按下。

选择Options面板,点击Wireframe,你可以看到建造模型的三角面块。



图三

27个立方体中的每一个都在OBJ文件中给予了一个名称,类似‘Block46’等。所有的三角面块都被集合在一起,且赋予了材质,每个立方体由1到6个面块组成,名字类似‘Block46', ‘Block46 (2)',总共有117个面块。


The color of each cubie meshes is asigned in the 'Cube.mtl' file with the Kd constant relative to the diffuse color.


每个面块的颜色都包含在'Cube.mtl'文件中,漫反射颜色也包含其中。

魔方—精简版

输入3D模型


当我们了解了我们的模型是怎么回事,我们就需要为面块(MeshView)建造节点了(Node)了。3DViewer中的ObjImporter类提供了getMeshes()方法,返回每个面块的名字。我们定义一个HashMap为每个MeshView绑定一个名字,针对每个面块的名字,我们用bulidMeshView(s)方法得到一个MeshView对象。

在设计时,模型中立方体的材质并不反射光线,我们修改它,允许它和Puntual光线交互,通过定义它为PhongMaterial类,编辑材质的特殊粒子属性。


最后,我们将旋转初始魔方,让白色面朝上,蓝色面朝前。

public class Model3D {
          
          /* Cube.obj contains 117 meshes, marked as "Block46",...,"Block72 (6)" in this set: 
          Cube.obj包含117个mesh面,标识为“Block46”、“Block72 (6)”
*/
          private Set meshes;
 
          /* HashMap to store a MeshView of each mesh with its key */
          /*哈希表用键值对存储MeshView*/
          private final Map mapMeshes=new HashMap<>();
          
          public void importObj(){
                    try {// cube.obj
                               ObjImporter reader = new ObjImporter(getClass().getResource("Cube.obj").toExternalForm());
                               meshes=reader.getMeshes(); // set with the names of 117 meshes
//得到117mesh面
                                                     
                               Affine affineIni=new Affine();                     
                               affineIni.prepend(new Rotate(-90, Rotate.X_AXIS));
                               affineIni.prepend(new Rotate(90, Rotate.Z_AXIS));
                               meshes.stream().forEach(s-> { 
                                         MeshView cubiePart = reader.buildMeshView(s);
                                         // every part of the cubie is transformed with both rotations:
//魔方的每个部分都要一起变化
                                         cubiePart.getTransforms().add(affineIni); 
                                         // since the model has Ns=0 it doesn't reflect light, so we change it to 1
//当NS=0,它不反射光线,我们将它置为1
                                         PhongMaterial material = (PhongMaterial) cubiePart.getMaterial();
                                         material.setSpecularPower(1);
                                         cubiePart.setMaterial(material);
                                         // finally, add the name of the part and the cubie part to the hashMap:
//最后,将魔方每一部份的名字加入hashMap中。
                                         mapMeshes.put(s,cubiePart); 
                               });
                    } catch (IOException e) {
                               System.out.println("Error loading model "+e.toString());
                    }
          }
          public Map getMapMeshes() {
                    return mapMeshes;
          }
}

模型导入后自身是白色面朝右(X轴)红色面朝前(Z轴),这就要求2次旋转。

第一次绕X轴旋转-90度,把蓝色面置前,然后绕Z轴旋转90度把白色面置顶。


(魔方的初始状态是白色面朝上,蓝色面朝前)


数学计算上(矩阵运算),第二次绕Z轴旋转的矩阵必须在左边乘以第一次绕X轴旋转的矩阵。但是按照如下情况,如果我们使用add或者append方法在右侧操作,将产生错误。

链接地址:
http://hg.openjdk.java.net/openjfx/8/master/rt/file/f89b7dc932af/modules/graphics/src/main/java/javafx/scene/transform/Affine.java

cubiePart.getTransforms().addAll(new Rotate(-90, Rotate.X_AXIS),new Rotate(90, Rotate.Z_AXIS));
cubiePart.getTransforms().addAll(new Rotate(90, Rotate.Z_AXIS),new Rotate(-90, Rotate.X_AXIS));

如果我们先在Z轴旋转,然后在X轴旋转,把红色面置顶黄色面置前,也会产生错误。

尽管进行右侧旋转,将需要次数更多地旋转,使魔方恢复到初始状态,这也比旋转脱离最后状态更加复杂。

所以prepend是正确可行的方法,我们需要采取把最后一次旋转的矩阵记录到Affine矩阵中,而且Affine矩阵中记录所有之前的旋转状态。


相关推荐

我常用的三个剪辑工具 免费功能强大 剪辑视频不再求人

今天特意写这篇文章分享一下我在用的三个视频剪辑工具,这三个免费,好用,功能强大,包含了我常用的手机上剪辑的视频软件,电脑端剪辑视频的软件。为什么要写这篇文章呢,还得从早上被一些垃圾剪辑软件给套路了,所...

macOS绝美流动壁纸!如何免费下载和制作?

大家好,我是dairy。我们都曾见识过Apple产品壁纸的惊艳,无论是macOS还是iOS设备壁纸,每更新一版系统版本,就会带来一波新的超美作品。从macOSMojave10.14开始,Mac系统...

适用于Windows和Mac的10款最佳照片恢复软件(免费&amp;付费)

丢失了您的珍贵照片?让我们看看最好的免费和付费照片恢复软件,用于在Windows和Mac上恢复它们。添加图片注释,不超过140字(可选)丢失照片很容易。一个错误的点击,一个贴错标签的SD卡,然...

Typora开始收费,介绍几款免费的MarkDown编辑器

前两天,一场突如其来的新闻,让本来就不富裕的TJ君更是雪上加霜。什么事情呢?Typora,大家一定都在用吧,作为一款主打免费旗号的Markdown编辑器,Typora一直是很多小伙伴的常备工具之一,...

Mac端想找一个免费好用的视频播放器?不妨看看IINA

今天为大家带来的是一款macOS系统下的视频播放软件介绍,它便是IINA,初识这个软件的时候它应该还刚刚上架GitHub,那时候我用的比较多的Mac端视频播放软件还是VLC。其实对于这类软件,相信大部...

CotEditor - 免费开源好软件推荐!macOS 上轻量好用的纯文本编辑器

mac上一款免费好用的纯文本编辑器,平时看看文档,可以满足类似notepad++这样的工具需求。关于CotEditorCotEditor是一款运行在mac电脑上的轻量级、简洁但功能强大的...

坚果云 for Mac(网盘工具)中文免费版

推荐一款国内很受欢迎的网盘工具,坚果云forMac提供文件自动同步、数据备份、文件共享、文件搜索、下载、文件自动锁定等实用的功能,让你管理文件更加便捷,而且坚果云网盘支持与手机、平板、网页等设备互...

微软发布Mac版Office 2016测试版:免费试用

微软发布Mac版Office2016测试版:免费试用新浪手机讯3月6日上午消息,微软公司今日发布适用于苹果Mac电脑的Offic办公套装软件,目前是预览版,用户下载后可免费试用60天。从命名就可...

《极限竞速:地平线5》下月登陆PS5,实体版缺失引担忧

IT之家3月3日消息,《极限竞速:地平线5》将于4月25日登陆PlayStation5平台,但此次发行将仅以数字版形式推出。游戏开发商PlaygroundGames在X...

PS5《控制:终极版》新增扩充内容和次世代增强视觉功能

GameSourceEntertainment(GSE)宣布,《控制:终极版》已于2月2日以PSN数位版形式登陆PlayStation(R)5平台,而PS5TM《Control》终极版的盒装...

PS修图插件-DR5高级版人像精修神器重磅来袭

设计筱柒设计资源分享10-14无偿领取提示:1、评论随意评论:各抒己见2、学习领取课件私信设计筱柒:想学每天最新的优质资源不容错过哦今天的内容希望可以帮到你~2021最新DR5白金版高级PS扩...

蛐蛐下AI 运行photoshop 脚本的失败经历

正好最近有图片批处理需求~针对AI结合各种软件提升工作效率的第一个尝试~在成功使用deepseek+豆包+kimi=pptdeepseek+vscode代码助手(自动写代码,原项目自带验证和热启...

PS5赚疯了!索尼一台主机碾压四代总和,玩家:钱都去哪儿了?

阅读之前,麻烦用你发财的小手点点创作不易,感谢大家的支持!每日更新最近,索尼PS5的赚钱能力直接炸裂!数据显示,PS5自2020年发售以来,利润已经突破130亿美元,直接超过了PS1、PS2、PS3、...

PS Plus PS5会免及Collection免费阵容公开

PlayStation公开了11月欧美服PS+会免游戏阵容,PS5游戏《虫子快餐店》首发即加入会免,可在2020年11月12日至2021年1月4日期间领取。除了《虫子快餐店》之外,《中土世界战争之影...

开源 Windows 和 Office 激活器, 无需部署直接使用。

更多内容请关注我的微信公众号:VistaHub上周写了一篇永久激活Windows和Office的文章,但是需要使用NAS进行部署,给本就门槛不低的激活操作,又增加了不小的难度。今天我发现了一...