计算机图形学-变换基础

坐标系转换历程
模型坐标系 -> 世界坐标系 -> 摄像机坐标系 -> 视口(屏幕)坐标系

变换

仿射变换和线性变换
线性:旋转 缩放 镜像 切变
放射: 平移
image.png
image.png

平移

2D变换矩阵

image.png

3D变换矩阵

image.png

旋转

2D旋转矩阵

image.png

 //2D 旋转private (float,float) VertexRotate(float angle ,float x,float y){float newX = (float)(x * Math.Cos(angle) - y * Math.Sin(angle));float newY = (float)(x * Math.Sin(angle) + y * Math.Cos(angle));return (newX,newY);}public void Rotate(int degree){float angle = (float)(degree / 360.0f * Math.PI);//a点float newX, newY;(newX,newY) =  VertexRotate(angle, A.X, A.Y);A.X = newX;A.Y = newY;//b点(newX, newY) = VertexRotate(angle, B.X, B.Y);B.X = newX;B.Y = newY;//C点(newX, newY) = VertexRotate(angle, C.X, C.Y);C.X = newX;C.Y = newY;}

e.Graphics.TranslateTransform(200, 200);调整坐标中心到屏幕中央
1.gif

3D 旋转矩阵

image.png

组合变换(平移 + 旋转)

dx dy dz是平移分量
矩阵乘积表示 组合变换比如
先旋转 再平移
image.png
可以看出左上角是旋转变换,最后一行是平移的变换

 //矩阵相乘public Matrix4X4 Mul(Matrix4X4 m){Matrix4X4 newM = new Matrix4X4();for (int w = 1; w <= 4; w++)for (int h = 1; h <= 4; h++)for (int n = 1; n <= 4; n++){newM[w, h] += this[w, n] * m[n, h];}return newM;}public Vector4 Mul(Vector4 v){Vector4 newV = new Vector4();newV.x = v.x * this[1,1] + v.y * this[2,1] + v.z * this[3,1] + v.w * this[4,1];newV.x = v.x * this[1,2] + v.y * this[2,2] + v.z * this[3,2] + v.w * this[4,2];newV.x = v.x * this[1,3] + v.y * this[2,3] + v.z * this[3,3] + v.w * this[4,3];newV.x = v.x * this[1,4] + v.y * this[2,4] + v.z * this[3,4] + v.w * this[4,4];return newV;}
 //三角形利用矩阵乘法进行变换public void Transform(Matrix4X4 m){this.a = this.A = m.Mul(this.A);this.b = this.B = m.Mul(this.B);this.c = this.C = m.Mul(this.C);}public void Draw(Graphics g){g.DrawLines(new Pen(Color.Red,2),this.Get2DPointFArr());}private PointF[] Get2DPointFArr(){PointF[] arr = new PointF[4];arr[0] = Get2DPointF(this.a);arr[1] = Get2DPointF(this.b);arr[2] = Get2DPointF(this.c);arr[3] = arr[0];return arr;}private PointF Get2DPointF(Vector4 v){PointF p = new PointF();p.X = (float)(v.x / v.w);p.Y = (float)(v.y / v.w);return p;}

2.gif
此时只有单纯的旋转。
如果在Z方向上添加透视投影矩阵

   m_view = new Matrix4X4();m_view = [1, 1] = 1;m_view = [2, 2] = 1;m_view = [3, 3] = 1;m_view = [4, 3] = 250;m_view = [4, 4] = 1;
 m_projection = new Matrix4X4();m_projection = [1, 1] = 1;m_projection = [2, 2] = 1;m_projection = [3, 3] = 1;m_projection = [3, 4] = 1.0 / 250;

3.gif
即可。

透视投影

image.png
小孔成像。利用相似三角形计算物体轮廓

透视投影矩阵

image.png

最终只有x y表达,实际的x 坐标需要 透视除法 (x / (z/d))

撤销变换

变换矩阵A * 变换矩阵A的逆矩阵

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

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

相关文章

【docker系列】docker命令篇

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

中科亿海微除法器(DIVIDE)

技术背景 技术概述 FPGA实现除法运算是一个比较复杂的过程&#xff0c;因为硬件逻辑与软件程序的区别。如果其中一个操作数为常数&#xff0c;可以通过简单的移位与求和操作代替&#xff0c;但用硬件逻辑完成两变量间除法运算会占用较多的资源&#xff0c;电路结构复杂&#xf…

数据结构 / 顺序表的遍历

