使用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 ...
随机推荐
- oracle触发器详解(转)
触发器是许多关系数据库系统都提供的一项技术.在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块. 8.1 触发器类型 触发器在数据库里以独立的对象存储,它与存储过 ...
- lintcode 中等题:find the missing number 寻找缺失的数
题目 寻找缺失的数 给出一个包含 0 .. N 中 N 个数的序列,找出0 .. N 中没有出现在序列中的那个数. 样例 N = 4 且序列为 [0, 1, 3] 时,缺失的数为2. 注意 可以改变序 ...
- apache配置优化
最近参加了很多面试,多多少少有点小感悟,可以说观念转变了不少,特别是对于作为一个开发人员的定位,原来只是认为开发人员就只需要写好代码就行了,所以只需要有数据结构,算法,设计模式,重构方面的知识就行了. ...
- application.xml定时
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- *windows文件显示后缀名
- mongodb group分组
先插入测试数据: for(var i=1; i<20; i++){ var num=i%6; db.test.insert({_id:i,name:"user_&quo ...
- java服务器知识
http://blog.csdn.net/chenyi8888/article/details/4484641 http://blog.csdn.net/chenyi8888/article/deta ...
- 1137. Bus Routes(dfs)
1137 做过一样的 怎么又忘了 再一次搜超时 不用回溯 #include <iostream> #include<cstdio> #include<cstring> ...
- 获取Android 手机屏幕宽度和高度以及获取Android手机序列号
1.获取Android 手机屏幕宽度 1 DisplayMetrics dm = new DisplayMetrics(); 2 this.getWindowManager().getDefaultD ...
- 实际举例C#引用类型和值类型的区别<网摘>
我们都知道,c#的两大数据类型分别为值类型和引用类型.很多人或许闭着眼睛都能说出值类型包括简单类型.结构体类型和枚举类型,引用类型包括自定义类.数组.接口.委托等,但是当被问及到二者之间的联系和区别, ...