立体图绘制 修复的Word格式.docx
- 文档编号:21581367
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:21
- 大小:54.08KB
立体图绘制 修复的Word格式.docx
《立体图绘制 修复的Word格式.docx》由会员分享,可在线阅读,更多相关《立体图绘制 修复的Word格式.docx(21页珍藏版)》请在冰豆网上搜索。
投影变换是在世界坐标系中建立的,而计算机屏幕所显示的图形是在给定视点和视线方向下的二位屏幕投影。
所以投影变换是整个图形变换的关键。
根据投影中心与投影平面之间距离的不同,投影可分为透视投影和正射投影
(1)透视投影——类似于人对客观世界的观察方式,它的特点是距离视点进的物体比较大,而距离视点远的物体相对较小,这种投影方式的视景空间可以被认为是一个棱台。
它广泛应用于三维地形,模拟,飞行穿越仿真,步行穿越仿真等模拟人眼视觉效果的研究领域
(2)正射投影——是物体直接映射到屏幕上。
正射投影实质上是透视投影的一种特例,即视点在无穷远或视点由一个点变为一个面。
它适用于某地的顶视效果图,地形晕眩图或需要观察模型某一个侧面下带有形变的景观等
11.2用类来抽象三维立体图形
对象是面向对象开发模式的基本成分。
每个对象可用一组属性和它可以执行的一组操作来定义。
属性一般只能通过执行对象的操作来改变。
操作又称作方法或服务,在C++中称为成员函数,它描述了对象执行的功能。
类是一组具有相同数据结构和相同操作的对象的集合。
类的定义包括一组数据属性和在数据上的一组合法操作。
类定义可以视为一个具有类似特性与共同行为对象的模板,用以产生对象。
在一个类中每个对象都是类的实例,它们都可以使用类中提供的函数,一个对象的状态则包含在它的实例变量中,
11.2点类的实现
空间点是最基础的图形构成元素,实现点类之前先介绍一个存储常量的头文件。
11.2.常量头函数
常量头函数const.h存储了点类实现的数值常量,用于存储一些公有的常量。
#if!
defined(_CONST_INCLUDE__)
#define_CONST_INCLUDE_
constdoubleVPOINT_X=1000;
constdoubleVPOINT_Y=1000;
constdoubleVPOINT_Z=1000;
constintNUMBER=100;
constintDELTA=50;
constintPIECE=360;
constdoublePI=3.1415926;
staticboolOnePoint=false;
#endif
/*其中,VPOINT_X,VPOINT_Y,VPOINT_Z是参照观察点的三维世界坐标,参照观察点
Oc=(VPOINT_X,VPOINT_Y,VPOINT_Z)在下文投影透视中使用、
OnePoint确定了透视变换方法,其中true为一点透视,false为正等侧透视
11.2.2点类
我们创建的点类是指立体空间的三维点,有x,y,z三向坐标。
C3dPoint封装了点类,实现了透视投影和坐标转换
头文件3dPoint的主要内容
classC3dPoint:
publicCObject
{
public:
CPointchange();
//实现透视变换,将三维世界坐标转化为二维屏幕坐标
doublex;
doubley;
doublez;
//x,y,z是空间三维点的世界坐标
C3dPoint();
C3dPoint(C3dPoint&
point);
C3dPointoperator=(C3dPoint&
~C3dPoint();
}
11.2.3透视理论
计算机绘制物体的投影图是将三维空间的物体用二维平面上的图形来表示,因此需要进行图形变换。
而进行图形变换的一种行之有效的方法是矩形及其运算,它使的计算机会提简便易行
一点透视即所有投影线交于一点,改点为视点(可理解为观察者眼睛相对于屏幕平面的对称点,符合近大远小的规则
Oc为模拟的视点,(Xs,Ys,Zs)为屏幕坐标系(可理解为屏幕面),(Xw,Yw,Zw)为世界坐标系
视点Oc在世界坐标系下的坐标为(a,b,c),v=
,u=
,
-b/c-ac/uv–a/u0
透视变换矩阵M=a/v-bc/uv--b/u0
0v/u-c/u0
00u1
屏幕是二维平面。
屏幕上任一点的Z值在世界坐标系中的是不变的,可设为Zs
最终的屏幕坐标值(Xs,Ys)=(Xe/Ye)[Xe/Ys,Xe/Ys]
11.2.4透视实现
视点Oc在世界坐标系下的坐标为(a,b,c)设v=
透视变换矩阵M展开后为
一点透视还要进行视点投射
则x”,y”为最终值。
透视变换矩阵视点投射在Change()函数中实现。
该函数的代码如下
CpointC3dPoint:
:
Change()//三维世界坐标转化为二维屏幕坐标
CPointpoint;
doubleu=sqrt(
VPOINT_X*VPOINT_X+VPOINT_Y*VPOINT_Y+VPOINT_Z*VPOINT_Z);
doublev=sqrt(VPOINT_X*VPOINT_X+VPOINT_Y*VPOINT_Y);
if(OnePoint==true)//实现一点透视的矩阵变换
{
doubletempx=(int)((-VPOINT_Y/v)*x+VPOINT_X/v*y);
doubletempy=(int)(-((VPOINT_X*VPOINT_Z)/(u*v))*x-((VPOINT_Y*VPOINT_Z)/(u*v))*y+v/u*z);
doubletempz=-VPOINT_X/u*x-VPOINT_Y/u*y-VPOINT_Z/u*z+u;
point.x=(int)(tempx*VPOINT_Z*tempz);
point.y=(int)(tempy*VPOINT_Z/tempz);
}
else//实现正等测透视的矩阵变换
point.x=(int)((-VPOINT_Y/v)*x+VPOINT_X/v*y);
point.y=(int)(-((VPOINT_X*VPOINT_Z)/(u/v))*x
-((VPOINT_Y*VPOINT_Z)/(u*v)*y+u/v*z);
returnpoint;
//将点进行投影变换并传出去
变量point是CPoint类型。
函数返回值为CPoint类型。
CPoint是屏幕坐标点对应VC6.0用于显示的点的类型。
是二维坐标点。
11.3线类的实现
线类是立体图形的边框的基本构成元素
11.3.1线类
程序中线指立体空间的三维线段,存在于三维世界坐标系。
CLine封装了线类,实现了虚线实线,为绘制三维立体图形的线框做好了准备。
线段的基本属性就是始终点和实现虚线。
线段的基本方法就是设置和取得始点终点坐标值,画出线。
//头文件Line.h的主要内容如下
classCLine:
protected:
COLORREFm_color;
//线段颜色
C3dPointm_sp;
//三维空间里线段的始点
C3dPointm_ep;
//三维空间里线段的终点
voidColor(COLOREEFcol);
//设置线段的颜色
boolm_hide;
//线段是否被遮挡true时线段不可见,虚线或者不再画出
。
false线段可见,实线voidDraw(CDC*pDC);
//画线段,将线段的起点和终点的三维世界坐标转化为二维屏幕坐标
voidLine(C3dPoint*sp,C3dPoint*ep);
//设置线的坐标轴
voidLine(C3dPointsp,C3dPointep);
CLine();
virtual~CLine();
11.3.2透视实现画线
本节将介绍透视变换画线段的理论和Cline的成员函数Draw(CDC*pDC)函数的实现
sp2d=m_sp.Change();
把线段起始点从立体空间的三维世界坐标转化为屏幕上的二维坐标
ep2d=m_ep.Change();
把线段的结束点从立体空间的三维世界坐标转化为屏幕上的二维坐标
在定义画笔是,如果m_hide为false则为实线。
用PS_SOLID;
如果m_hide为true则为虚线,用PS_DASH。
pDC->
MoveTo(sp2d.x,sp2d.y);
移动到线段起始点的屏幕投影点处,可以开始画线
LineTo(ep2d.x,ep2d.y);
从线段起始点开始划线,画到线段终止点的屏幕投影处。
Cline类的Draw(CDC*pDc)函数实现了从始点到终点画出线段,根据线段是否可见画实线或虚线。
该成员函数的代码如下
voidCLine:
Draw(CDC*pDC)
CPointsp2d;
CPointep2d;
m_sp.x=m_sp.x*10;
m_sp.y=m_sp.y*10;
m_sp.z=m_sp.z*10;
m_ep.x=m_ep.x*10;
m_ep.y=m_ep.y*10;
m_ep.z=m_ep.z*10;
sp2d=m_sp.Change();
ep2d=m_ep.Change();
if(!
m_hide)
CPenmyPen(PS_SOLID,0,m_color);
//实线
CPen*pOldpen=pDc->
SelectObject(&
myPen);
pDC->
MoveTo(sp2d.x,sp2d.y);
起点
LineTo(ep2d.x,ep2d.y);
终点
SelectObject(pOLdPen);
else
CPenmyPen(PS_DASH,0,m_color);
//虚线
11.4面的实现
面是很重要的图形元素,要实现着色必需从面着手
11.4.1面类
这里所说的面,指立体三维空间的不规则四边形,是由四条边圈起来的小断面
CFace封装了面类。
实现了绘制线框小断面和为小断面填充色彩,为绘制三维立体图形的线框图和着色图做好了准备。
表11.5列出了CFace类的成员变量,表11.6列出了CFace类的成员函数
表11.5面类成员变量表
成员变量
访问权限
变量类型
解释
LeftLine
Public
Cline三维空间中的线
四边形小面的左边
UpLine
四边形小面的上边
DownLine
四边形小面的下边
RightLine
四边形小面的右边
表11.6面类成员函数表
成员函数
CFace()
构造函数
~CFace()
析构函数
Draw()
绘制线框面
PickColor()
绘制着色面
头文件Face.h的主要内容如下
classCFace:
voidPickColor(C3dPointpo,C3dPointp1,C3dPointp2,C3dPointp3,CDC*pDC);
voidDraw(CDC*pDC);
CLineLeftLine,UpLine,DownLine,RightLine;
CFace();
virtual~CFace();
};
11.4.2实现画线框面
面是由线框组成的,画线框面时调用画线的函数,提高了代码的重用性。
CFace类的Draw()函数画出了前后左右四条边框线。
voidCFace:
Draw(CDC*pDC)
DownLine.Draw(pDc);
//画下边线
UpLine.Draw(pDc);
//画上边线
RightLine.Draw(pDc);
//画右边线
LeftLine.Draw(pDc);
//画左边线
11.5体类的实现
本节中,体是所有具体三维立体图形的基
11.5.1体类
体指立体空间的几何标准三锥立体图形,包括球体,椭圆,立方体,圆柱,圆锥。
这些体在软件中其实只显示其可见表面,其表面都是二次曲面。
CBody封装了体类,实现了三维立体图形平移和旋转的通用功能。
表11.7列示了体的属性,进行平移和旋转的参数值作为体的属性被封装
表11.7体类成员变量值
AngleX
Protected
double
三维立体图形绕X轴旋转角度
AngleY
三维立体图形绕Y轴旋转角度
AngleZ
三维立体图形绕Z轴旋转角度
ShiftX
三维立体图形在X轴方向平移位置
ShiftY
三维立体图形在Y轴方向平移位置
ShiftZ
三维立体图形在Z轴方向平移位置
体类CBody是基类,具体三维立体图形的绘制必须由体类CBody的子类实现.
表11.8体类的成员函数表
CBody()
~CBody()
绘制线框体
绘制着色体
SetPara()
设置体的旋转角度,平移的距离等参照数
GetPara()
获取体的旋转角度,平移的距离等参照数
绘制线框体,有virtual修饰,是虚函数
Color()
绘制着色体,有virtual修饰,是虚函数
Rotate()
三维立体图形围绕坐标轴旋转
Move()
三维立体图形沿坐标轴平移
头文件Body.h的主要内容如下
classCBody:
DECLARE_DYNAMIC(CBody)
voidGetPara(double&
ax,double&
ay,double&
az,double&
mx,double&
my,double&
mz);
voidSetPara(doubleax,doubleay,doubleaz,doublemx,doublemy,doublemz);
前三个旋转度变量,后三个平移量变量
virtualvoidDraw(CDC*pDC)=0;
virtualvoidColor(CDC*pDC)=0;
CBody();
virtual~CBody();
doubleAngleX;
doubleAngleY;
doubleAngleZ;
doubleShiftX;
doubleShiftY;
doubleShiftZ;
voidRotate(double&
x,double&
y,double&
z);
voidMove(double&
11.6立方体的绘制
立方体的绘制主要属立方体的线框图和着色图额画法
11.6.1立方体类
CCube封装了立方体类,实现了绘制立方体的线框和着色图。
其父类是CBody,从父类继承了公用的平移,旋转方法。
立方体有长宽高属性,其六个面好八个顶点也作为立方体类的成员变量列示在表11.9中。
其属性的设置函数和画线框图和着色图的函数列示在表11.10中
表11.9立方体类成员变量表
M_Length
protected
长
m_width
宽
m_height
高
Upface
public
CFace
上面
Downface
下面
Rightface
Leftface
Frontface
Backface
PInfo[8]
C3dPoint三维空间中的点
立方体八个角的顶点
表11.10立方体类成员函数表
CCube()
~CCube()
Length()
取得立方体的边长
Width()
取得立方体的宽长
Height()
取得立方体的高度
Length(doublelen)
设置立方体的边长
Width(doublewid)
设置立方体的宽长
Height(doublehei)
设置立方体的高度
SetBodyValue()
初始化立方体八个角点的值,然后计算出其平移旋转后的最终位置
Hide()
设置隐藏的边和隐藏的面
RestHide()
吧各个棱线均设置为不可见,用于初始化
立方体的线框绘制函数
立方体的着色函数
头文件Cube.h的主要内容如下
#include"
face.h"
Body.h"
3dPoint.h"
classCCube:
publicCBody
DECLARE_DYNAMIC(CCube);
voidSetBodyValue();
voidColor(CDC*pDC);
doubleLength();
voidLength(doublelen);
doubleWidth();
voidWidth(doublewid);
doubleHeight();
voidHeight(doublehei);
CFaceUpface,Downface;
CFaceLeftface.Rightface;
CFaceFrontface,Backface;
CCube();
virtual~CCube();
voidRestHide();
intHide();
C3dPointPInfo[8];
doublem_length;
doublem_Height;
doublem_width;
//CCube:
Draw(CDC*pDC)函数画出立方体线框图。
voidCCube:
SetBodyValue();
Hide();
Backface.Draw(pDC);
Downface.Draw(pDC);
Upface.Draw(pDC);
Frontface.Draw(pDC);
Leftface.Draw(pDC);
Rightface.Draw(pDC);
RetHide();
Draw()函数调用了SetBodyValue()函数。
SetBodyValue()函数初始化立方体的八个角点的值,然后计算出其平移旋转后的最终位置。
SetBodyValue()函数的代码如下:
voi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 立体图绘制 修复的 立体图 绘制 修复