1. 顺序表的遍历函数代码 /**判断顺序表是否为空* */int is_list_empty(sqlist *list) {return list->len 0 ? 1 : 0; }/**顺序表遍历** */void output(sqlist *list) {if(NULLlist||1is_list_empty(list)){printf("list is NULL!\n");return;}for(int i0; i&…

【虚拟机Ubuntu 18.04配置网络】

虚拟机Ubuntu 18.04配置网络 1.配置网络连接方式,查看自己网关 2.修改主机名 3.修改系统配置1.配置网络连接方式,查看自己网关 选择虚拟机镜像设置网络连接模式,可以选择桥接或者NAT连接(我这里选择是NAT连接) 确定自己网关&#xff0c;可以在虚拟机 -》 编辑 -》虚拟网络编…

springboot(ssm高校大学生评奖评优系统 奖学金管理系统Java(codeLW)

springboot(ssm高校大学生评奖评优系统 奖学金管理系统Java(code&LW) 开发语言&#xff1a;Java 框架&#xff1a;ssm/springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.7&#xff08;或8.…

TypeScript和JavaScript有什么不同

TypeScript是JavaScript的一个超集&#xff0c;它添加了静态类型检查和其他一些高级特性。下面是TypeScript和JavaScript之间的一些主要区别&#xff1a; 类型系统&#xff1a;TypeScript引入了静态类型检查&#xff0c;可以在开发过程中捕获潜在的类型错误&#xff0c;并提供更…

Kubernetes之kubeadm集群部署篇—k8s集群部署

文章目录 1、启动集群1.1 新增 kubernetes yum源&#xff1a;(所有节点)1.2 安装kubelet kubeadm kubectl &#xff08;master节点&#xff09;1.3 启动k8s-master节点 &#xff08;master节点&#xff09; 二、部署 flannel &#xff08;master节点&#xff09;2.1 下载flanne…

SpringBoot通过URL请求图片方法

通过URL请求图片方法 来源 如果你想通过controller动态返回图片&#xff0c;你可以参考以下示例代码:java // 使用PathVariable注解&#xff0c;获取请求路径中的参数 GetMapping(value "/image/{name}", produces MediaType.IMAGE_JPEG_VALUE) ResponseBody pub…

Android 10.0 mtp模式下连接pc后显示的文件夹禁止删除copy重命名功能实现

1.前言 在10.0的系统开发中,usb连接pc端的时候有好几种模式,在做otg连接pc端的时候,改成mtp模式的时候,在pc端可以看到产品设备 的显示的文件夹的内容,对于产品设备里面的文件在pc端禁止做删除重命名拷贝等操作功能的实现 2.mtp模式下连接pc后显示的文件夹禁止删除copy重命…

【计算机视觉】【图像处理综合应用】路沿检测

实验内容&#xff1a;针对给定的视频&#xff0c;利用图像处理基本方法实现道路路沿的检测&#xff1b; 提示&#xff1a;可利用Hough变换进行线检测&#xff0c;融合路沿的结构信息实现路沿边界定位&#xff08;图中红色的点位置&#xff09;。 处理视频文件 处理视频文件的主…

springboot函数式web

1.通常是路由(请求路径)业务 2.函数式web&#xff1a;路由和业务分离 一个configure类 配置bean 路由等 实现业务逻辑 这样实现了业务和路由的分离

codeforces 1851F

题目链接 题目大意&#xff1a;给你一个长度为n的数组a, 和一个整数k(2<n<2e5, k<30, a[i]<pow(2,k))。 任选一个x&#xff0c;求(a[i] ^ x) & (a[j] ^ x) 的最大值(1<i,j<n, i!j, x<pow(2,k))。 由于中间有个&&#xff0c;所以我们要求两个数最高…

/dev/root

文章目录 后背发凉软链接搞的鬼破案 后背发凉 使用 mount 命令查看设备挂载情况 /# mount /dev/root on / type ext4 (rw,noatime) proc on /proc type proc (rw,nosuid,nodev,noexec,noatime) sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,noatime) cgroup2 on /sys/f…

Exclude,Extract

在TypeScript中&#xff0c;Exclude<T, U>和Extract<T, U>都是条件类型&#xff0c;用于根据类型U排除或提取类型T中的某些部分。 其中&#xff0c;Exclude<T, U>返回一个新类型&#xff0c;该类型是T中不属于U的部分&#xff1b;而Extract<T, U>返回一…

【Rust日报】2023-11-25 CXX-Qt 0.6 发布

CXX-Qt 0.6 发布 CXX-Qt 是一组 Rust 包&#xff0c;用于创建与 Qt 的双向 Rust ⇄ C 绑定。它可用于使用 CMake 将 Rust 集成到 C 应用程序中&#xff0c;或使用 Cargo 构建 Rust 应用程序。 CXX-Qt 提供了用于在 Rust 中实现 QObject 子类的工具&#xff0c;可在 C、QML 和 J…

Spring MVC程序开发

所谓的Spring MVC程序开发&#xff0c;其实也是一个Spring Boot项目。 MVC是Model View Controller的缩写&#xff0c;它是软件工程中的一种软件架构模式&#xff0c;它把软件系统分为模型&#xff0c;视图&#xff0c;控制器三个部分。 项目使用什么技术实现的&#xff1f;&a…

【nowcoder】BM3 链表中的节点每k个一组翻转

题目&#xff1a; 题目分析&#xff1a; 题目解析转载&#xff1a; 代码实现&#xff1a; package BMP3;import java.util.List;class ListNode {int val;ListNode next null;public ListNode(int val) {this.val val;} } public class BM3 {/*** 代码中的类名、方法名、参…

13-21-普通数组、矩阵

LeetCode 热题 100 文章目录 LeetCode 热题 100普通数组13. 中等-最大子数组和14. 中等-合并区间15. 中等-轮转数组16. 中等-除自身以外数组的乘积17. 困难-缺失的第一个正数 矩阵18. 中等-矩阵置零19. 中等-螺旋矩阵20. 中等-旋转图像21. 中等-搜索二维矩阵II 本文存储我刷题的…

一般将来时

一般将来时 概念 表示将要发生的动作或打算、计划准备做某事 时间 tomorrow 明天 the day after tomorrow 后天 next week 下周 next weekend 下周末 next month 下个月 next year 明年 ...句子结构 主语 be&#xff08;am/is/are&#xff09;going to do … 计划,…

面试题目总结(一)

1. 谈谈数据库的乐观锁和悲观锁 乐观锁和悲观锁是数据库并发控制中常用的两种策略&#xff0c;用于处理多个事务同时访问和修改同一个数据时的并发冲突问题。 数据库的乐观锁是指在读取数据时&#xff0c;不对数据进行加锁&#xff0c;而是在更新数据时检查数据版本是否发生变…