3D数学基础之C#实现矩阵变换
Never put off what you can do today until tomorrow.
从刚开始学unity各种组件,C#基础,API,到现在的学习Cg语言,学习shaderLab
用了很长时间在细节上,有的时候一些看似非常基础的概念,大致了解下怎么用后,如果不知道其原理,那么,我认为是不可能真正的学会一种技术的。
本节就来实现矩阵与向量之间的计算,,我们将自己实现向量的类和矩阵的类,这也就代表着,我们必须实现基本的Mul功能
tools:visual studio 2015 建议安装插件:resharper.
step1
首先,关于C#语法,以及内置函数,这里不会解释的,大家可以搜索API或者MSDN
为了不在代码处做过多数学赘述,第一步将会介绍矩阵的几何变换(3种)
矩阵的平移变换Translation
将三维空间中的一个点移动到另一个点,随便Google了一张图
其中平移变换的结果为等号左侧,平移变换的计算在等号右侧,回想下矩阵乘法的运算规则
这里的运算为
X偏移量 = (X x 1 + Y x 0 + 1 x Tx) = X + Tx 也就是在X上的偏移量
同理: Y的偏移量 = (X x 0 + Y x 1 + 1 x Ty) = Y + Ty 也就是在Y上的偏移量
算到这里大家应该明白为什么三维向量和矩阵的运算,要用到Vector4了,因为w = 1方便我们跟矩阵做乘法。
矩阵的缩放变换
将模型放大或者缩小,本质也是对模型上每个顶点进行放大和缩小(顶点坐标值变大或变小)
缩放变换跟平移变换没差的 ,还是找个图把公式看下
矩阵的旋转变化
这个是本系列中会用到的,很重要,这里只说绕坐标轴旋转,来源Google图片
绕X轴旋转:顶点的X坐标不变,y坐标和z坐标绕X轴旋转θ度,旋转的正方向为顺时针方向,也就是逆时针是正方向,从图中可以看出,X的旋转结果 = X x 1 + Y x 0 + Z x 0 + 1 x 0 = X 这里可以解释绕X轴旋转X轴的顶点坐标不变
Y的旋转结果:X x 0 + Ycos(a) - Zsin(a) + 0 = Ycos(a) - Zsin(a) Z轴的旋转同理,最后,W = 1.
这是绕X轴旋转的公式
上面的分别是绕Y轴旋转和绕Z轴旋转的公式。
刚才讲了公式,并没有写公式的推导(懒/(ㄒoㄒ)/~~)
Ok,知道了矩阵的几何变换,下面进入实战
step2
接下来进入vs2015 新建c#窗体应用程序
我认为还是有必要提一下,本篇只是对3D数学中矩阵的计算加深理解,并不想重复造轮子
(1)首先要实现矩阵和向量的之间的计算,我们要先实现向量类,在资源管理器处右键新建类
class Vector4{public double x, y, z, w;public Vector4(){}public Vector4(double x,double y,double z,double w){this.x = x;this.y = y;this.z = z;this.w = w;}//用来copy外部声明的向量public Vector4(Vector4 vector4){this.x = vector4.x;this.y = vector4.y;this.z = vector4.z;this.w = vector4.w;}}
这个向量类没什么解释的,简单的构造函数重载
(2)接下来实现矩阵类,一样右键新建类
//16个元素class matrix4X4{private double[,] ptsDoubles;//无参构造函数,Initializepublic matrix4X4(){ptsDoubles = new double[4, 4];}//索引器,帮助我们通过传递索引,便可轻松拿到数组每一个元素public double this[int i, int j]{get { return ptsDoubles[i - 1,j - 1]; }set { ptsDoubles[i - 1,j - 1] = value; }}//实现矩阵的乘法规则,这个没啥难的,大家复习下乘法规则就明白了,不要被三个for吓到public matrix4X4 MulMatrix4X4(matrix4X4 m){matrix4X4 newMatrix4X4 = new matrix4X4();for (int w = 0; w <= 4; w++)for (int h = 0; h <= 4; h++)for (int n = 0; n <= 4; n++){newMatrix4X4[w, h] += this[w, n] * m[n,h];}return newMatrix4X4;}//向量与矩阵的乘法运算,返回一个新的向量public Vector4 MulVector4(Vector4 v){Vector4 newVector4 = new Vector4();newVector4.x = v.x * this[1, 1] + v.y * this[2, 1] + v.z * this[3, 1] + v.w * this[4, 1];newVector4.y = v.x * this[1, 2] + v.y * this[2, 2] + v.z * this[3, 2] + v.w * this[4, 2];newVector4.z = v.x * this[1, 3] + v.y * this[2, 3] + v.z * this[3, 3] + v.w * this[4, 3];newVector4.w = v.x * this[1, 4] + v.y * this[2, 4] + v.z * this[3, 4] + v.w * this[4, 4];return newVector4;}}
实现了4x4矩阵的类,该注释的地方都解释了,不明白的私信吧,这里需要注意的是,在c#里或者unity封装好的矩阵里,应该不会用这么简单的方法来定义矩阵,只是加深理解的作用
(3)接下来实现三角形的3D变换,新建Triangle3D类
class Triangle3D{private Vector4 a, b, c;public Vector4 A, B, C;public Triangle3D() { }public Triangle3D(Vector4 a,Vector4 b,Vector4 c){//这里面可以回想一下vector4类里的copy函数,其实就是做一个新的引用this.A = this.a = new Vector4(a);this.B = this.b = new Vector4(b);this.C = this.c = new Vector4(c);}//三角形利用矩阵(m)的乘法进行变换,其实变换的就是顶点public void Transfrom(matrix4X4 m){//这里新声明了私有的向量,对应A,B,C//如果在原有变量上修改,那么就会改变原有变量的引用空间this.a = m.MulVector4(this.A);this.b = m.MulVector4(this.B);this.c = m.MulVector4(this.C);}//绘制三角形到2D窗口,其实放在unity editor里实现会更加easypublic void Draw(Graphics graphics){graphics.TranslateTransform(300,300);graphics.DrawLines(new Pen(Color.Red,2),this.Get2DPointarr());}private PointF[] Get2DPointarr(){//想要在2D平面画出三角形,必须首尾连接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;}}
//接下来是最后的form窗口
//如果对矩阵计算熟悉些的话,这个Form窗体程序还是很好理解的//怎么打开这个事件函数 这个 就不截图了吧。。public partial class Form1 : Form{private int a = 0;private Triangle3D triangle3D;private matrix4X4 m_Scale; //缩放矩阵private matrix4X4 m_rotate; //旋转矩阵private matrix4X4 m_view; //摄像机矩阵private matrix4X4 m_Projection; //视图矩阵//这里面所有的矩阵计算都是根据上面的乘法规则public Form1(){InitializeComponent();m_rotate = new matrix4X4();m_Scale = new matrix4X4();m_Scale[1, 1] = 250;m_Scale[2, 2] = 250;m_Scale[3, 3] = 250;m_Scale[4, 4] = 1;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;}private void Form1_Load(object sender, EventArgs e){//w一定要是1,然后跟矩阵相乘才能进行正常的变换Vector4 a = new Vector4(0,-0.5,0,1);Vector4 b = new Vector4(0.5,0.5,0,1);Vector4 c = new Vector4(-0.5,0.5,0,1);triangle3D = new Triangle3D(a,b,c);triangle3D.Transfrom(m_Scale);}//然后可以开始绘制窗体事件private void Form1_Paint(object sender, PaintEventArgs e){triangle3D.Draw(e.Graphics);}//这个函数是通过time空间添加进来的,目的是随着时间的推移,顶点也跟着变换private void timer1_Tick(object sender, EventArgs e){ //现在是角度a += 2; //计算出弧度double angle = a / 360.0 * Math.PI; //矩阵的几何变换m_rotate[1, 1] = Math.Cos(angle);m_rotate[1, 3] = Math.Sin(angle);m_rotate[2, 2] = 1;m_rotate[3, 1] = -Math.Sin(angle);m_rotate[3, 3] = Math.Cos(angle);m_rotate[4, 4] = 1;matrix4X4 m = m_Scale.MulMatrix4X4(m_rotate);m = m.MulMatrix4X4(m_view);m = m.MulMatrix4X4(m_Projection);triangle3D.Transfrom(m);//重绘this.Invalidate();}}
这样 就可以实现一个三角形在空间视图进行3D旋转
如果看完很蒙 ,可能是我表达的不够仔细,这个程序是我在网上找的,当时对矩阵和向量的计算一点都不了解,看完这个感觉很爽嗒~
如果对整个winform程序不理解不了,那我建议大家可以试着先实现上面的vector4 和 matrix4x4 相信你会有所收获的
最后推荐大家一个vs插件:resharper,以前只支持.net,现在也支持c++了,我之所以在上述程序中没解释的那么详细,就是因为它,它的代码提示功能太强了(中文的提示),当然它的功能还有很多
缺点:太胖啦!!!
3D数学基础之C#实现矩阵变换相关推荐
- 3D数学基础——矩阵变换
文章目录 3D数学基础--矩阵变换 0. 前提假设与符号定义 向量与矩阵 缩放 旋转 平移 1. 缩放 2. 旋转 3. 平移 4. 总结 5. 扩展阅读 6. 手写版 3D数学基础--矩阵变换 0. ...
- 3D数学基础:Matrix4*3类代码清单
Matrix4×3矩阵和RotationMatrix矩阵是<3D数学基础>中的两大矩阵.相比于只能运用于旋转功能的RotationMatrix矩阵,Matrix 4×3矩阵更加一般化,能够 ...
- 《3D数学基础》1.8 混合积
理解数学,理解代码! 大家好,我是老G! 今天为大家带来<3D数学基础>系列视频. 主要讲解:游戏开发中用到的3D数学知识,包括:定义,定理,推论. 也包括他们的推导过程,以及应用举例. ...
- 《3D数学基础》系列视频 1.5 向量的夹角
理解数学,理解代码! 大家好,我是老G! 今天为大家带来<3D数学基础>系列视频. 主要讲解:游戏开发中用到的3D数学知识,包括:定义,定理,推论. 也包括他们的推导过程,以及应用举例. ...
- 《3D数学基础系列视频》1.1向量基本概念
今天带来的是系列最新视频,关于向量的内容 本次视频,主要讲解一下向量的基本概念. 国内网盘: http://pan.baidu.com/s/1c0ldm5U 苹果iTunes U注册代码: 1班:EF ...
- 3d数学基础学习总结
3d数学基础目录 第1章 简介 1.1 什么是3D数学 1.2 为什么选择本书 1.3 阅读本书需要的基础知识 1.4 概览 第2章 笛卡尔坐标系统 2.1 1D数学 2.2 2D笛卡尔数学 2.3 ...
- 《3D数学基础》实践1 向量类代码分析
理解数学,理解代码! 大家好,我是老G! 今天为大家带来<3D数学基础>系列视频. 主要讲解:游戏开发中用到的3D数学知识,包括:定义,定理,推论. 也包括他们的推导过程,以及应用举例. ...
- 3D Math Primer for Graphics and Game Development -- 图形与游戏开发(3D数学基础) (简介)...
3D Math Primer for Graphics and Game Development //z 2014-04-28 13:18:20 L.247'38500 BG57IV3@XCL T20 ...
- 3d数学基础:图形和游戏开发(第2版)_游戏引擎编程需要哪些基本数学知识?
现今,想要从头写一个功能强大的3D引擎,个人的力量恐怕难以胜任,即使能力足够,时间恐怕也不允许.在这个美好的开源时代,你只需具备修改各种引擎的能力便足以满足开发游戏的各项需求.现代游戏引擎的复杂级别已 ...
最新文章
- java.sql.SQLException: Column ‘class‘ not found.异常没有找到列
- 通过apt自动生成建造者模式单线程版代码(一)
- Spring Boot 使用Actuator监控应用
- SQL Server 移动数据库
- PLSQL写给员工涨工资,总裁涨1000,经理涨800,其他员工涨400
- PHP数据类型的转化:(类型) 变量 类型val(变量) settype(变量,类型)
- 代码实现sql编译器_TiDB-Wasm 原理与实现 | Hackathon 优秀项目介绍
- vue实例属性之el,template,render
- 开关量光端机产品特点及应用范围介绍
- 一些常见的HTTP的请求状态码
- 光伏巨头“脱轨” 英利确认债务重组
- 阿里云仓库使用小技巧
- 360推出国内首个工业互联网安全态势感知系统
- java接口之双端队列
- 13.2-“制作一款私有IAP串口下载小工具”之串口IAP的通信协议设计
- 杭州公司java开发工程师常见面试问题
- php think命令,ThinkPHP 使用命令行 (cli) think 调用
- C语言简易程序设计————7、输出特殊图案
- Python随机生成出生日期
- uniapp判断是否打开定位GPS