当前位置: 首页 > news >正文

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

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

嗨!这里是蜜糖~~

蜜糖相信很多人在学生时期应该都玩过魔方,上大学或者工作之后却玩的很少了,所以今天蜜糖就给大家带来一款与众不同的魔方——代码版魔方,有电脑就能玩~莱茨狗
在这里插入图片描述
看到这个你是不是心动了呢,不要急,因为代码比较多,所以我就不贴出来了,结尾放了文件,感兴趣的小伙伴可以自行下载研究,蜜糖这里给大家简单的讲解一下,方便大家理解。
文字有点难以理解,可以根据代码来进行学习~

操作方法

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】。想要了解程序员未来的发展有兴趣的也可加群闲聊。希望和大家一起共同学习进步!!!
在这里插入图片描述

相关文章:

  • 4、乐趣国学—“满招损,谦受益。”
  • 商城项目07_网关工程初步搭建、商品分类树状结构展示、网关配置、解决跨域问题
  • 【Python刷题篇】——Python入门 09 字典(下)
  • MySQL-查询数据库(二)
  • 《安富莱嵌入式周报》第281期:Keil Studio发布VSCode插件,微软嵌入式IDE升级,开源穿戴手表,CAN XL汽车单片机,USB4 V2.0规范
  • 【数据挖掘】pandas使用手册
  • 图像处理技术的综合应用——提取篮球
  • 2021 第四届 浙江省大学生网络与信息安全竞赛技能赛 预赛 Writeup,4题
  • 【MCAL_CANDriver】-1.2-Can Mailbox邮箱,Hardware Object,HOH,HRH,HTH之间的关系
  • 【零基础学QT】第七章 网络通信,TCP、UDP通信实验
  • 一次解释器模式的实际使用
  • C++入门·收尾
  • 25.CF992E Nastya and King-Shamans 转化+线段树二分
  • 快来带您了解中秋节的前世今生
  • 分布式锁之防止超卖 --mysql原子操作,乐观锁,redis事务,乐观锁
  • Angular数据绑定机制
  • egg(89)--egg之redis的发布和订阅
  • Linux各目录及每个目录的详细介绍
  • mysql 数据库四种事务隔离级别
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • pdf文件如何在线转换为jpg图片
  • React的组件模式
  • webgl (原生)基础入门指南【一】
  • 对超线程几个不同角度的解释
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 排序算法学习笔记
  • 通信类
  • 原生 js 实现移动端 Touch 滑动反弹
  • 找一份好的前端工作,起点很重要
  • 《天龙八部3D》Unity技术方案揭秘
  • Hibernate主键生成策略及选择
  • 国内开源镜像站点
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​HTTP与HTTPS:网络通信的安全卫士
  • #define MODIFY_REG(REG, CLEARMASK, SETMASK)
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (C语言)球球大作战
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (搬运以学习)flask 上下文的实现
  • (补)B+树一些思想
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (一)Thymeleaf用法——Thymeleaf简介
  • ******之网络***——物理***
  • .NET Core Web APi类库如何内嵌运行?
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET MVC、 WebAPI、 WebService【ws】、NVVM、WCF、Remoting
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @Async注解的坑,小心
  • @zabbix数据库历史与趋势数据占用优化(mysql存储查询)
  • []新浪博客如何插入代码(其他博客应该也可以)
  • [asp.net core]project.json(2)