第 2 次大作业进展报告
2/28/25About 4 min
实现三阶魔方的操作与动画
[TOC]
问题
请编写带有图形界面的普通三阶魔方模拟程序.
要求:
- 实现平移、放大、缩小和自适应大小的魔方展示功能.
- 请自定义编码表示魔方的各种可能操作, 每种编码表示其中 1 种操作.
- 实现打开文本文件的功能, 该文本文件由一系列编码组成, 对应魔方操作.
- 实现魔方操作功能: 可以交互实现每个操作, 也可以通过动画自动播放魔方的系列操作.
- 在操作或转动魔方时, 必须以动画的形式展示, 从而方便看清如何操作或转动.
- 可以保存魔方操作, 保存结果是由一系列编码组成文本文件.
- 编写文档详细介绍模拟算法与图形界面等内容.
参考:
- 雍俊海. 清华教授的小课堂魔方真好玩. 北京: 清华大学出版社.
1. 构建系统与包管理
1.1 xmake & xrepo
工具定位:
- xmake: 新一代跨平台构建工具, 采用 Lua 语法编写构建规则
- xrepo: xmake 生态的跨平台包管理器
选择理由:
- 相比 CMake 更简洁的配置语法 (
xmake.luavsCMakeLists.txt) - 内置依赖管理, 无需额外工具链
- 支持交叉编译和多种工具链
- 集成包管理功能, 降低依赖管理成本
典型配置:
add_requires("glm", "fmt", "imgui v1.89") -- 声明依赖
target("RubikCube")
set_kind("binary")
add_packages("glm", "fmt", "imgui") -- 链接依赖
add_files("src/*.cpp") -- 添加源文件1.2 ccache
作用机制:
- 通过缓存编译中间结果, 加速重复编译过程
- 采用哈希校验机制保证缓存一致性
集成方式:
xmake f --ccache=enable # 启用缓存
xmake build -j8 # 并行编译2. 代码质量保障体系
2.1 代码格式化
工具链配置:
# .clang-format
BasedOnStyle: Google
IndentWidth: 2
ColumnLimit: 1202.2 Sanitizers
| 检测类型 | 检测范围 |
|---|---|
| AddressSanitizer | 内存越界, 使用释放内存 |
| UndefinedBehavior | 未定义行为 (除零, 空指针等) |
| LeakSanitizer | 内存泄漏 |
2.3 静态分析
| 工具 | 检测能力 |
|---|---|
| clang-tidy | 代码质量分析 |
| iwyu | 头文件包含优化 |
| cppcheck | 代码质量分析 |
3. 核心功能库选型
3.1 3D 渲染引擎 - Polyscope
核心特性:
- 基于 OpenGL 的轻量级可视化框架
- 内置相机控制系统 (旋转/平移/缩放)
- 支持实时表面网格渲染
- 提供即时模式 GUI 集成
魔方应用:
// 创建立方体单元
polyscope::SurfaceMesh* add_cube(std::string name, glm::vec3 center) {
std::vector<glm::vec3> vertices = {...};
std::vector<std::vector<size_t>> faces = {...};
return polyscope::registerSurfaceMesh(name, vertices, faces);
}3.2 数学库 - GLM
功能矩阵:
- 提供仿射变换矩阵运算:
glm::rotate(),glm::translate() - 支持四元数旋转插值:
glm::slerp() - 类型安全向量运算:
glm::vec3,glm::mat4
动画实现:
// 立方体旋转插值
glm::mat4 interpolateRotation(float t) {
glm::quat start = ...;
glm::quat end = ...;
return glm::mat4_cast(glm::slerp(start, end, t));
}3.3 用户界面 - ImGui
本程序采用纯键盘交互模式, 通过 ImGui 输入系统实现以下核心交互逻辑:
3.3.1. 操作映射表
| 物理按键 | 魔方操作语义 | 动画参数 |
|---|---|---|
F | 前面顺时针 90 度 | axis: +Z, angle: 90° |
Shift+F | 前面逆时针 90 度 | axis: +Z, angle:-90° |
R | 右面顺时针 90 度 | axis: +X, angle: 90° |
Shift+R | 右面逆时针 90 度 | axis: +X, angle:-90° |
U/D/L/B | 类似映射(各面轴系不同) | … |
3.3.2. 输入处理核心逻辑
void processInput() {
ImGuiIO& io = ImGui::GetIO();
auto checkRotation = [&](ImGuiKey key, Face face) {
if (io.KeysDown[key] && !io.WantCaptureKeyboard) {
const bool reverse = io.KeyShift;
executeRotation(face, reverse);
io.KeysDown[key] = false; // 防止重复触发
}
};
checkRotation(ImGuiKey_F, FRONT);
checkRotation(ImGuiKey_B, BACK);
checkRotation(ImGuiKey_U, UP);
checkRotation(ImGuiKey_D, DOWN);
checkRotation(ImGuiKey_L, LEFT);
checkRotation(ImGuiKey_R, RIGHT);
}3.3.3. 防冲突机制
- WantCaptureKeyboard 检测: 仅在 ImGui 无焦点时响应魔方操作
- 去抖动处理: 操作执行后立即清除键位状态
- 动画锁: 旋转动画执行期间禁用新输入
3.4 辅助工具库
| 库名称 | 功能定位 |
|---|---|
| spdlog | 日志记录 |
| fmt | 类型安全字符串格式化 |
| dbg-macro | 调试信息输出 |
5. 文档生成
5.1 Doxygen 配置
# Doxyfile
PROJECT_NAME = "Rubik's Cube"
INPUT = src/ include/
RECURSIVE = YES
EXTRACT_ALL = YES
GENERATE_LATEX = NO
USE_MDFILE_AS_MAINPAGE = README.md文档生成命令:
doxygen Doxyfile6. 项目目录结构
rubiks-cube/
├── src/ # 源代码
├── tests/ # 单元测试
├── scripts/ # 构建脚本
├── docs/ # 文档
├── xmake.lua # 构建配置
└── .github/ # CI/CD配置本环境配置通过严格的工具链集成, 实现了从代码编写, 质量验证到可视化呈现的全流程支持, 为魔方模拟程序的开发提供了可靠的技术保障. 各组件间通过 xmake 构建系统深度整合, 确保跨平台开发体验的一致性.