头歌实践教学平台:CG3-v2.0-图形几何变换

第3关:图形的平移与旋转

一. 任务描述

1. 本关任务

(1) 理解几何变换基本原理, 掌握平移和旋转变换的方法; (2) 根据几何变换基本原理,将main函数中的空白部分补充完整。

2. 输入

(1) 代码将自动输入一个边长为2的obj正方体模型,具体模型如下图:

test

(2) 将立方体的顶点坐标分别沿x,y,z轴方向缩放0.5倍,然后绘制一个白色正方形; (3) 将立方体的顶点坐标分别向x,y,z轴正方向平移0.5个单位距离,再沿z轴逆时针方向旋转45度,然后绘制一个绿色正方形 (4) 将立方体的顶点坐标分别沿z轴逆时针方向旋转45度,再分别向x,y,z轴正方向平移0.5个单位距离,然后绘制一个红色正方形;

3. 输出

具体结果如下图所示:

test

二. 相关知识

几何变换:指对图形的几何信息经过平移、缩放、旋转等变换后产生的新图形。

1. 先平移后旋转

将某个点P的坐标首先通过矩阵T平移一定距离,然后再通过矩阵R 旋转一定角度得到 P′

写成矩阵的形式就是:

P′=RTP

2. 先旋转后平移

将某个点P的坐标首先通过矩阵R 旋转一定角度,然后再通过矩阵T平移一定距离,得到 P′

写成矩阵的形式就是:

P′=TRP

提示: 注意对比图形平移和旋转的顺序不同时的效果。

三. 操作说明

(1)按要求补全代码; (2)点击窗口右下角"测评"按钮,等待测评结果,如果通过后可进行下一关任务。


开始你的任务吧,祝你成功!

四、实验代码

