• 嗨!这里是蜜糖~~
    • 操作方法
    • 简单说明
    • 代码文件
      • 源代码文件
  • 总结
    • 视频

嗨!这里是蜜糖~~

蜜糖相信很多人在学生时期应该都玩过魔方,上大学或者工作之后却玩的很少了,所以今天蜜糖就给大家带来一款与众不同的魔方——代码版魔方,有电脑就能玩~莱茨狗

看到这个你是不是心动了呢,不要急,因为代码比较多,所以我就不贴出来了,结尾放了文件,感兴趣的小伙伴可以自行下载研究,蜜糖这里给大家简单的讲解一下,方便大家理解。
文字有点难以理解,可以根据代码来进行学习~

操作方法

1.鼠标左键拖动能观察不同角度下的魔方。

2.鼠标右键拖动能拧动魔方。

简单说明

这个程序主要讲如何判断哪些面是要展示出来的以及如何判断点在哪个面的哪个小平面上,以及旋转时的逻辑。

要判断哪些面是要展示出来的,就需要投影面的法向量 m 和每个面的法向量 n,若 m * n 为负数,说明这两个向量夹角为钝角,也就是不用展示出来,反之就要展示出来。

数学基础就这么两句话,但是要用代码实现出来得有几十行,这里我将魔方 8 个顶点固定住,6 个面的法向量也是固定的,略一计算,我们只需要根据投影面的法向量的 x,y,z 值的正负就能判断 6 个面中哪些面是要展示出来的。

这里判断正负要注意,c 语言中的浮点数无法表示 0,最接近 0 的浮点数是 2^(-128),因此浮点数的 0 会比 0 略大或者略小,我这里用一个宏 ZERO 表示 0,只要浮点数比这个宏大就是大于 0。

同时在透视投影中,当观察点没有倾斜一定角度无法看到侧面,这个倾斜的角度的 cos 值为魔方边长的一半除以观察点到投影面的距离。

也就是当观察点在某一个平面上,就只能看到距离最近的两个点形成的直线,看不到这个平面上的其他点。这时候 ZERO 值就表示能看到侧面的最小 cos 值。
判断点在哪个面的哪个小平面上需要建一个模型,不然你不知道一个平面的起点在哪里,也就不能判断每个小平面的位置。

魔方的 8 个顶点中,头四个表示底部,尾四个表示顶部,逆时针挨个排序,在空间直角坐标系中,魔方中心点为原点,x 轴正方向为右边平面的法向量,也就是 Right 表示的平面,y 轴正方向为后面平面的法向量,也就是 Back 表示的平面,z 轴正方向为上平面的法向量,也就是 Up 平面。用 8 个顶点来表示平面为:

前面(Front):0、1、5、4

后面(Back):3、2、6、7

左面(Left):0、3、7、4

右面(Right):1、2、6、5

上面(Up):4、5、6、7

下面(Down):0、1、2、3

判断时先根据投影面得到每个魔方面的二维点值,对于魔方面的每个角,可以连接顶点与点中的地方构成一个二维向量 i,再从这个顶点往两边做两个二维向量求这两个二维向量与 i 的夹角余弦值,余弦值可以表示 180 度以内的角的大小,若这两个余弦值有一个比两边向量夹角的余弦值要小,说明点中的点与某条边所形成的夹角比这个顶点的夹角要大,也就是点在平面外。对任意多边形都可以用这个方法判断点是否在平面内,判断次数为多边形顶点的个数。

判断完点是否在平面内后判断在该平面的位置,每个平面的起点上面已经给出,根据每个平面的起点与点中的位置构成一个向量,起点与两边的向量的 1/3 长度为横纵坐标单位向量。

这里做个简单的数学计算,a,b 是两个不平行的二维向量,m、n 为常数,m * a + n * b = c,c 为点中的位置与起点构成的二维向量,求出 m、n 就能得到点在平面内的位置。这方法只对平行投影有效,透视投影则将一个面的横纵方向各分为三个平面,判断点在第 m 个横平面的第 n 个纵平面,根据 m,n 值求出点在平面上的坐标。

旋转时的逻辑比以上两个都要复杂,我的做法是用一个数组保存六个面的颜色,旋转时先画出旋转时的效果,旋转结束后改变颜色数组。

代码文件

头文件及宏定义

#include <iostream>
#include <graphics.h>
#include <math.h>
#define WIDTH 640                       // 窗口宽度
#define HEIGHT 480                      // 窗口高度
#define PI 3.14159265                   // π
#define SIDE (min(WIDTH, HEIGHT) / 4)   // 正方体边长
#define GAMEPAD (SIDE / 2)              // 手柄,控制面旋转幅度的量
#define ZERO 0.1                // 对于浮点数来说的 0 值
#define PIECE 180                       // 将一个 π 分为 PIECE 份
COLORREF DifferentColor = RGB(193, 181, 62);

源代码文件

  • 链接:https://pan.baidu.com/s/1QNYjOjRRPQmZF1srOF3VOQ?pwd
  • 提取码:dkjy

总结

好了,大家尽情玩耍,可能会有一点点难度,但是蜜糖相信对学编程的你们来说都是小菜一碟,大家都可以尝试研究一下,说不定还能发现新大陆,希望大家可以得到自己想要的知识以及快乐,也希望大家可以给蜜糖一个关注,非常感谢大家!!!

视频

