当前位置: 首页 > article >正文

计算机图形学-变换基础

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

变换

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

相关文章:

  • C语言之图像文件的属性
  • Spring 中的事件驱动模型
  • C# 的 NLog 库高级进阶
  • Jenkins 启动
  • 【LeetCode100】--- 寻找重复数
  • mongodb详解二:基础操作
  • Linux 面试题(一)
  • zookeeper 单机伪集群搭建简单记录
  • AUTOSAR汽车电子嵌入式编程精讲300篇-汽车CAN总线安全性模糊测试
  • docker network容器网络通信
  • 机器学习【02】在 Pycharm 里使用 Jupyter Notebook
  • 【第二部分:结构】ARM Realm Management Monitor specification
  • Android 10.0 mtp模式下连接pc后显示的文件夹禁止删除copy重命名功能实现
  • Jenkins 保姆级教程
  • 一篇文章完成Hbase入门
  • SpringMVC(三)
  • (C)一些题4
  • Python与ArcGIS系列(十)要素查询与选择
  • ESP32控制数码管实现数字叠加案例
  • 【学习记录】从0开始的Linux学习之旅——驱动模块编译与加载
  • 开源与闭源:大模型未来的发展之争
  • Sass的嵌套CSS 规则详细教程
  • C++面试,const的使用
  • 【LLS-Player】音视频帧的回调过程
  • 基于element自动表格
  • 【数据库】缓冲区管理器结构,几种常用替换策略分析,pin钉住缓冲区块防止错误的替换,以及缓冲区管理带来的代价优化