使用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 ...
随机推荐
- DP方程及意义
01背包 有N件物品和一个容量为V的背包.第i件物品的费用(即体积,下同)是w[i],价值是c[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路: 这是最基 ...
- 应用程序加载外部字体文件(使用AddFontResource API函数指定字体)
/* MSDN: Any application that adds or removes fonts from the system font table should notify other w ...
- 写个Python练练手吧
在Python的交互式命令行写程序,好处是一下就能得到结果,坏处是没法保存,下次还想运行的时候,还得再敲一遍. 所以,实际开发的时候,我们总是使用一个文本编辑器来写代码,写完了,保存为一个.py文件, ...
- C++:类的成员函数定义方式
1.成员函数的第一种定义方式:在类声明中只给出成员函数的原型,而将成员函数的定义 放在类的外部. 返回值类型 类名::成员函数名(参数表) { 函数体 } class Point{ pub ...
- Servlet编写登录界面
package com.mhb; import java.io.IOException;import java.io.PrintWriter; import javax.servlet.Servlet ...
- kali 安装中文输入法
(1)apt-get install fcitx-googlepinyin (2)你希望继续执行吗?Y (3)连续执行数次 (4)init 6(命令行重启)
- 一些CSS技巧
1.网页LOGO背景居中 html { background: #f5f7f9 url(img/logo.png) no-repeat center center fixed; backgro ...
- UDP丢包和无序 问题的解决方法
最近在做一个项目,在这之前,做了个验证程序. 发现客户端连续发来1000个1024字节的包,服务器端出现了丢包现象. 纠其原因,是服务端在还未完全处理掉数据,客户端已经数据发送完毕且关闭了. 我用过s ...
- 学习Hadoop的资料
1)Cygwin相关资料 (1)Cygwin上安装.启动ssh服务失败.ssh localhost失败的解决方案 地址:http://blog.163.com/pwcrab/blog/static/1 ...
- Jenkins iOS – Git, xcodebuild, TestFlight
Introduction with Jenkins iOS If you are new to continuous integration for mobile platforms then you ...