本文主要是介绍飞越星空屏保实现:3D数学之透视变换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近想实践总结下3D图形学的一些内容
所以,就做出了这个东西。
本来打算用C++写的,
但考虑到MFC的丑陋和C++使用GDI/GDI+的各种不方便
遂用C#实现之,以简化实现手段。
呵呵,C#是做某些实验算法/测试的不错选择!
先上效果图:
gif动画录制的效果不太好,实际程序会流畅得多。
程序界面也可以放大,全屏。
本程序可执行下载:
http://download.csdn.net/detail/stevenkylelee/4927451
本程序工程源代码下载:
http://download.csdn.net/detail/stevenkylelee/4927775
用C#的一个好处是,双缓冲的实现很简单。
不像在C++中,要先CreateXXX什么的,
创建位图,创建DC,在其上画,
最后再Bitblt到显示DC。
说明一下,我的这个程序吧。
每个白点都是一个3D向量对象,它的运算完全是3D的。
那些白点向观察者方向运动时,
逻辑上只是自减自加其Z坐标的值。
其实,对于3D,我现在也是一个初学者,
我只是按照公式简单实现了坐标的“透视变换”,“屏幕变换”而已
本程序的整体结构用的是做游戏的方式。
帧率被设置为60fps,
C#的GDI+是否能达到60fps,
我就没有测试过了。
Render方面,
当摄像机位于原点,没有旋转时,这个实现会变得很简单
而我在做程序时压根就没考虑过摄像机的问题,呵呵。
本程序核心只有2步:
1.世界坐标经过透视变换后到视平面的映射
2.用第一步的结果,转换成屏幕坐标
透视变换的公式是:
x_per = d * x0 / z0
y_per = d * x0 / z0
其实就是:
透视变换后的X坐标 = 视距 * 点的世界坐标X / 点的世界坐标Z
透视变换后的Y坐标 = 视距 * 点的世界坐标Y / 点的世界坐标Z
截图一本书上的图示吧:
其实这个公式不难理解,
基于相似三角形,
就是用视距d在视平面上的那个点 与 坐标Z的比值
来求三角形缩小后,y在视平面的位置。
大白话说就是,
想象一个三角形缩小后,
某个点从某个位置移动到另一个位置上。
如果,你下载了我的工程源代码
可以做这样一个实验,
在FrmMain.cs文件中,
把 int m_ViewDistance = 320 ;改成
int m_ViewDistance = 50;
再编译运行一下,看看会怎样。
你会发现,白点的运动速度变快了
实际上,它距离观察者较远的时候,运动是慢的,
当它距离观察者近时,运动就变快了。
这是怎么回事呢?
实际上,点的运动速度并没有改变。
修改那句代码,只是改变了视距。
”物理世界“中那些点的速度一点没有变化,
只是,观察者看到的景象变化了。
我画了一个图来分析:
从这个图可以看到。不管视距是多少
当点向你飞来,它在远处的运动,
投影到视平面上y坐标的运动轨迹,都是缓慢的
当它越靠近你,你就会感到它在你的视觉中运动越快
而视距越短就会在更大的y空间内“剧烈地”变化,
所以,修改视距320为50,就会看到好像它飞得更快了
以上是我个人浅显的认识总结和分析,
如有错误和不足,欢迎高手纠正补充
最后,谁想把这个程序改成屏保谁就搞吧
反正,我源代码都上传了
这篇关于飞越星空屏保实现:3D数学之透视变换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!