计算机图形学-变换基础

news2024/11/28 6:43:44

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

变换

仿射变换和线性变换
线性:旋转 缩放 镜像 切变
放射: 平移
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.coloradmin.cn/o/1256898.html

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

相关文章

案例026:基于微信的原创音乐小程序的设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

7000字详解 动态代理(JDK动态代理 CGLIB动态代理)与静态代理

代理模式 1. 代理模式 概念2. 静态代理3. 动态代理3.1.JDK动态代理3.2.CGLIB动态代理3.3. JDK动态代理和CGLIB动态代理区别 4.静态代理和动态代理区别5.篇末 1. 代理模式 概念 代理模式是一种设计模式。 使用代理对象来替代真实对象&#xff0c;用代理对象去访问目标对象。这样…

ROS2智能小车基本原理图

我觉得这样意思已经表的很清楚了 这个图很重要&#xff0c;有了这个图&#xff0c;就可以积累每个部分的代码了&#xff0c;如果没有这个图&#xff0c;那么每次都只能是测试&#xff0c;以前的代码都会需要重新写一次。不过第一次训练也许更重要&#xff0c;这也是不可避免的…

使用STM32与MFRC522 IC进行RFID卡的读取与识别(含代码)

利用STM32与MFRC522 IC进行RFID卡的读取和识别&#xff0c;可以实现对RFID卡的读取和获取卡片标识信息。MFRC522 IC是一种高集成度的13.56MHz RFID芯片&#xff0c;常用于门禁系统、物流跟踪和智能支付等领域。下面将介绍如何使用STM32与MFRC522 IC进行RFID卡的读取和识别&…

Mycat实现读写分离

Mycat实现读写分离 Mycat支持MySQL主从复制状态绑定的读写分离机制。这里实现的也是基于MySQL主从复制的读写分离。 MySQL主从复制配置 首先要配置MySQL的主从复制&#xff0c;这里配置的是一主一次从。可以参考下面的文章。 https://blog.csdn.net/wsb_2526/article/detail…

【c++随笔14】虚函数表

【c随笔14】虚函数表 一、虚函数表&#xff08;Virtual Function Table&#xff09;1、定义2、查看虚函数表2.1、 问题&#xff1a;三种类型&#xff0c;包含一个int类型的class、一个int类型的变量、int类型的指针&#xff1a;这三个大小分别是多少呢&#xff1f;2.2、怎么发现…

JVM 内存管理深度剖析

1、JVM 基础知识 1.1 JVM 与操作系统的关系 JVM 能识别 class 后缀的文件&#xff0c;并且能够解析它的指令&#xff0c;最终调用操作系统上的函数&#xff0c;完成指定操作。操作系统并不认识这些 class 文件&#xff0c;是 JVM 将它们翻译成操作系统可识别的机器码&#xf…

【古诗生成AI实战】之二——项目架构设计

[1] 项目架构 在我们深入古诗生成AI项目的具体实践之前&#xff0c;让我们首先理解整个项目的架构。本项目的代码流程主要分为三个关键阶段&#xff1a; 1、数据处理阶段&#xff1b;   2、模型训练阶段&#xff1b;   3、文本生成阶段。 第一步&#xff1a;在数据处理阶段…

WordPress无需插件禁用WP生成1536×1536和2048×2048尺寸图片

我们在使用WordPress上传图片媒体文件的时候&#xff0c;是不是看到媒体库中有15361536和20482048的图片文件&#xff0c;当然这么大的文件会占用我们的服务器空间&#xff0c;如何禁止掉呢&#xff1f; function remove_default_image_sizes( $sizes) {unset( $sizes[1536x15…

Gee教程1.HTTP基础

标准库启动web服务 Go语言内置了 net/http库&#xff0c;封装了HTTP网络编程的基础的接口。这个Web 框架便是基于net/http的。我们先回顾下这个库的使用。 package mainimport ("fmt""log""net/http" )func main() {//可以写成匿名函数(lambda…