还有一个视频版本,希望给予一点小小的赞,鞠躬~!@#@!!
视频入口:https://www.bilib1500行代码实现一个魔方,学会之后以后买魔方都省了!

后续蜜糖还会发布更多的项目源码以及学习资料,希望大家可以持续关注,有什么问题可以回帖留言,我尽量回答。
需要C/C++学习资料以及其他项目的源码的可以加粉丝裙下载【706913185】。想要了解程序员未来的发展有兴趣的也可加群闲聊。希望和大家一起共同学习进步!!!

【魔方代码】1200行C语言代码实现“魔方”程序,学会它买魔方的钱都省了,拿走不谢~相关推荐

  1. 将python代码转化为c语言代码,提高运行效率

    将python代码转化为c语言代码,提高运行效率 首先,需要安装cpython库: pip install cython 安装完成之后,写一段简单的代码,例如下面这个利用递归求斐波那契数列的函数,然后 ...

  2. Golang cgo:如何在Go代码中调用C语言代码?

    如何在Go代码中调用C语言代码? Go语言是通过自带的一个叫CGO的工具来支持C语言函数调用,同时我们可以用Go语言导出C动态库接口给其它语言使用. 方式一.直接在 Go 代码中写入 C 代码 检查是 ...

  3. 牛逼c语言代码,这段c语言代码牛逼在哪?

    原标题:这段c语言代码牛逼在哪? 有人说C语言是世界上最牛逼的语言,因为操作系统就是用C语言编写的,学好了C才能更好的学习其他编程语言.为此,有人分享了下面一段代码,说是很牛逼的c语言代码,看得W3C ...

  4. java玫瑰花代码_玫瑰花c语言代码

    玫瑰花 c 语言代码 #include <dos.h> #include <graphics.h> #include <math.h> /* 玫瑰花 */ #def ...

  5. rsa2048加密算法c语言代码,rsa加密算法c语言代码

    如何用C语言实现RSA算法? 上学期交的作业,已通过老师在运行时间上的测试 #include #include unsigned long prime1,prime2,ee; unsigned lon ...

  6. html语言代码游戏,常用html语言代码

    大标题代码: A part of me 透明flash特效代码: 加入背景音乐代码: type=audio/x-ms-wma LOOP="TRUE" AUTOSTART=" ...

  7. 用200行C语言代码写出一个贪吃蛇——1.0(基本版)

    1.设计思路 总的来说,贪吃蛇这个小游戏涉及到的东西不多,但是对逻辑思维是比较吃基本功的. 贪吃蛇,显示给我们看的有三部分:蛇.食物.地图边界. 我们可以用一个二维数组来标记这些部分: 例如这里我创建 ...

  8. c语言查看cpu温度代码_树莓派学习笔记——短短几行C语言代码获取树莓派的CPU温度...

     玩转树莓派 标签: 树莓派CPU温度 前言 本文通过文件操作读取树莓派CPU温度,在linux系统中任何设备的操作都被抽象成为文件读写,通过读取/sys/class/thermal/thermal_ ...

  9. 300行C语言代码搞定坦克大战游戏,看完我是佩服的五体投地!

    想当年小编的暑假除了做作业外,最重要的就是玩说起80.90后的童年那真是相当精彩!虽然没有现在这么高科技的iPad.XBOX ONE.PS4...但那时候也有很多很好玩的游戏机!陪伴我们不断的长大. ...

  10. r语言dataellipse_几行R语言代码搞定菌群与环境因子或临床指标相关性的可视化...

    相关性分析是生物信息学中常用的分析方法,可以用来分析菌群与菌群的关联,菌群与因子的关联等等.本文使用R语言内置函数cor()计算变量之间的相关系数,并用corrplot包进行可视化.(本文测试数据为R ...

最新文章

  1. 从原理到实操,看当前最佳的YOLO V4是如何炼成的?
  2. altium designer PCB把板子翻过来看
  3. 思科中国创新中心总部正式落户广州
  4. Java的List转Scala的数组
  5. 如何连接两个窗口JAVA_java-如何连接两个ArrayLists?
  6. VTK:绘图之FunctionalBagPlot
  7. maven中pom文件解析
  8. can‘t resolve symbol xxx
  9. kodi android设置中文,Kodi(原XBMC)
  10. 网络时延——发送时延和传播时延
  11. c语言逆波兰计算器程序,C语言实现的简单的逆波兰计算器
  12. linux 修改用户登录密码
  13. SQL Server Denali:SSDT新功能解读
  14. Spring boot--控制器增强
  15. 2013级C++第2周(春)项目——结构体应用大体验
  16. RPM 包的构建 - SPEC 基础知识
  17. 我与鸟哥 Yar 的亲密接触
  18. 悉尼mit it硕士选课 INFO5990
  19. 宏录制流程——例:生成工资条
  20. python 多线程实现多任务,多进程实行多任务

热门文章

  1. 【12月英语博客】念念不忘,必有回响
  2. Java8 - 使用 Comparator.comparing 进行排序
  3. 1816. 截断句子【我亦无他唯手熟尔】
  4. node重绘图片_使用nodejs生成图片的尝试
  5. 《生命》第五集:Birds (鸟类)
  6. 用 HTML 做一个表单模板
  7. maven的资源过滤filters
  8. 我在美团Android研发岗工作的那5年,终局之战
  9. Renew 、Revive 、Renovate、Update、Refresh区别
  10. Gson解析遇到的异常分析与记录