Games101作业0:图形学新手的虚拟机实验舱入门指南

发布时间:2026/10/25 1:01:38
Games101作业0:图形学新手的虚拟机实验舱入门指南 简介本资源是GAMES101《计算机图形学与混合现实研讨会》课程2020年春季学期的首项实践作业指南面向图形学初学者及需快速搭建统一开发环境的学习者核心解决虚拟机配置繁琐、环境不一致导致的编译运行障碍问题。文档以PDF形式提供完整操作闭环涵盖VirtualBox安装含Win/mac/Linux多平台链接、清华云盘虚拟硬盘Ubuntu 18.04下载与解压、虚拟机新建与VDI挂载、Guest Additions增强功能安装GUI/命令行双路径、VSCode代码编辑与拖放传输设置以及C基础语法、Eigen库使用和常见错误段错误、链接失败等排错提示。资源共1个PDF文件大小874KB内容结构清晰含详细截图指引与命令示例适合作为图形学实验环境搭建的标准参考。目前已有435人学习下载是入门GAMES101系列作业不可或缺的预备性技术文档。1. 这不是装系统是“开箱即用”的图形学实验舱Games101作业0到底在干啥你有没有试过——想跑一个图形学小demo结果卡在装OpenGL、配CMake、调Eigen版本、解决Ubuntu和Mac终端差异上三天过去连“Hello World”都没打印出来别慌这不是你手残是环境配置本身就在劝退。Games101作业0就是闫令琪老师团队为你亲手焊好、加满油、钥匙插在 ignition 上的一台“图形学实验舱”。它不叫安装教程它叫虚拟机交付包你下载一个文件.vdi点几下鼠标输入密码Ilovegraphics就直接坐进一台预装好VSCode、C17、Eigen3、cmake 3.10、Ubuntu 18.04 的完整开发环境里。没有“我的头文件找不到”没有“为什么你的g能编我的报错”更没有“同学A说运行成功同学B说Segmentation Fault”——所有人从同一块硬盘镜像启动就像全班共用同一台物理实验室电脑。它专为零基础新手设计不考算法、不扣分、不设门槛唯一目标就是让你第一次敲C代码、第一次用Eigen算矩阵、第一次用cmake编译、第一次看到自己写的坐标变换结果输出在终端里。如果你刚听说“齐次坐标”“旋转变换”“线性代数库”又怕被环境配置按在地上摩擦——这份作业0就是你敢点“开始”的那个绿色启动按钮。2. 先搞懂一个事实为什么非得用虚拟机而不是直接在你电脑上装2.1 图形学环境的“三座大山”没虚拟机真跨不过新手常以为“我Mac有ClangWindows有VSLinux有gcc不都一样编C”——这是最典型的认知偏差。图形学作业不是写个计算器它背后站着三座必须翻越的大山依赖地狱Dependency HellEigen要特定版本3.3.xOpenCV要兼容CUDAGLFW要匹配显卡驱动……装错一个整个链路崩掉。比如你本机Eigen是3.4但课程示例用的是3.3的APIEigen::Matrix3f初始化语法就可能报错。平台撕裂Platform FragmentationMac的Metal、Windows的DirectX、Linux的OpenGL——底层渲染接口不同连#include GL/gl.h都可能因系统而异更别说终端命令brew installvsapt-get install、路径分隔符/vs\、甚至默认编码UTF-8 vs GBK引发的玄学bug。教学一致性Teaching Consistency老师演示时./Transformation能跑你本地make完却提示undefined reference to Eigen::MatrixBase...::operator*——问题不在你代码而在你CMakeLists.txt里漏写了target_link_libraries(Transformation eigen3)而虚拟机里这行已预置好。提示虚拟机不是“多此一举”它是把“环境配置”这个黑匣子直接换成一个带锁的铅盒——你打不开也不需要打开。你只负责往里放代码看结果。2.2 虚拟机 ≠ 慢 卡这份交付包专为学习优化很多人一听“虚拟机”就皱眉“我i5笔记本跑不动”——但Games101作业0的虚拟硬盘.vdi是精简定制版无GUI冗余服务关掉了蓝牙、打印机、远程桌面等所有与图形学无关的后台进程内存精准分配文档明确建议2GB RAM——够跑VSCode终端Eigen计算又不抢主机资源IO直通优化VirtualBox的Guest Additions启用后共享剪贴板、拖放文件、自动缩放窗口全开操作感接近原生系统。你可以把它理解成“轻量级沙盒容器”不是模拟整个世界而是只搭好你写作业需要的那一张课桌、一把椅子、一支笔和一本教材。2.3 你真正要做的只有三步下载 → 配置 → 启动别被“虚拟机”这个词吓住。它不像装系统那样要你选分区、格式化硬盘。整个流程就是三个确定性动作下载一个文件清华云盘链接https://cloud.tsinghua.edu.cn/f/103133da1bf8451b8ba6密码games101解压出.vdi文件约3GB在VirtualBox里“挂载”它新建虚拟机 → 类型选Linux/Ubuntu-64bit → 内存2GB → “使用已有虚拟硬盘” → 指向你解压出的.vdi点“启动” → 输入密码Ilovegraphics→ 进入桌面。全程无需编译、无需sudo、无需查报错——就像插入一张游戏光盘按Start就能玩。后面所有代码编写、编译、运行都在这个已经调好的环境里发生。2.4 避坑新手最容易卡死的5个地方现象→原因→解决注意以下全是真实翻车现场来自某高校图形学入门班前3届学员的血泪经验总结。现象1点击“启动”后黑屏/卡在紫色Ubuntu Logo界面不动→ 原因VirtualBox未启用硬件虚拟化VT-x/AMD-V。很多新笔记本默认关闭此功能。→ 解决重启电脑进BIOS开机狂按F2/F10/Del找到Advanced → CPU Configuration → Intel Virtualization Technology或类似选项设为Enabled保存退出。再启动即可。现象2拖文件进虚拟机没反应或提示“拖放功能不可用”→ 原因Guest Additions未安装或安装后未重启。→ 解决先确认是否已执行1.4节操作若失败务必用终端命令重装sudo mkdir -p /media/cdrom sudo mount -t auto /dev/cdrom /media/cdrom cd /media/cdrom sudo sh VBoxLinuxAdditions.run sudo reboot注意mkdir -p中的-p是关键避免因目录已存在报错reboot不可省略。现象3VSCode里打开main.cpp中文注释显示乱码如“// 计算旋转”变“// ???”→ 原因VSCode默认编码非UTF-8而作业文件用UTF-8保存。→ 解决在VSCode中按CtrlShiftPMac为CmdShiftP→ 输入Change File Encoding→ 选Reopen with Encoding→ 选UTF-8。之后右下角状态栏会显示“UTF-8”永久生效。现象4终端执行cmake ..时报错CMake Error: The source directory .../build does not appear to contain CMakeLists.txt→ 原因你在build文件夹里执行了cmake ..但..指向的是build的上级目录——而你还没把CMakeLists.txt放到那个上级目录→ 解决确保你的作业框架含main.cpp和CMakeLists.txt放在同一文件夹如~/Desktop/assignment0然后cd ~/Desktop/assignment0 # 先进入作业根目录 mkdir build # 创建build文件夹 cd build # 进入build cmake .. # 此时..才是正确的上级目录 make现象5运行./Transformation后报错./Transformation: error while loading shared libraries: libeigen3.so: cannot open shared object file: No such file or directory→ 原因Eigen是头文件库header-only无需动态链接此错误说明你误删或覆盖了系统预装的Eigen路径。→ 解决虚拟机里Eigen位于/usr/include/eigen3/绝不可动。检查CMakeLists.txt中是否错误添加了find_package(Eigen3 REQUIRED)并target_link_libraries(... eigen3)——作业0不需要链接删掉这两行即可。正确写法只需cmake_minimum_required(VERSION 3.10) project(Transformation) set(CMAKE_CXX_STANDARD 17) add_executable(Transformation main.cpp)3. 先跑通第一个例子用Eigen算出“绕原点转45°再平移(1,2)”的坐标3.1 理解题目为什么非要用“齐次坐标”不用行不行题目要求“点P(2,1)绕原点逆时针旋转45°再平移(1,2)求最终坐标”。你可能会想旋转用x x*cosθ - y*sinθ,y x*sinθ y*cosθ平移直接x x 1,y y 2——两步搞定为啥非要扯“齐次坐标”因为这是图形学的统一语言。普通二维坐标(x,y)只能做旋转、缩放线性变换但平移1,2是非线性操作无法用2×2矩阵表示。齐次坐标把它升维成(x,y,1)用3×3矩阵一次性封装旋转平移[ cosθ -sinθ tx ] [x] [x] [ sinθ cosθ ty ] × [y] [y] [ 0 0 1 ] [1] [1 ]这样无论你做10次变换旋转→缩放→平移→再旋转只要把10个3×3矩阵乘起来再乘原始点一步到位。这就是“变换矩阵堆叠”的威力——而Eigen就是帮你安全、高效、可读地完成这些矩阵乘法的工具。3.2 动手写代码main.cpp里填这7行核心逻辑打开VSCode创建main.cpp或直接编辑作业框架里的把下面代码复制进去注意替换掉原有样例代码#include iostream #include cmath #include eigen3/Eigen/Core int main() { // 1. 定义原始点P齐次坐标x, y, 1 Eigen::Vector3f P(2.0f, 1.0f, 1.0f); // 2. 构造旋转矩阵R绕Z轴逆时针45°cos45sin45√2/2≈0.7071 float rad M_PI / 4.0f; // 弧度制45° π/4 Eigen::Matrix3f R; R std::cos(rad), -std::sin(rad), 0, std::sin(rad), std::cos(rad), 0, 0, 0, 1; // 3. 构造平移矩阵Ttx1, ty2 Eigen::Matrix3f T; T 1, 0, 1, 0, 1, 2, 0, 0, 1; // 4. 组合变换先旋转再平移 → 总变换矩阵 T * R Eigen::Matrix3f M T * R; // 5. 应用变换P_final M * P Eigen::Vector3f P_final M * P; // 6. 输出结果去掉齐次坐标第三维 std::cout 原始点P (2, 1) std::endl; std::cout 变换后坐标 ( P_final(0) , P_final(1) ) std::endl; return 0; }逻辑说明Eigen::Vector3f P(2.0f, 1.0f, 1.0f)定义齐次坐标点f后缀表示float类型避免double精度干扰M_PI是cmath里的π常量rad M_PI / 4.0f确保用浮点运算矩阵R和T用流式赋值按行优先填入清晰对应数学公式关键点M T * R顺序不能反矩阵乘法不满足交换律T*R表示“先R后T”R*T则完全错误P_final(0)和P_final(1)取变换后向量的前两个分量即最终二维坐标。3.3 编译运行四条命令走完从代码到结果确保你的文件结构是这样的~/Desktop/assignment0/ ├── main.cpp # 刚刚写好的代码 ├── CMakeLists.txt # 课程提供内容应为上面3.2节的正确版本 └── build/ # 待创建的编译目录在终端CtrlAltT中依次执行cd ~/Desktop/assignment0 # 进入作业根目录 mkdir build # 创建build文件夹若已存在可跳过 cd build # 进入build cmake .. # 生成Makefile会检查CMakeLists.txt和main.cpp make # 编译生成可执行文件Transformation ./Transformation # 运行看到结果预期输出原始点P (2, 1) 变换后坐标 (1.70711, 4.12132)参数验证手动验算一下——旋转45°(2,1) → (2×0.7071 - 1×0.7071, 2×0.7071 1×0.7071) (0.7071, 2.1213)平移(1,2)(0.70711, 2.12132) (1.7071, 4.1213) ✓ 完全吻合3.4 如果报错对照这个最小排查清单报错信息关键词最可能原因快速验证命令‘M_PI’ was not declared in this scopecmath未正确包含或编译器标准过低检查#include cmath是否存在在CMakeLists.txt中确认set(CMAKE_CXX_STANDARD 17)no match for ‘operator’Eigen矩阵输出需#include eigen3/Eigen/Dense在main.cpp开头添加#include eigen3/Eigen/Dense虽然Core够用但Dense提供完整IOerror: ‘cos’ is not a member of ‘std’未用std::cos且未using namespace std改为std::cos(rad)或在文件开头加using namespace std;课程不推荐但临时调试可用Segmentation fault (core dumped)访问了未初始化的Eigen对象如Eigen::Matrix3f M; M(0,0) 1;未初始化矩阵所有Eigen矩阵/向量声明后立即赋值或用Eigen::Matrix3f M Eigen::Matrix3f::Zero();4. 为什么用Eigen不用手写矩阵3个让新手少走半年弯路的真相4.1 真相一Eigen不是“库”是“C模板头文件集合”你可能搜过“怎么安装Eigen”然后看到一堆sudo apt install libeigen3-dev——但在Games101虚拟机里根本不用装。因为Eigen是纯头文件库header-only所有代码都在/usr/include/eigen3/下的.h文件里编译时直接展开进你的程序。你只需#include eigen3/Eigen/Core编译器就自动把矩阵乘法、求逆、特征值等所有逻辑“复印”进你的可执行文件。没有.so动态库没有链接步骤没有版本冲突——就像#include vector一样自然。类比手写矩阵类就像每次做饭都要从种水稻开始用Eigen等于超市买现成大米淘洗下锅就行。4.2 真相二Eigen的语法就是数学公式的直译看这段代码Eigen::Matrix3f A, B, C; A 1,2,3, 4,5,6, 7,8,9; B 2,3,1, 4,6,5, 9,7,8; C A * B; // 矩阵乘法它和你草稿纸上写的C A × B完全一致。没有multiply(A, B)函数调用没有A.dot(B)这种反直觉命名。Eigen重载了*、、-、等运算符让C代码长得和线性代数课本一模一样。对新手而言这意味着你不用学“Eigen怎么用”你只要学“线性代数怎么算”代码就自然会写。4.3 真相三Eigen的报错是给你指路的“数学翻译器”手写矩阵时A(10,10) 1越界程序直接Segmentation Fault你得翻core dump而Eigen会报eigen3/Eigen/src/Core/DenseCoeffsBase.h:425: Eigen::DenseCoeffsBaseDerived, 1::Scalar Eigen::DenseCoeffsBaseDerived, 1::operator()(Eigen::Index, Eigen::Index) [with Derived Eigen::Matrixfloat, 3, 3; Eigen::DenseCoeffsBaseDerived, 1::Scalar float; Eigen::Index long int]: Assertion row 0 row rows() col 0 col cols() failed.翻译成人话“你试图访问第10行第10列但这个矩阵只有3行3列请检查下标”。它不只告诉你错了还告诉你错在哪一行数学操作上——这是手写代码永远给不了的调试体验。4.4 避坑Eigen新手必踩的3个“看起来很对”陷阱陷阱1混用float和double导致精度丢失→ 现象Eigen::Vector3f v(1.0, 2.0, 3.0);中1.0是doublev会被隐式转换为double向量但声明是float结果截断。→ 正确写法全部加f后缀 →Eigen::Vector3f v(1.0f, 2.0f, 3.0f);陷阱2矩阵未初始化就访问元素→ 现象Eigen::Matrix3f M; std::cout M(0,0);输出随机大数内存垃圾。→ 正确写法用Zero()、Identity()或赋值初始化 →Eigen::Matrix3f M Eigen::Matrix3f::Zero();陷阱3用进行深拷贝却误以为是引用→ 现象Eigen::Matrix3f A, B; A 1,0,0,0,1,0,0,0,1; B A; A(0,0)999; std::cout B(0,0);输出1不是999。→ 原因B A是值拷贝B是A的副本修改A不影响B。若需引用用const Eigen::Matrix3f B A;但Eigen不鼓励裸引用易生命周期问题。5. 下一步学什么从“能跑”到“真懂”的3条渐进路径5.1 路径一把作业0的代码变成你自己的“图形学计算器”现在你已能算一个点的变换下一步是让它活起来。不要停留在P(2,1)试试这些改造参数化输入用std::cin让用户输入点坐标、角度、平移量实时计算结果批量处理定义std::vectorEigen::Vector3f points对10个点同时应用同一变换可视化雏形用std::cout画个简易坐标系把变换前后的点用*和o标出来如x: -5..5, y: -5..5网格感受空间变化。我第一次学时花了一晚上写了个“旋转动画”循环从0°到360°每步算一次P_rotated用system(clear)清屏再打印新位置——虽然只是文字但看着点真的在绕圈那种“我控制了它”的兴奋感比任何理论都管用。5.2 路径二啃透Eigen官方Tutorial的前3页每天15分钟Eigen官网http://eigen.tuxfamily.org的 Tutorial 不是文档是手把手教案。重点攻克章节为什么必须读新手实操建议Basic Matrix Manipulation学会.block(),.row(),.col()切片才能处理图像像素块、顶点缓冲区用Eigen::MatrixXf img(100,100); img.block(10,10,20,20).setOnes();画个白色方块Reductions, Visitors and Broadcasting.sum(),.mean(),.array().sqrt()——图像亮度调整、归一化必备对随机矩阵M算M.array().abs().maxCoeff()找最大绝对值Geometry ModuleEigen::Affine2f,Eigen::Transform——作业0的手动拼接矩阵这里一行搞定替换作业0代码Eigen::Affine2f transform Eigen::Translation2f(1,2) * Eigen::Rotation2Df(M_PI/4);注意别从头读到尾每天只读1个小节立刻在虚拟机里敲代码验证。遇到不懂的API就std::cout your_matrix.rows() x your_matrix.cols();——Eigen的调试永远从cout开始。5.3 路径三用cmake管理更复杂的项目为作业1铺路作业0的CMakeLists.txt只有5行但真实项目会这样cmake_minimum_required(VERSION 3.10) project(GraphicsDemo VERSION 0.1) # 查找依赖未来会用到 find_package(Eigen3 REQUIRED) find_package(OpenGL REQUIRED) # 添加可执行文件 add_executable(main main.cpp shader.cpp) # 链接库Eigen不用linkOpenGL需要 target_link_libraries(main OpenGL::GL) # 设置C标准和警告 set_property(TARGET main PROPERTY CXX_STANDARD 17) set_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED ON) target_compile_options(main PRIVATE -Wall -Wextra)现在就动手在虚拟机里创建新文件夹~/Desktop/mini_demo把上面代码存为CMakeLists.txt再建个空main.cpp。执行mkdir build cd build cmake .. make——如果成功生成main说明你已拿下cmake骨架。这是后续加载着色器、调用OpenGL的基础比背概念重要十倍。5.4 一个习惯从那以后我每次写Eigen代码都强制走一遍“三查”查类型Vector3f还是Vector3dMatrix4f还是Matrix4d统一用ffloat除非明确需要double精度查维度A.rows() B.cols()乘法前先std::cout A.rows() x A.cols() * B.rows() x B.cols();查初始化声明后第一行必须是赋值或::Zero()绝不留空矩阵。这个习惯让我在后续作业中把90%的Segmentation Fault扼杀在编译前。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询