使用C语言实现二维,三维绘图算法(1)-透视投影
使用C语言实现二维,三维绘图算法(1)-透视投影
---- 引言----
每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其实想想, Win32中既然存在画线画点函数, 利用计算机图形学的知识, 我们用可以用纯C调用Win32实现三维绘图, 完全不用借助OpenGL和DirectX, 这有重复造轮子的嫌疑, 但是自己动手实现一遍, 毕竟也是有意义的.
[效果演示]
线框效果, 隐藏面采用虚线

颜色填充后效果

[透视投影理论]
分析:假定投影中心在Z轴上(z=-d处),投影面在xoy面上,与z轴垂直,d为投影面与=投影中心的距离。现求空间一点p(x, y, z)的透视投影p'(x', y', z')点的坐标。

根据相似三角形对应边成比例关系有:

写成矩阵形式如下:


透视缩小效应:物体的透视投影的大小与物体到投影中心的Z方向距离成反比。

特点:透视投影的深度感更强,更加具有真实感,但透视投影不能够准确反映物体的大小和形状。
(1)透视投影的大小与物体到投影中心的距离有关。
(2)一组平行线若平行于投影平面时,它们的透视投影仍然保持平行。
(3)只有当物体表面平行于投影平面时,该表面上的角度在透视投影中才能被保持。
灭点:透视投影中不平行于投影面的平行线的投影会汇聚到一个点,这个点称为灭点(Vanishing Point)。
坐标轴方向的平行线在投影面上形成的灭点称作主灭点。 透视投影可以按照主灭点的个数分类:
(1)一点透视有一个主灭点,即投影面与一个坐标轴正交,与另外两个坐标轴平行。
(2)二点透视有两个主灭点,即投影面与两个坐标轴相交,与另一个坐标轴平行。
(2)三点透视有三个主灭点,即投影面与三个坐标轴都相交。

