使用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 ...
随机推荐
- No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK? 问题
maven编译项目时出错,提示信息如下: [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3 ...
- shell脚本 -d 是目录文件,那么-e,-f等说明
-e filename 如果 filename存在,则为真 -d filename 如果 filename为目录,则为真 -f filename 如果 filename为常规文件,则为真 -L fil ...
- 转:Servlet的url匹配以及url-pattern详解
Servlet是J2EE开发中常用的技术,使用方便,配置简单,老少皆宜.估计大多数朋友都是直接配置用,也没有关心过具体的细节,今天遇到一个问题,上网查了servlet的规范才发现,servlet中的u ...
- UVa 1453 - Squares 旋转卡壳求凸包直径
旋转卡壳求凸包直径. 参考:http://www.cppblog.com/staryjy/archive/2010/09/25/101412.html #include <cstdio> ...
- .Net MVC API初试
新建.net mvc api项目后,直接运行,默认会访问http://localhost:xxxx/Home/Index页面,这个页面不是要访问的API页面. 从项目的目录可以看出,默认的API页面访 ...
- TagHighlight
:UpdateTypesFile 命令会生成相应的上色高亮文件(生成的着色文件可以叫types_c.taghl)还有相应的tags文件,寻找tags或taghl_config.txt确定project ...
- MapReduce 中的Map后,sort不能对中文的key排序
今天写了一个用mapreduce求平均分的程序,结果是出来了,可是没有按照“学生名字”进行排序,如果是英文名字的话,结果是排好序的. 代码如下: package com.pro.bq; import ...
- HBase的Shell操作
1.进入命令行 bin/hbase shell 2.输入help 查看各种命令组. 命令是分组的,可以执行help 'general'查看general组的命令. 3.常用命令 --显示有哪些表 li ...
- C# 按拼音/笔划 排序的简单示例(转)
class Program { static void Main(string[] args) { string[] arr = { "趙(ZHAO)", "錢(QIAN ...
- java实现最基础的socket网络通信
一.网络通信基础 网络中存在很多的通信实体,每一个通信实体都有一个标识符就是IP地址. 而现实中每一个网络实体可以和多个通信程序同时进行网络通信,这就需要使用端口号进行区分. 二.java中的基本网络 ...