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#实现矩阵变换相关推荐

  1. 3D数学基础——矩阵变换

    文章目录 3D数学基础--矩阵变换 0. 前提假设与符号定义 向量与矩阵 缩放 旋转 平移 1. 缩放 2. 旋转 3. 平移 4. 总结 5. 扩展阅读 6. 手写版 3D数学基础--矩阵变换 0. ...

  2. 3D数学基础:Matrix4*3类代码清单

    Matrix4×3矩阵和RotationMatrix矩阵是<3D数学基础>中的两大矩阵.相比于只能运用于旋转功能的RotationMatrix矩阵,Matrix 4×3矩阵更加一般化,能够 ...

  3. 《3D数学基础》1.8 混合积

    理解数学,理解代码! 大家好,我是老G! 今天为大家带来<3D数学基础>系列视频. 主要讲解:游戏开发中用到的3D数学知识,包括:定义,定理,推论. 也包括他们的推导过程,以及应用举例. ...

  4. 《3D数学基础》系列视频 1.5 向量的夹角

    理解数学,理解代码! 大家好,我是老G! 今天为大家带来<3D数学基础>系列视频. 主要讲解:游戏开发中用到的3D数学知识,包括:定义,定理,推论. 也包括他们的推导过程,以及应用举例. ...

  5. 《3D数学基础系列视频》1.1向量基本概念

    今天带来的是系列最新视频,关于向量的内容 本次视频,主要讲解一下向量的基本概念. 国内网盘: http://pan.baidu.com/s/1c0ldm5U 苹果iTunes U注册代码: 1班:EF ...

  6. 3d数学基础学习总结

    3d数学基础目录 第1章 简介 1.1 什么是3D数学 1.2 为什么选择本书 1.3 阅读本书需要的基础知识 1.4 概览 第2章 笛卡尔坐标系统 2.1 1D数学 2.2 2D笛卡尔数学 2.3 ...

  7. 《3D数学基础》实践1 向量类代码分析

    理解数学,理解代码! 大家好,我是老G! 今天为大家带来<3D数学基础>系列视频. 主要讲解:游戏开发中用到的3D数学知识,包括:定义,定理,推论. 也包括他们的推导过程,以及应用举例. ...

  8. 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 ...

  9. 3d数学基础:图形和游戏开发(第2版)_游戏引擎编程需要哪些基本数学知识?

    现今,想要从头写一个功能强大的3D引擎,个人的力量恐怕难以胜任,即使能力足够,时间恐怕也不允许.在这个美好的开源时代,你只需具备修改各种引擎的能力便足以满足开发游戏的各项需求.现代游戏引擎的复杂级别已 ...

最新文章

  1. java.sql.SQLException: Column ‘class‘ not found.异常没有找到列
  2. 通过apt自动生成建造者模式单线程版代码(一)
  3. Spring Boot 使用Actuator监控应用
  4. SQL Server 移动数据库
  5. PLSQL写给员工涨工资,总裁涨1000,经理涨800,其他员工涨400
  6. PHP数据类型的转化:(类型) 变量 类型val(变量) settype(变量,类型)
  7. 代码实现sql编译器_TiDB-Wasm 原理与实现 | Hackathon 优秀项目介绍
  8. vue实例属性之el,template,render
  9. 开关量光端机产品特点及应用范围介绍
  10. 一些常见的HTTP的请求状态码
  11. 光伏巨头“脱轨” 英利确认债务重组
  12. 阿里云仓库使用小技巧
  13. 360推出国内首个工业互联网安全态势感知系统
  14. java接口之双端队列
  15. 13.2-“制作一款私有IAP串口下载小工具”之串口IAP的通信协议设计
  16. 杭州公司java开发工程师常见面试问题
  17. php think命令,ThinkPHP 使用命令行 (cli) think 调用
  18. C语言简易程序设计————7、输出特殊图案
  19. Python随机生成出生日期
  20. uniapp判断是否打开定位GPS

热门文章

  1. Hamachi让天堑变通途
  2. 实战解决使用ghost安装系统出现的各种问题
  3. RabbitMq(具体怎么用,看这一篇即可)
  4. 如何将VMIX编辑输出的视频嵌入网页直播
  5. 一个农村小伙网上创业如何年入百万
  6. AFL(American Fuzzy Lop)源码详细解读(1)
  7. c语言辅助防破写法,陈正冲老师讲c语言之const关键字
  8. echarts用富文本标签添在lable中加图片
  9. 解析创新教育体系中的创客教育
  10. 小型电梯尺寸_家用小型电梯-美丽与小尺寸的完美融合