Java 注解在 Android 中的使用场景

Java 元注解有 5 种&#xff0c;常用的是 Target 和 Retention 两个。 其中 Retention 表示保留级别&#xff0c;有三种&#xff1a; RetentionPolicy.SOURCE - 标记的注解仅保留在源码级别中&#xff0c;并被编译器忽略RetentionPolicy.CLASS - 标记的注解在编译时由编译器保…

树状数组 / pbds解法 E2. Array Optimization by Deque

Problem - 1579E2 - Codeforces Array Optimization by Deque - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 树状数组解法 将 a i a_i ai​插入到队头&#xff0c;贡献为&#xff1a;原队列中所有比 a i a_i ai​小的数的数量将 a i a_i ai​插入到队尾&#xff0c;贡献为&a…

深信服超融合一体机提示:内存ECC

PS&#xff1a;此事件分享主要来源于季度巡检时发现的超融合一体机红灯闪烁异常&#xff0c;接入IPMI端口查看日志发现持续提示内存ECC&#xff1b; 因为是只有3.05这一天发现了有这个告警的提示&#xff0c;所以当时清除了日志以后重启了BMC服务就解决了&#xff1b;但是如果清…

常见树种(贵州省):021冬青、连香树、白辛树、香合欢、云贵鹅耳枥、肥牛树、杜英、格木、黄连木、圆果化香树、南天竹

摘要&#xff1a;本专栏树种介绍图片来源于PPBC中国植物图像库&#xff08;下附网址&#xff09;&#xff0c;本文整理仅做交流学习使用&#xff0c;同时便于查找&#xff0c;如有侵权请联系删除。 图片网址&#xff1a;PPBC中国植物图像库——最大的植物分类图片库 一、冬青 …

MyBatis插入操作返回主键报错问题记录

一开始用直接传参数的方法写的插入操作 StudentMapper.java接口 Integer insertStudent(Param("sname") String name,Param("sage") int age); 然后在网上搜了返回主键的方法 StudentMapper.xml: <insert id"insertStudent" useGenerat…

简易版王者荣耀

所有包和类 GameFrame类 package newKingOfHonor;import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayList;im…

【操作系统】Linux操作系统中命令行参数与环境变量

本篇要分享的内容关于Linux新操作系统中命令行参数。 命令行参数本质上还是作为以后的环境变量的基础来学习的&#xff0c;所以在接触更高难度的内容之前先学习基础。 以下为本篇目录 目录 1.main函数的参数&#xff1f; 2.命令行解释器意义 3.环境变量 3.1.PATH环境变量…

手把手教会你--渗透实战--Hack The Box-Starting Point-Meow--持续更新

有什么问题&#xff0c;请尽情问博主&#xff0c;QQ群796141573 前言 前言 请务必跟着博主复现一遍 参考&#xff1a; Hack The Box-Starting Point-Meow

工业级 S25HS01GTDPBHV030 NOR闪存,L9305EP汽车级驱动器IC,LMK03318RHSR时钟发生器,PLL(中文资料)

一、工业级 S25HS01GTDPBHV030 Semper™ NOR闪存 S25HS01GT SEMPER™ NOR Flash闪存系列是英飞凌高性能、安全而可靠的 NOR Flash解决方案。 它集成了适用于汽车、工业、通信等广泛应用的关键安全功能。 凭借 SEMPER™ NOR Flash闪存&#xff0c;英飞凌推出了业界首款符合 ASI…

设计模式—接口隔离原则(ISP)

1.背景 2002 年罗伯特C.马丁给“接口隔离原则”的定义是&#xff1a;客户端不应该被迫依赖于它不使用的方法&#xff08;Clients should not be forced to depend on methods they do not use&#xff09;。该原则还有另外一个定义&#xff1a;一个类对另一个类的依赖应该建立…