[编程实现要点]
计算三维投影点的函数
void Calc3DPoint(void)
{
x = (-)*x;
xa = cr1*x - sr1*z;
za = sr1*x + cr1*z; x = cr2*xa + sr2*y;
ya = cr2*y - sr2*xa; z = cr3*za - sr3*ya;
y = sr3*za + cr3*ya; x=x+mx; y=y+my; z=z+mz; sx = d*x/z;
sy = d*y/z;
return;
}
逐个画出各个侧面, 并进行消隐形探测
...
surface1:
x1=B1[][]; y01=B1[][]; z1=B1[][];
x2=B1[][]; y2=B1[][]; z2=B1[][];
x3=B1[][]; y3=B1[][]; z3=B1[][];
VisibilityTest(); if(sp>) goto surface2; sx1=B2[][]; sy1=B2[][];
sx2=B2[][]; sy2=B2[][];
sx3=B2[][]; sy3=B2[][];
sx4=B2[][]; sy4=B2[][];
sx5=B3[][]; sy5=B3[][];
DrawPoly(); surface2:
x1=B1[][]; y01=B1[][]; z1=B1[][];
x2=B1[][]; y2=B1[][]; z2=B1[][];
x3=B1[][]; y3=B1[][]; z3=B1[][];
VisibilityTest(); if(sp>) goto surface3; sx1=B2[][]; sy1=B2[][];
sx2=B2[][]; sy2=B2[][];
sx3=B2[][]; sy3=B2[][];
sx4=B2[][]; sy4=B2[][];
sx5=B3[][]; sy5=B3[][];
DrawPoly();
...
使用C语言实现二维,三维绘图算法(1)-透视投影的更多相关文章
- 使用C语言实现二维,三维绘图算法(3)-简单的二维分形
使用C语言实现二维,三维绘图算法(3)-简单的二维分形 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...
- 使用C语言实现二维,三维绘图算法(2)-解析曲面的显示
使用C语言实现二维,三维绘图算法(2)-解析曲面的显示 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...
- ARCGIS二维三维导航
在使用代码前需要先安装arcgis10.0 或者10.1都可以 不过本人建议初学者安装10.0比较容易安装.. 安装方式和二维三维地图的加载网上都有,就不在此一一赘述了. 先从基本的功能开 ...
- [图形学] 习题8.12 NLN二维线段裁剪算法实现
Nicholl-Lee-Nicholl二维线段裁剪算法相对于Cohen-Sutherland和Liang-Barsky算法来说,在求交点之前进行了线段端点相对于几个区域的判断,可以确切的知道要求交点的 ...
- C语言之二维数组
二维数组 还是一个数组,只不过数组中得每一个元素又是一个数组 1). 声明语法 类型 数组名[行][列]; 例: int nums[2][3];//2行3列的二维数组,保存的数据类型是int类型 c ...
- VC、OpenGL、ArcGIS Engine开发的二维三维结合的GIS系统
一.前言 众所周知,二维GIS技术发展了近四十年,伴随着计算机软硬件以及关系型数据库的飞速发展,二维GIS技术已日臻完善.在对地理信息的分析功能上有着无可比拟的优势.一些宏观的地理信息,一维的地理信息 ...
- ARCGIS二维三维互动
当对三维模型进行操作时(如导航.平移)二维地图自动跟进. private void Synckron() { m_pGlobe = this._GlobeControl.Globe; m_pMap = ...
- ARCGIS二维三维放大缩小
private void ULZoomPan() { ESRI.ArcGIS.SystemUI.ICommand com = new ControlsGlobeFixedZoomOutCommand( ...
- ARCGIS二维三维平移
private void glZoomPan() { ESRI.ArcGIS.SystemUI.ICommand com = new ControlsGlobePanTool(); com.OnCre ...
随机推荐
- untiy 插件工具: 游戏中 策划数据Excel 导出到项目中
https://github.com/zhutaorun/Excel2Unity,这个项目是直接下载就可以用的, 其中原理和相关的解释 http://blog.csdn.net/neil3d/arti ...
- 教育行业SaaS选型 需要注意的三点问题
2008年经济危机席卷全球,造成世界范围内的金融动荡,国内各行业虽然都面临了不小的冲击,但是在危机面前,中国的教育行业却逆势而上,硕果累累.据统计,2008年教育行业的投资案例达18起,投资金额18. ...
- 目标检测的图像特征提取之(二)LBP特征
LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像年提出,用于纹理特征提取.而且,提取的特征是图像的局部的纹理特征: 1.LBP特征的描述 原始的LBP算子定义为在3* ...
- [cocoapods]cocoapods问题解决
错误1. While executing gem no such name 错误原因:gem 网址被挡住了. 解决办法:设置https://ruby.taobao.org/ 详情参考 http://w ...
- 素数筛法--SPOJ Problem 2 Prime Generator
质数(prime number)又称素数,除了1和它本身外,不能整除以其他自然数,换句话说就是该数除了1和它本身以外不再有其他的因数:否则称为合数.最小的质数是2. 要判断一个整数N是不是质数很简单, ...
- MariaDB10.2.X-新特性1-支持分析函数
前言:前段时间看到MariaDB10.2出测试版本了,心想有什么新特性玩玩,大家都知道MySQL不支持分析函数,但是MariaDB10.2.X支持分析函数了, 1.表结构 CREATE TABLE ` ...
- rundeck email配置文件配置
最近工作中用到了一个任务管理软件rundeck,其中有个很重要的功能就是任务执行提醒,用邮件执行,其中一些配置项,官网没有详细的说明,在网上也没有一个整体的说明,在次跟大家共享下,rundeck的使用 ...
- hdu 1243 反恐训练营(dp 最大公共子序列变形)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1243 d[i][j] 代表第i 个字符与第 j 个字符的最大的得分.,, 最大公共子序列变形 #inclu ...
- iOS开发:为xcode项目添加git仓储
现在apple官网下载Command Line Tools 对应mac版本和xcode版本,记录地址:https://developer.apple.com/downloads/ 找到mac的终端,c ...
- HNOI2004宠物收养所(平衡树)
treap! var i,n,x,y,ans,a,b,root,tot,ft:longint; l,r,s,v,hr:..] of longint; procedure r_rotate(var x: ...