头歌实践教学平台:投影变换v2.0

2024-05-03 12:20

本文主要是介绍头歌实践教学平台:投影变换v2.0,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第1关:一点透视

一. 任务描述

1. 本关任务

(1) 理解透视投影变换的方法; (2) 将projection函数和main函数中的空白部分补充完整。

2. 输入

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

test

(2) 代码自动将模型投影到二维平面中心生成一个边长为1的立方体,经过模型变换和投影变换后生成三个绿色的方体,三个立方体的投影变换eye的坐标均为(0,0,5),具体图片如下所示:

test

(3) 参考已有代码,将中心立绿色方体的顶点分别向y轴负方向平移1.2个单位,绘制一个红色立方体。再将红色立方体顶点分别向x轴正,负两个方向平移1.2个单位,绘制两个红色立方体。三个立方体的投影变换eye的坐标均为(0,0,4); (4) 将中心绿色立方体的顶点分别向y轴正方向平移1.2个单位,绘制一个黄色立方体。再将黄色立方体顶点分别向x轴正,负两个方向平移1.2个单位,绘制两个黄色立方体。三个立方体的投影变换eye的坐标均为(0,0,8);

3. 输出

具体结果如下图所示:

test

二. 相关知识

1. 透视投影

透视投影相关知识点,请参考教材与课件或有关资料。

三. 操作说明

(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 projection(Vec3f eye, Vec3f center)
{Matrix m = Matrix::identity(4);// Please add the code here/********** Begin ********/m[3][2] = -1.f / (eye - center).norm();/********** End **********/return m;
}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 lookat(Vec3f eye, Vec3f center, Vec3f up) {Vec3f z = (eye - center).normalize();Vec3f x = (up^z).normalize();Vec3f y = (z^x).normalize();Matrix res = Matrix::identity(4);for (int i = 0; i < 3; i++) {res[0][i] = x[i];res[1][i] = y[i];res[2][i] = z[i];res[i][3] = -center[i];}return res;
}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 = 800;const int height = 800;const int depth = 255;Vec3f center(0, 0, 0);Matrix ViewPort = viewport(width / 4, width / 4, width / 2, height / 2, depth);//generate some imagePNGImage image(width, height, PNGImage::RGBA); image.init(black);model = new Model("cube.obj");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()]);Matrix S0 = scale(0.5, 0.5, 0.5);Vec3f swp0 = S0 * wp0;Vec3f swp1 = S0 * wp1;// 一点透视 float t[3] = { -1.2, 0, 1.2 };Matrix ModelView = Matrix::identity(4);PNGColor clr[3] = { red, green, yellow };Vec3f eye2(0, 0, 5);Matrix Projection2 = projection(eye2, center);for (int j = 0; j < 3; j++){ModelView = translation(Vec3f(t[j], t[1], 0));Vec3f op0 = ViewPort * Projection2 * ModelView * swp0;Vec3f op1 = ViewPort * Projection2 * ModelView *swp1;line(op0, op1, image, green);}// Please add the code here/********** Begin ********/float t33[3] = { 1.2, 0,-1.2 };Matrix ModelView33 = Matrix::identity(4);PNGColor clrRed[3] = { red, red, red };Vec3f eye33(0, 0, 4);Matrix Projection33 = projection(eye33, center);for (int j = 0; j < 3; j++){ModelView33 = translation(Vec3f(t33[j], t[0], 0));Vec3f op0 = ViewPort * Projection33 * ModelView33 * swp0;Vec3f op1 = ViewPort * Projection33 * ModelView33 * swp1;line(op0, op1, image, red);}float t44[3] = { 1.2, 0,-1.2 };Matrix ModelView44 = Matrix::identity(4);PNGColor clrYellow[3] = { yellow, yellow, yellow };Vec3f eye44(0, 0, 8);Matrix Projection44 = projection(eye44, center);for (int j = 0; j < 3; j++){ModelView44 = translation(Vec3f(t44[j], t[2], 0));Vec3f op0 = ViewPort * Projection44 * ModelView44 * swp0;Vec3f op1 = ViewPort * Projection44 * ModelView44 * swp1;line(op0, op1, image, yellow);}/********** 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;
}

这篇关于头歌实践教学平台:投影变换v2.0的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/956737

相关文章

C++必修:模版的入门到实践

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C++学习 贝蒂的主页:Betty’s blog 1. 泛型编程 首先让我们来思考一个问题,如何实现一个交换函数? void swap(int& x, int& y){int tmp = x;x = y;y = tmp;} 相信大家很快就能写出上面这段代码,但是如果要求这个交换函数支持字符型

亮相WOT全球技术创新大会,揭秘火山引擎边缘容器技术在泛CDN场景的应用与实践