#include <vector>
#include <cmath>
#include <algorithm>
#include <iostream>
#include "model.h"
#include "geometry.h"
#include "pngimage.h"using namespace std;
const double PI = acos(-1.0);void line(Vec3i p0, Vec3i p1, PNGImage  &image, PNGColor color)
{bool steep = false;if (std::abs(p0.x - p1.x) < std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep = true;}if (p0.x > p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx = p1.x - p0.x;int dy = std::abs(p1.y - p0.y);int y = p0.y;int d = -dx;for (int x = p0.x; x <= p1.x; x++){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d = d + 2 * dy;if (d > 0){y += (p1.y > p0.y ? 1 : -1);d = d - 2 * dx;}}
}Matrix viewport(int x, int y, int w, int h, int depth) {Matrix m = Matrix::identity(4);m[0][3] = x + w / 2.f;m[1][3] = y + h / 2.f;m[2][3] = depth / 2.f;m[0][0] = w / 2.f;m[1][1] = h / 2.f;m[2][2] = depth / 2.f;return m;
}Matrix translation(Vec3f v) {Matrix Tr = Matrix::identity(4);Tr[0][3] = v.x;Tr[1][3] = v.y;Tr[2][3] = v.z;return Tr;
}Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z = Matrix::identity(4);Z[0][0] = factorX;Z[1][1] = factorY;Z[2][2] = factorZ;return Z;
}Matrix rotation_x(float angle)
{angle = angle * PI / 180;float sinangle = sin(angle);float cosangle = cos(angle);Matrix R = Matrix::identity(4);R[1][1] = R[2][2] = cosangle;R[1][2] = -sinangle;R[2][1] = sinangle;return R;
}Matrix rotation_y(float angle)
{angle = angle * PI / 180;float sinangle = sin(angle);float cosangle = cos(angle);Matrix R = Matrix::identity(4);R[0][0] = R[2][2] = cosangle;R[0][2] = sinangle;R[2][0] = -sinangle;return R;
}Matrix rotation_z(float angle) {angle = angle * PI / 180;float sinangle = sin(angle);float cosangle = cos(angle);Matrix R = Matrix::identity(4);R[0][0] = R[1][1] = cosangle;R[0][1] = -sinangle;R[1][0] = sinangle;return R;
}int main(int argc, char** argv)
{const PNGColor white = PNGColor(255, 255, 255, 255);const PNGColor black = PNGColor(0, 0, 0, 255);const PNGColor red = PNGColor(255, 0, 0, 255);const PNGColor green = PNGColor(0, 255, 0, 255);const PNGColor blue = PNGColor(0, 0, 255, 255);const PNGColor yellow = PNGColor(255, 255, 0, 255);Model *model = NULL;const int width = 500;const int height = 500;const int depth = 255;//generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size() in encodeimage.init(black);model = new Model("cube.obj");Matrix VP = viewport(width / 4, width / 4, width / 2, height / 2, depth);for (int i = 0; i < model->nfaces(); i++){std::vector<int> face = model->face(i);for (int j = 0; j < (int)face.size(); j++){Vec3f wp0 = model->vert(face[j]);Vec3f wp1 = model->vert(face[(j + 1) % face.size()]);// Please add the code here/********** Begin ********/// draw the model after scaledMatrix Suo=scale(0.5,0.5,0.5);Vec3f ssp0=VP*Suo*wp0;Vec3f ssp1=VP*Suo*wp1;line(ssp0,ssp1,image,white);//  translated then rotated Matrix Tp=translation(Vec3f(1,1,1));Matrix R = rotation_z(45 );Vec3f trp0 = VP*Suo*Tp*R*wp0;Vec3f trp1 = VP*Suo*Tp*R*wp1;line(trp0, trp1, image, red);// rotated then translatedMatrix Tp1=translation(Vec3f(1.5,1.5,1.5));Vec3f rtp0=VP*Suo*R*Tp*wp0;Vec3f rtp1=VP*Suo*R*Tp*wp1;line(rtp0,rtp1,image,green);/********** End *********/}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file("../img_step1/test.png");delete model;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/8381.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DDR4 SDRAM 和LPDDR4的区别

DDR4 SDRAM(Double Data Rate Fourth Generation Synchronous Dynamic Random-Access Memory)和LPDDR4(Low Power Double Data Rate Fourth Generation)都是内存技术的标准,但它们设计用于不同的平台,并在性能、功耗和物理尺寸方面有所差异: 应用领域: DDR4 SDRAM 主要…

【力扣】746. 使用最小花费爬楼梯

原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者…

Unity图文混排EmojiText的使用方式和注意事项

​​​​​​​ 效果演示&#xff1a; 使用方式&#xff1a; 1、导入表情 2、设置图片格式 3、生成表情图集 4、创建/修改目标材质球 5、测试 修复换行问题 修复前&#xff1a; 修复后&#xff1a; 修复代码&#xff1a; 组件扩展 1、右键扩展 2、组件归类&#…

ODBC - 笔记

0 C++通过ODBC方式连接数据库SQLServer及增删查改操作【图书借阅系统为例】 C++通过ODBC方式连接数据库SQLServer及增删查改操作【图书借阅系统为例】_odbc5.2 c++怎么连接数据库-CSDN博客 0.1 c++使用libODBC linux - /lib/x86_64-linux-gnu/libodbc.so.2 win - /c/WINDO…

【MySQL数据库设计规范】安全规范

欢迎点开这篇文章&#xff0c;自我介绍一下哈&#xff0c;本人笔名姑苏老陈&#xff0c;是一个JAVA开发老兵。 本文收录于 《MySQL数据库设计规范》专栏中&#xff0c;该专栏主要分享一些关于MySQL数据库设计相关的技术规范文章&#xff0c;定期更新&#xff0c;欢迎关注&#…

ansible-3

目录 一、Templates 模块 1.1.先准备一个以 .j2 为后缀的 template 模板文件&#xff0c;设置引用的变量 1.2.修改主机清单文件&#xff0c;使用主机变量定义一个变量名相同&#xff0c;而值不同的变量 1.3.编写 playbook 二、tags 模块 三、Roles 模块 四、编写模块 4…

环形链表问题详解

引言 环形链表的题大家都应该做过&#xff0c;如果没有做过可以去某扣上做一下 ,下面有传送门 141. 环形链表 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/linked-list-cycle/submissions/530160081/ 正文 如果在面试的情况下出现了环形链表的题大…

【PHP】计算两个时间戳之间相差的时间

目录 一、span方法概述 二、输出格式解析 三、方法执行流程 四、应用场景 五、注意事项 六、完整代码示例 时间跨度计算&#xff1a;PHP中的span方法解析 在Web开发中&#xff0c;我们经常需要对时间进行各种计算&#xff0c;尤其是在用户界面中展示时间差或倒计时等功能…

iOS 10权限问题

简单说明 1.注意需要打开info.plist文件添加相应权限以及权限的说明&#xff0c;否则程序在iOS10上会出现崩溃。 2.且添加时注意不要有空格。 3.输入Privacy一般会有提示。 权限说明 iOS 10支持的所有权限类型 Privacy - Bluetooth Peripheral Usage Description 蓝牙权限…

43.乐理基础-拍号-常见的拍号与强弱关系

首先拍号的定义&#xff1a;39.认识音符、40.什么是一拍、41.小节、小节线、终止线、42.看懂拍号的意义 通过 39.认识音符、40.什么是一拍、41.小节、小节线、终止线、42.看懂拍号的意义 应该可以知道 Y的取值只能是2、4、8、16、32、64。。。。因为Y指的是Y分音符&#xff0c;…

【ITK配准】第八期 优化器(Optimizer)

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享ITK中的优化器(Optimizer),希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 优化器 在ITK中最…

数据结构之单单单——链表

一.链表 1&#xff09;链表的概念 链表&#xff08;Linked List&#xff09;是一种物理存储结构上非连续&#xff0c;非顺序的储存结构&#xff0c;数据元素的逻辑顺序是通过链表中指针链接次序实现的。要注意&#xff0c;链表也是线性表----->但链表在物理结构上不是线性的…

WinDbg 常用的SOS命令

在使用WinDbg进行.NET应用程序的调试时&#xff0c;SOS (Son of Strike) 调试扩展是一个非常重要的工具。它是专门为.NET Framework应用程序设计的&#xff0c;帮助开发者理解托管代码的内部状态。以下是一些常用的SOS调试命令及其用途&#xff1a; 1. !dumpheap 用途: 列出托…

(自适应手机端)物流运输快递仓储网站模板 - 带三级栏目

(自适应手机端)物流运输快递仓储网站模板 - 带三级栏目PbootCMS内核开发的网站模板&#xff0c;该模板适用于物流运输网站、仓储货运网站等企业&#xff0c;当然其他行业也可以做&#xff0c;只需要把文字图片换成其他行业的即可&#xff1b;自适应手机端&#xff0c;同一个后台…

SOLIDWORKS Electrical电气元件智能开孔

实际的电气元器件安装中&#xff0c;一些元器件需要穿过孔洞安装&#xff0c;例如按钮、指示灯会在配电柜的控制面板上&#xff0c;需要穿过控制面板安装。这部分内容放在软件建模、装配时&#xff0c;往往比较复杂因为考虑孔的大小符合元器件规格、孔跟随元器件移动、同一元器…

Java并发编程之锁的艺术:面试与实战指南(一)

Java并发编程之锁的艺术&#xff1a;面试与实战指南&#xff08;一&#xff09; 文章目录 Java并发编程之锁的艺术&#xff1a;面试与实战指南&#xff08;一&#xff09;一、什么是锁&#xff1f;二、Java中有哪些类型的锁&#xff1f;三、synchronized 和 ReentrantLock的区别…

MinimogWP WordPress 主题下载——优雅至上,功能无限

无论你是个人博客写手、创意工作者还是企业站点的管理员&#xff0c;MinimogWP 都将成为你在 WordPress 平台上的理想之选。以其优雅、灵活和功能丰富而闻名&#xff0c;MinimogWP 不仅提供了令人惊叹的外观&#xff0c;还为你的网站带来了无限的创作和定制可能性。 无与伦比的…

后端常用技能:解决java项目前后端传输数据中文出现乱码、问号问题

0. 问题背景 最近做一个解析数据的小工具&#xff0c;本地运行时都正常&#xff0c;发布到服务器上后在导出文件数据时发现中文全部变成了问号&#xff0c;特此记录下问题解决的思路和过程 1. 环境 java 1.8 springboot 2.6.13 额外引入了fastjson&#xff0c;commons-csv等…

5.1 Java全栈开发前端+后端(全栈工程师进阶之路)-服务端框架-MyBatis框架-相信我看这一篇足够

0.软件框架技术简介 软件框架&#xff08;software framework&#xff09;&#xff0c;通常指的是为了实现某个业界标准或完成特定基本任务的软件组件规范&#xff0c;也 指为了实现某个软件组件规范时&#xff0c;提供规范所要求之基础功能的软件产品。 框架的功能类似于基础设…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷1(私有云)

#需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包…