2024年6月21日-22日,51CTO“WOT全球技术创新大会2024”在北京举办。火山引擎边缘计算架构师李志明受邀参与,以“边缘容器技术在泛CDN场景的应用和实践”为主题,与多位行业资深专家,共同探讨泛CDN行业技术架构以及云原生与边缘计算的发展和展望。 火山引擎边缘计算架构师李志明表示:为更好地解决传统泛CDN类业务运行中的问题,火山引擎边缘容器团队参考行业做法,结合实践经验,打造火山

springboot家政服务管理平台 LW +PPT+源码+讲解

3系统的可行性研究及需求分析 3.1可行性研究 3.1.1技术可行性分析 经过大学四年的学习,已经掌握了JAVA、Mysql数据库等方面的编程技巧和方法,对于这些技术该有的软硬件配置也是齐全的,能够满足开发的需要。 本家政服务管理平台采用的是Mysql作为数据库,可以绝对地保证用户数据的安全;可以与Mysql数据库进行无缝连接。 所以,家政服务管理平台在技术上是可以实施的。 3.1

比较学习难度:Adobe Illustrator、Photoshop和新兴在线设计平台

从入门设计开始,几乎没有人不知道 Adobe 公司两大设计软件:Adobe Illustrator和 Photoshop。虽然AI和PS很有名,有一定设计经验的设计师可以在早期探索和使用后大致了解AI和PS的区别,但似乎很少有人会系统地比较AI和PS。目前,设计软件功能多样,轻量级和网页设计软件已成为许多设计师的需求。对于初学者来说,一篇有针对性的AI和PS比较总结文章具有非常重要的指导意义。毕竟

智慧环保一体化平台登录

据悉,在当今这个数字化、智能化的时代,环境保护工作也需要与时俱进,不断创新。朗观视觉智慧环保一体化平台应运而生,它利用先进的信息技术手段,为环保工作提供了更加便捷、高效的管理方式,成为推动绿色发展的重要力量。 一、智慧环保一体化平台的诞生背景 随着工业化进程的加快,环境污染问题日益严重,传统的环保管理模式已经难以满足现代社会的需求。为了提高环保工作的效率和质量,智慧环保一体化平台应运而

9 个 GraphQL 安全最佳实践

GraphQL 已被最大的平台采用 - Facebook、Twitter、Github、Pinterest、Walmart - 这些大公司不能在安全性上妥协。但是,尽管 GraphQL 可以成为您的 API 的非常安全的选项,但它并不是开箱即用的。事实恰恰相反:即使是最新手的黑客,所有大门都是敞开的。此外,GraphQL 有自己的一套注意事项,因此如果您来自 REST,您可能会错过一些重要步骤!

基于Spring Boot构建淘客返利平台

基于Spring Boot构建淘客返利平台 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将讨论如何基于Spring Boot构建一个淘客返利平台。 淘客返利平台通过整合各种电商平台的商品信息,提供给用户查询和返利功能,从而实现流量变现。以下是实现一个简单的淘客返利平台的步骤。 1. 项目初始化 首先,使用Spri

IPD推行成功的核心要素(十一)技术规划与平台规划促进公司战略成功

随着外部大环境的影响,各企业仅有良好的愿望是不够的。预测并顺应新兴市场和技术的变化,变危机为转机,不断推出强大的产品才是一个公司持续繁荣的根本保障。而高效的产品开发往往是基于某些关键技术,针对市场推出的一个或几个产品系列,这些产品系列通常共用一些产品平台,共用一种或者几种关键技术。当一家企业进入了平稳发展期,已经建立了较为完善的管理制度和产品开发流程,但是依然认为竞争对手是那样强大,那样不可战胜。

一二三应用开发平台应用开发示例(4)——视图类型介绍以及新增、修改、查看视图配置

调整上级属性类型 前面为了快速展示平台的低代码配置功能,将实体文件夹的数据模型上级属性的数据类型暂时配置为文本类型,现在我们调整下,将其数据类型调整为实体,如下图所示: 数据类型需要选择实体,并在实体选择框中选择自身“文件夹” 这时候,再点击生成代码,平台会报错,提示“实体【文件夹】未设置主参照视图”。这是因为文件夹选择的功能页面,同样是基于配置产生的,因为视图我们还没有配置,所以会报错。

Netty ByteBuf 释放详解:内存管理与最佳实践

Netty ByteBuf 释放详解:内存管理与最佳实践 在Netty中(学习netty请参考:🔗深入浅出Netty:高性能网络应用框架的原理与实践),管理ByteBuf的内存是至关重要的(学习ByteBuf请参考:🔗Netty ByteBuf 详解:高性能数据缓冲区的全面介绍)。未能正确释放ByteBuf可能会导致内存泄漏,进而影响应用的性能和稳定性。本文将详细介绍如何正确地释放ByteB