当前位置:文档之家› 计算机图形学

计算机图形学

计算机图形学
计算机图形学

直线中点Bresenham算法

一、实验内容

给出坐标点,利用Bresenham将其绘画成一条直线。

二、绘图的函数

void CTestView::Mbline() //Bresenham函数

void CTestView::OnMENUMbline();//菜单函数

三、程序设计说明及源代码:

1、绘制直线的算法

1)、Bresenham 函数(直线的扫描转换就是在屏幕像素点阵中用指定颜色点亮最佳趋近于理想直线的像素点集的过程,最著名的的Bresenham算法就是其中之一。Bresenham算法原理:每次在主位移方向上走一步,另一个方向上走不走取决于重点偏差判别式的值。本程序以X方向作为主位移方向)

void CTestView::Mbline()//Bresenham函数

{

CClientDC dc(this); //使用这种方式的菜单调用方式在VC++客户区绘制图形COLORREF rgb=RGB(0,0,255);//定义直线颜色蓝色,分别设置R,G,B参数值,改变线条颜色double x,y,d,k; //d=F(Xm,ym)=F(Xi+1,yi+0.5)=yi+0.5-k(Xi+1)-b构造中点判别式

x=x0;y=y0;k=(y1-y0)/(x1-x0)//起点及函数的斜率计算公式

for(x=x0;x<=x1;x++)

{

Sleep(20);//延时函数,每20毫秒画出一个像素点

dc.SetPixel(ROUND(x),ROUND(y),rgb);//设置像素点的坐标及颜色

if(d<0) //(中点在直线下方)

{

y++;

d+=1-k;

}

if(d>0) //(中点在直线上方)

{

y--;

d+=1-k;

}

Else //(中点在直线上)

d-=k;

}

2)、void CTestView::OnMENUMbline() //菜单函数

{

InputDlg dlg;

if(dlg.DoModal()==IDOK)

{

x0=dlg.m_x0;

y0=dlg.m_y0;

x1=dlg.m_x1;

y1=dlg.m_y1;

}

AfxGetMainWnd()->SetWindowText("案例2:直线中点Bresenham算法");(线运行出来后边框显示见图)

RedrawWindow();

Mbline();

}

四、截图

五、实验总结:

直线,圆和椭圆是图形设计的最基本图形。通过本次实验,我们了解了Bresenham函数,在以后利用Bresenham函数设计那些基本图形。

AET多边形有效边表填充算法

一、实验内容

自己给出7个顶点(扩充后可以自己增加顶点和删除顶点),利用绘制多边形程序作出多边形,再利用AET函数对图形进行填充。并全面掌握ET函数。

二、关于绘制图形的函数:

void CTestView::CreatBucket()//建立桶结点

void CTestView::Et()//构造边表

void CTestView::AddEdge(AET *NewEdge)//插入临时边表

void CTestView::EdgeOrder()//对边表进行排序

void CTestView::PolygonFill()//多边形填充

void LineFill();//用扫描线算法填充多边形

三、程序设计说明及部分源代码:

CTestView::CTestView()

{

// TODO: add construction code here//设置多边形的5个顶点

Point[0]=CPoint(300,175); //P0顶点数组的定义位于TestView.h头文件中

Point[1]=CPoint(250,300); //P1

Point[2]=CPoint(100,300); //P2

Point[3]=CPoint(225,385); //P3

Point[4]=CPoint(150,550); //P4

Point[5]=CPoint(300,450); //P5

Point[6]=CPoint(450,550); //P6

Point[7]=CPoint(375,385); //P7

Point[8]=CPoint(500,300); //P8

Point[9]=CPoint(350,300); //P9

//Point[7]=CPoint(900,450); //P7 增加节点需要增加顶点显示的个数,闭合多边形定点数相关数据在TestView.h头文件中(number,point[])更改修改线条定点与显示定点必须对应···}

void CTestView::OnDraw(CDC* pDC)

{

CTestDoc* pDoc = GetDocument();

ASSERT_V ALID(pDoc);

// TODO: add draw code for native data here

pDC->Polygon(Point,10);//绘制多边形绘制多边形的函数point表面多边形顶点数组中每一个定点对是一个point结构,有十个顶点

//输出多边形的顶点编号

pDC->TextOut(290,160,"P0"); //文本输出函数,(X,y坐标)加上Cstring对象

pDC->TextOut(235,280,"P1");

pDC->TextOut(80,295,"P2");

pDC->TextOut(200,380,"P3");

pDC->TextOut(140,555,"P4");

pDC->TextOut(295,460,"P5");

pDC->TextOut(450,550,"P6");

pDC->TextOut(385,385,"P7");

pDC->TextOut(500,300,"P8");

pDC->TextOut(350,280,"P9");

}

void CTestView::CreatBucket()//建立桶结点//桶的数据结构定义在Bucket.h头文件中CreatBucket()建立桶节点桶在TestView.h头文件中

{

int ScanMin,ScanMax;//确定扫描线的最小值和最大值扫描线的开始扫描位置与结束扫描位置

ScanMax=ScanMin=Point[0].y;

for(int i=1;i

{

if(Point[i].y

{

ScanMin=Point[i].y;//问题3:扫描线的最小值

}

if(Point[i].y>ScanMax)

{

ScanMax=Point[i].y;//问题4:扫描线的最大值

}

}

for(i=ScanMin;i<=ScanMax;i++)//建立桶结点

{

if(ScanMin==i)//桶头结点

{

HeadB=new Bucket;//建立桶的头结点

CurrentB=HeadB;//CurrentB为Bucket当前结点指针

CurrentB->ScanLine=ScanMin; //扫描线定义在桶的数据结构中

CurrentB->p=NULL;//没有连接边链表(*p桶上的边表指针)

CurrentB->next=NULL;

}

else//建立桶的其它结点

{

CurrentB->next=new Bucket; //新建一个桶结点

CurrentB=CurrentB->next; //使CurrentB指向新建的桶结点

CurrentB->ScanLine=i;

CurrentB->p=NULL; //没有连接边链表

CurrentB->next=NULL;

}

}

}

void CTestView::Et()//构造边表有效边表的数据结构定义在AET.h中

{

//问题6:全面掌握Et函数

for(int i=0;i

{

CurrentB=HeadB;//从桶链表的头结点开始循环

int j=i+1;//边的第二个顶点,Point[i]和Point[j]构成边

if(j==Number) j=0;//保证多边形的闭合

if(Point[j].y>Point[i].y)//终点比起点高

{

while(CurrentB->ScanLine!=Point[i].y)//在桶内寻找该边的yMin

{

CurrentB=CurrentB->next;//移到下一个桶结点

}

E[i].x=Point[i].x;//计算AET表的值有效边表节点相关的都定义在TestView.h头文件中

E[i].yMax=Point[j].y;

E[i].k=double((Point[j].x-Point[i].x))/(Point[j].y-Point[i].y);//代表1/k E[i].next=NULL; //有效边表的的建立需要三个参数,x,ymax以及1/k.

CurrentE=CurrentB->p;//获得桶上链接边表的地址

if(CurrentB->p==NULL)//当前桶结点上没有链接边结点

{

CurrentE=&E[i];//赋边的起始地址

CurrentB->p=CurrentE;//第一个边结点直接连接到对应的桶中

}

else

{

while(CurrentE->next!=NULL)//如果当前边已连有边结点

{

CurrentE=CurrentE->next;//移动指针到当前边的最后一个边节点

}

CurrentE->next=&E[i];//把当前边接上去

}

}

if(Point[j].y

{

while(CurrentB->ScanLine!=Point[j].y)

{

CurrentB=CurrentB->next;

}

E[i].x=Point[j].x;

E[i].yMax=Point[i].y;

E[i].k=double((Point[i].x-Point[j].x))/(Point[i].y-Point[j].y);

E[i].next=NULL;

CurrentE=CurrentB->p;

if(CurrentE==NULL)

{

CurrentE=&E[i];

CurrentB->p=CurrentE;

}

else

{

while(CurrentE->next!=NULL)

{

CurrentE=CurrentE->next;

}

CurrentE->next=&E[i];

}

}

}

CurrentB=NULL; CurrentE=NULL;

}

void CTestView::AddEdge(AET *NewEdge)//插入临时边表

{

T1=HeadE;

if(T1==NULL)//边表为空,将边表置为TempEdge

{

T1=NewEdge; HeadE=T1;

}

else

{

while(T1->next!=NULL)//边表不为空,将TempEdge连在该边之后

{

T1=T1->next;

}

T1->next=NewEdge;

}

}

void CTestView::EdgeOrder()//对边表进行排序

{

T1=HeadE;

if(T1==NULL)

{

return;

}

if(T1->next==NULL)//如果该边表没有再连边表

{

return;//桶结点只有一条边,不需要排序

}

else

{

if(T1->next->xx)//边表按x值排序

{

T2=T1->next; T1->next=T2->next;

T2->next=T1; HeadE=T2;

}

T2=HeadE; T1=HeadE->next;

while(T1->next!=NULL)//继续两两比较相连的边表的x值,进行排序

{

if(T1->next->xx)

{

T2->next=T1->next; T1->next=T1->next->next;

T2->next->next=T1; T2=T2->next;

}

else

{

T2=T1; T1=T1->next;

}

}

}

}

void CTestView::PolygonFill()//多边形填充

{

HeadE=NULL;

for(CurrentB=HeadB;CurrentB!=NULL;CurrentB=CurrentB->next)//访问所有桶结点

{

for(CurrentE=CurrentB->p;CurrentE!=NULL;CurrentE=CurrentE->next)//访问桶中排序前的边结点

{

AET *TempEdge=new AET;

TempEdge->x=CurrentE->x;

TempEdge->yMax=CurrentE->yMax;

TempEdge->k=CurrentE->k;

TempEdge->next=NULL;

AddEdge(TempEdge);//将该边插入临时Aet表

}

EdgeOrder();//使得边表按照x递增的顺序存放

T1=HeadE;//根据ymax抛弃扫描完的边结点

if(T1==NULL)

{

return;

}

while(CurrentB->ScanLine>=T1->yMax)//放弃该结点,Aet表指针后移(下闭上开){

T1=T1->next;

HeadE=T1;

if(HeadE==NULL)

{

return;

}

}

if(T1->next!=NULL)

{

T2=T1;

T1=T2->next;

}

while(T1!=NULL)

{

if(CurrentB->ScanLine>=T1->yMax)//跳过一个结点

{

T2->next=T1->next; T1->next=NULL; T1=T2->next;

}

else

{

T2=T1; T1=T2->next;

}

}

BOOL In=false;//设置一个BOOL变量In,初始值为假

double xb,xe;//扫描线的起点和终点

for(T1=HeadE;T1!=NULL;T1=T1->next)//填充扫描线和多边形相交的区间

{

if(In==false)

{

xb=T1->x;

In=true;//每访问一个结点,把In值取反一次

}

else//如果In值为真,则填充从当前结点的x值开始到下一结点的x值结束的区间

{

xe=T1->x-1;//左闭右开

CClientDC dc(this);

for(double x=xb;x<=ROUND((xe+xb)/2+0.5);x++) //扫描线和多边形相交的区间从中间分开,左边的颜色由自己选择,右边的颜色设定在程序中

dc.SetPixel(ROUND(x),CurrentB->ScanLine,GetColor);//填充语句

//GetColor用来获取自己选择的颜色,如果改成RGB(255,0,0)或者其他数字组合,则自己选择的颜色无效,自动按设定的颜色填充

for(x=(xe+xb)/2;x<=xe;x++)

dc.SetPixel(ROUND(x),CurrentB->ScanLine,RGB(0,255,0));//填充语句Sleep(1);//延时1ms,提高填充过程的可视性

In=FALSE;

}

}

for(T1=HeadE;T1!=NULL;T1=T1->next)//边连贯性

{

T1->x=T1->x+T1->k;//x=x+1/k

}

}

delete HeadB;

delete CurrentB;

delete CurrentE;

delete HeadE;

//删除各种头结点

}

四、截图:

未添加顶点之前(图2-1):

2-1 2-2

添加节点之后:(节点连线之间有交点,填充后的效果2-2)

添加节点之后:(节点连线之间无交点,填充后的效果2-3)

2-3 2-4 添加节点之后:(填充双色(设置默认红色和手动设置颜色)后的效果2-4)

2-4

五、实验总结:

本次实验使我了解了AET 多边形有效边表填充算法,在按照老师给出的算法加以验证之后,我又通过自己的深层次理解,对AET 多边形有效边表填充进行了更进一步的扩充。

直线距离加权反走样算法

一、实验内容:

给出两个点利用Bresenham算法画出一条线,在根据直线距离加权走反样算法画出另外一条线。

二、关于绘制图形的函数:

void CTestView::Mbline()//中点算法绘制直线

void CTestView::AntiDisline()//距离加权反走样直线RedrawWindow()清屏

Mbline();//走样直线

AntiDisline();//反走样直线

三、程序设计说明及源代码:

直线距离加权走样算法原理:根据像素和理想直线的距离对像素的灰度进行调节。void CTestView::Mbline()//走样直线

{

CClientDC dc(this);

COLORREF rgb=RGB(255,0,0);//定义直线颜色

double x,y,d,k;

x=x0;y=y0;k=(y1-y0)/(x1-x0);

d=0.5-k;

for(x=x0;x<=x1;x++)

{

dc.SetPixel(ROUND(x),ROUND(y),rgb);

if(d<0) { y++; d+=1-k; }

Else d-=k;

}

dc.TextOut(10,20,"走样直线");//在固定坐标处输出文字

}

void CTestView::AntiDisline()//距离加权反走样直线

{

CClientDC dc(this);

double x,y,d,k;

k=(y1-y0)/(x1-x0);

d=0;x=x0+30;y=y0+30; //两条直线之间的距离为30个像素

COLORREF rgb1=RGB(255,0,0),rgb2=RGB(0,0,0);

for(x=x0;x<=(x1+10);x++)

{

rgb1=RGB(d*255,d*255,d*255);

rgb2=RGB((1-d)*255,(1-d)*255,(1-d)*255);

dc.SetPixel(ROUND(x),ROUND(y),rgb1);

dc.SetPixel(ROUND(x),ROUND(y+1),rgb2);

d+=k;

if(d>1.0)

{

y++; d--;

}

}

dc.TextOut(0,100,"反走样直线");//在固定坐标处输出文字

}

void CTestView::OnMENUAntiliasing()//菜单函数

{

// TODO: Add your command handler code here

InputDlg dlg;

if(dlg.DoModal()==IDOK)

{

x0=dlg.m_x0; y0=dlg.m_y0; x1=dlg.m_x1; y1=dlg.m_y1;

}

AfxGetMainWnd()->SetWindowText("案例5:直线距离加权反走样算法");

RedrawWindow();//清屏

Mbline();//走样直线

AntiDisline();//反走样直线

}

四、截图

五、实验总结:

通过本次实验的主要学习目标是直线距离加权走样算法,在学习此次算法的过程中,我们又一次的温习了Bresenham算法,为以后的图形设计做好了充足的准备。

二维基本几何变换算

一、实验内容:

根据需要选定一条直线或正三角形或者矩形,对其进行平移、缩放、旋转......操作。达到理想要求。

二、关于绘制图形的函数:

#include "math.h"//数学头文件

#include "Picdlg.h"//图形输入对话框

void CTestView::GetMaxX()//获得屏幕宽度

void CTestView::GetMaxY()//获得屏幕高度

void CTestView::ClearMatrix(double A[3][3])//清除变换矩阵

void CTestView::Draw(double D[][3],int n)//绘制原始图形

void CTestView::Calculate(double P0[][3],double T[][3])//两个矩阵相乘

三、程序设计说明及源代码:

二维图形基本几何变换:相对于坐标原点和坐标轴进行平移、比例、旋转、反射和错切这5种变换。二维坐标点的基本几何变换可以表示为p’=p*t的形式,其中p(x,y)为变换前的规范化其次坐标点,p’(x’,y’)为变换后的规范化其次坐标点,T为3*3的变换矩形。void CTestView::GetMaxX()//获得屏幕宽度

{

CRect Rect;

GetClientRect(&Rect);

MaxX=Rect.right;

}

void CTestView::GetMaxY()//获得屏幕高度

{

CRect Rect;

GetClientRect(&Rect);

MaxY=Rect.bottom;

}

void CTestView::ClearMatrix(double A[3][3])//清除变换矩阵

{

for(int i=0;i<3;i++)

{

for(int j=0;j<3;j++)

A[i][j]=0;

}

}

void CTestView::OnMENUChoose()//菜单函数

{

// TODO: Add your command handler code here

Picdlg dlg;

if(dlg.DoModal()==IDOK)

{

if(dlg.m_Square==TRUE)//绘制矩形

{

P[0][0]=-dlg.m_Slength/2;P[0][1]=dlg.m_Swidth/2;P[0][2]=1;

P[1][0]=dlg.m_Slength/2;P[1][1]=dlg.m_Swidth/2;P[1][2]=1;

P[2][0]=dlg.m_Slength/2;P[2][1]=-dlg.m_Swidth/2;P[2][2]=1;

P[3][0]=-dlg.m_Slength/2;P[3][1]=-dlg.m_Swidth/2;P[3][2]=1;

ntype=4;

KeepOriginalMatrix(P,OSquare);

Draw(P,ntype);

}

if(dlg.m_Triangle==TRUE)//绘制等边三角形

{

P[0][0]=-dlg.m_Tlength/2;P[0][1]=0;P[0][2]=1;

P[1][0]=dlg.m_Tlength/2;P[1][1]=0;P[1][2]=1;

P[2][0]=0;P[2][1]=dlg.m_Tlength/2*tan(60*PI/180);P[2][2]=1;

P[3][0]=0;P[3][1]=0;P[3][2]=1;

ntype=3;

KeepOriginalMatrix(P,OTriangle);

Draw(P,ntype);

}

if(dlg.m_Line==TRUE)//绘制直线

{

P[0][0]=-dlg.m_Llength/2;P[0][1]=0;P[0][2]=1;

P[1][0]=dlg.m_Llength/2;P[1][1]=0;P[1][2]=1;

P[2][0]=0;P[2][1]=0;P[2][2]=1;

P[3][0]=0;P[3][1]=0;P[3][2]=1;

ntype=2;

KeepOriginalMatrix(P,OLine);

Draw(P,ntype);

}

}

InvalidateRect(NULL,FALSE);//重画窗口

}

void CTestView::Draw(double D[][3],int n)//绘制原始图形

{

RedrawWindow();

CClientDC dc(this);

CPen pen,*pOldpen;

pen.CreatePen(PS_SOLID,3,RGB(0,255,0));

pOldpen=dc.SelectObject(&pen);

for(int i=0;i

{

if(i==0)

dc.MoveTo(ROUND(MaxX/2+D[i][0]),ROUND(MaxY/2-D[i][1]));

else

dc.LineTo(ROUND(MaxX/2+D[i][0]),ROUND(MaxY/2-D[i][1]));

}

dc.LineTo(ROUND(MaxX/2+D[0][0]),ROUND(MaxY/2-D[0][1]));

dc.SelectObject(pOldpen);

pen.DeleteObject();

}

void CTestView::Calculate(double P0[][3],double T[][3])//两个矩阵相乘

{

double Ptemp[4][3];

KeepOriginalMatrix(P,Ptemp);

for(int i=0;i<4;i++)

for(int j=0;j<3;j++)

P[i][j]=Ptemp[i][0]*T[0][j]+Ptemp[i][1]*T[1][j]+Ptemp[i][2]*T[2][j]; }

void CTestView::OnMENUleft()//向左平移

{

// TODO: Add your command handler code here

Tmove(-10,0);

}

void CTestView::OnMENUright()//向右平移

{

// TODO: Add your command handler code here

Tmove(10,0);

}

void CTestView::OnMENUup() //向上平移

{

// TODO: Add your command handler code here

Tmove(0,10);

}

void CTestView::OnMENUdown()//向下平移

{

// TODO: Add your command handler code here

Tmove(0,-10);

}

void CTestView::OnMENUClockwise()//顺时针旋转

{

// TODO: Add your command handler code here

Trotate(30);

}

void CTestView::OnMENUAnticlockwise()//逆时针旋转

{

// TODO: Add your command handler code here

Trotate(-30);

}

void CTestView::OnMENUIncrease()//放大比例

{

// TODO: Add your command handler code here

Tscale(2,2);

}

void CTestView::OnMENUDecrease()//缩小比例

{

// TODO: Add your command handler code here

Tscale(0.5,0.5);

}

void CTestView::OnMENUXaxis()//X轴反射

{

// TODO: Add your command handler code here

Treflect(1,-1);

}

void CTestView::OnMENUYaxis()//Y轴反射

{

// TODO: Add your command handler code here

Treflect(-1,1);

}

void CTestView::OnMENUorg() //原点反射

{

// TODO: Add your command handler code here

Treflect(-1,-1);

}

void CTestView::OnMENUXdirectionplus()//X正向错切{

// TODO: Add your command handler code here

Treform(0,1);

}

void CTestView::OnMENUXdirectionneg()//X负向错切{

// TODO: Add your command handler code here

Treform(0,-1);

}

void CTestView::OnMENUITYdirectionplus()//Y正向错切{

// TODO: Add your command handler code here

Treform(1,0);

}

void CTestView::OnMENUYdirectionneg()//Y负向错切

{

// TODO: Add your command handler code here

Treform(-1,0);

}

void CTestView::OnMENUReset() //复位

{

// TODO: Add your command handler code here

if(ntype==4)

{

KeepOriginalMatrix(OSquare,P);

}

if(ntype==3)

{

KeepOriginalMatrix(OTriangle,P);

}

if(ntype==2)

{

KeepOriginalMatrix(OLine,P);

}

AfxGetMainWnd()->SetWindowText("案例9");

Draw(P,ntype);

}

void CTestView::Tmove(double Tx,double Ty)//平移变换矩阵

{

ClearMatrix(TM);

RedrawWindow();

TM[0][0]=1;

TM[1][1]=1;

TM[2][0]=Tx;

TM[2][1]=Ty;

TM[2][2]=1;

Calculate(P,TM);

AfxGetMainWnd()->SetWindowText("案例9:二维基本几何变换-平移变换");

Draw(P,ntype);

}

void CTestView::Tscale(double Sx,double Sy)//比例变换矩阵

{

ClearMatrix(TS);

RedrawWindow();

TS[0][0]=Sx;

TS[1][1]=Sy;

TS[2][2]=1;

Calculate(P,TS);

AfxGetMainWnd()->SetWindowText("案例9:二维基本几何变换-比例变换");

Draw(P,ntype);

}

void CTestView::Trotate(double thta)//旋转变换矩阵

{

ClearMatrix(TR);

RedrawWindow();

TR[0][0]=cos(thta*PI/180);

TR[0][1]=sin(thta*PI/180);

TR[1][0]=-sin(thta*PI/180);

TR[1][1]=cos(thta*PI/180);

TR[2][2]=1;

Calculate(P,TR);

AfxGetMainWnd()->SetWindowText("案例9:二维基本几何变换-旋转变换");

Draw(P,ntype);

}

void CTestView::Treflect(double Fx,double Fy)//反射变换矩阵

{

ClearMatrix(TF);

RedrawWindow();

TF[0][0]=Fx;

TF[1][1]=Fy;

TF[2][2]=1;

Calculate(P,TF);

AfxGetMainWnd()->SetWindowText("案例9:二维基本几何变换-反射变换");

Draw(P,ntype);

}

void CTestView::Treform(double b,double c)//错切变换矩阵

{

ClearMatrix(TC);

RedrawWindow();

TC[0][0]=1;

TC[0][1]=b;

TC[1][0]=c;

TC[1][1]=1;

TC[2][2]=1;

Calculate(P,TC);

AfxGetMainWnd()->SetWindowText("案例9:二维基本几何变换-错切变换");

Draw(P,ntype);

}

void CTestView::KeepOriginalMatrix(double Orig[][3],double Dest[][3])//保留矩阵{

int i,j;

for(i=0;i<4;i++)

for(j=0;j<3;j++)

Dest[i][j]=Orig[i][j];

}

四、截图

五、实验总结:

本次实验的结果很神奇,让我充满了兴趣,对二维图形基本几何变换矩阵以及其他的图形有了一定的了解,根据源代码,按照课本上的知识对其进行理解还是比较轻松。

Bezier曲线算法

一、实验内容:

自己左键先点出几个点连成图形,右键后出现趋于多边形形状的曲线。

二、关于绘制图形的函数:

void CTestView::DrawBezier()//绘制Bezier曲线

void CTestView::DrawCharPolygon()//绘制控制多边形

void CTestView::OnLButtonDown(UINT nFlags, CPoint point)//获得屏幕控制点坐标

void CTestView::OnRButtonDown(UINT nFlags, CPoint point)//调用绘制函数

三、程序设计说明及源代码:

Bezier曲线:只有第一顶点和最后一个顶点落在控制多边形上,并且多边形的第一条边和最后一条边表示了曲线的矢量方向,其他顶点则用于定义曲线的导数、阶次和形状,曲线的形状趋近于控制多边行的形状,改变控制多边形的顶点位置就会改变曲线的形状。

void CTestView::OnMENUBezierCurve()

{

// TODO: Add your command handler code here

RedrawWindow();

AfxGetMainWnd()->SetWindowText("案例18:Bezier曲线");//显示标题

MessageBox("单击左键绘制控制多边形,单击右键绘制曲线","提示",MB_OK);

pt=new CPoint[N_MAX_POINT];

Flag=true;CtrlPoint=0;

}

void CTestView::DrawBezier()//绘制Bezier曲线

{

CClientDC dc(this);

double x,y;

int rate=800,n;

n=CtrlPoint-1;

for(double t=0;t<=1;t+=1.0/rate)

{

x=0;y=0;

for(int i=0;i<=n;i++)

{

x+=pt[i].x*Cnk(n,i)*pow(t,i)*pow(1-t,n-i);

y+=pt[i].y*Cnk(n,i)*pow(t,i)*pow(1-t,n-i);

}

dc.SetPixel(ROUND(x),ROUND(y),RGB(0,255,0));//曲线颜色

}

}

double CTestView::Cnk(const int &n, const int &i)//Bernstein第一项

西安交通大学18年9月课程考试《计算机图形学》作业考核试题

(单选题) 1: 计算机图形学中的光栅算法主要用于( )。 A: 三维图形的输入 B: 三维图形的输出 C: 二维图形输入 D: 二维图形输出 正确答案: (单选题) 2: 在光亮度插值算法中,下列论述哪个是错误的( ) A: Gouraud明暗模型计算中,多边形与扫描平面相交区段上每一采样点的光亮度值是由扫描平面与多边形边界交点的光亮度插值得到的 B: Phong明暗处理模型中,采用了双线性插值和构造法向量函数的方法模拟高光 C: Gouraud明暗模型和Phong明暗处理模型主要是为了处理由多个平面片近似表示曲面物体的绘制问题 D: Phong明暗模型处理的物体表面光亮度呈现不连续跃变 正确答案: (单选题) 3: 种子填充算法中,正确的叙述是() A: 它是按扫描线的顺序进行像素点的填充 B: 四连接算法可以填充八连接区域 C: 四连接区域内的每一个像素可以通过上下左右四个方向组合到达 D: 八连接算法不能填充四连接区域 正确答案: (单选题) 4: 选择下面哪一个命令,可以在工作时获得最好的视觉效果( ) A: “View-Simple Wireframe” B: “View-Wireframe” C: “View-Draft” D: “View-Enhanced” 正确答案: (单选题) 5: 在下列叙述语句中,错误的论述为( ) A: 在图形文件系统中,点、线、圆等图形元素通常都用其几何特征参数来描述 B: 在图形系统中,图形处理运算的精度不取决于显示器的分辨率 C: 在光栅扫描图形显示器中,所有图形都按矢量直接描绘显示,不存在任何处理 D: 在彩色图形显示器中,使用RGB颜色模型 正确答案: (单选题) 6: 下列哪个对象不可以使用“Effect-Add Perspective”命令添加透视效果( ) A: 未转换成为曲线路径的美术字文本 B: 具有使用“交互阴影”工具创建的阴影的矢量对象 C: 位图 D: 具有使用“交互透明”工具创建的局部透明效果的矢量对象 正确答案: (单选题) 7: 编辑3D文字时,怎样得到能够在三维空间内旋转3D文字的角度控制框( ) A: 利用“选择”工具单击3D文字 B: 利用“交互立体”工具单击3D文字 C: 利用“交互立体”工具双击3D文字 D: 利用“交互立体”工具先选中3D文字,然后再单击 正确答案: (单选题) 8: 分别用编码裁剪算法和中点分割裁剪算法对一条等长的直线段裁剪,下面那一个说法是正确的( ) A: 编码裁剪算法的速度快于中点分割裁剪算法的裁剪速度 B: 编码裁剪算法的速度慢于中点分割裁剪算法的裁剪速度 C: 编码裁剪算法的速度和中点分割裁剪算法的裁剪速度一样 D: 编码裁剪算法的速度和中点分割裁剪算法的裁剪速度哪一个快,无法确定 正确答案: (单选题) 9: 下列关于Bezier曲线的性质,哪个是错误的( ) A: 在起点和终点处的切线方向和控制多边形第一条边和最后一条边的方向一致 B: 在端点处的R阶导数,仅与R个相邻个控制顶点有关

计算机图形学 答案

计算机图形学Ⅰ 专业:计算机科学与技术 计算机科学与技术2092 2012年12月

第1章绪论 1、计算机图形学的概念?(或什么是计算机图形学?) 计算机图形学是研究怎样利用计算机表示、生成、处理和显示图形的(原理、算法、方法和技术)一门学科。 2、图形与图像的区别? 图像是指计算机内以位图(Bitmap)形式存在的灰度信息;图形含有几何属性,更强调物体(或场景)的几何表示,是由物体(或场景)的几何模型(几何参数)和物理属性(属性参数)共同组成的。 3、计算机图形学的研究内容? 计算机图形学的研究内容非常广泛,有图形硬件、图形标准、图形交互技术、光栅图形生成算法、曲线曲面造型、实体造型、真实感图形计算与显示算法,以及科学计算可视化、计算机动画、自然景物仿真和虚拟现实等。 4、计算机图形学的最高奖是以 Coons 的名字命名的,而分别获得第一届(1983年)和第二 届(1985年)Steven A. Coons 奖的,恰好是 Ivan E. Sutherland 和 Pierre Bézier 。 5、1971年,Gourand提出“漫反射模型+插值”的思想,被称为 Gourand 明暗处理。 6、1975年,Phong提出了著名的简单光照模型—— Phong模型。 7、1980年,Whitted提出了一个光透明模型—— Whitted模型,并第一次给出光线跟踪算 法的范例,实现了Whitted模型。 8、以 SIGGRAPH 会议的情况介绍,来结束计算机图形学的历史回顾。 9、什么是三维形体重建? 三维形体重建就是从二维信息中提取三维信息,通过对这些信息进行分类、综合等一系列处理,在三维空间中重新构造出二维信息所对应的三维形体,恢复形体的点、线、面及其拓扑关系,从而实现形体的重建。 10、在漫游当中还要根据CT图像区分出不同的体内组织,这项技术叫分割。 11、一个图形系统通常由图形处理器、图形输入设备和输出设备构成。 12、CRT显示器的简易结构图 12、LCD液晶显示器的基本技术指标有:可视角度、点距和分辨率。

计算机图形学复习重点

1:简述计算机图像学与数字图像处理和计算几何以及模式识别等学科之间的区别:计算机图形学研究计算机显示图像,即现实世界在计算机中的表示,其逆过程就是计算机视觉;图像处理:对图像进行处理包括图像变换,图像分析,边缘检测,图像分割等。模式识别:对数据的模式分析,涉及数据分析统计学,模式分类等。 2:第一台图像显示器是起源于:1950年麻省理工的旋风一号。 3:I.E萨瑟兰德被誉为计算机图像学之父,1963年他的SKETCHPAD被作为计算机图像学作为一个新学科的出现的标志。 4:列举计算机图像学的应用领域:计算机辅助绘图设计;事务管理中的交互式绘图;科学技术可视化;过程控制;计算机动画及广告;计算机艺术;地形地貌和自然资源的图形显示。5:计算机图形系统包括哪些组成:硬件设备和相应的程序系统(即软件)两部分组成。6:图像系统的基本功能:计算功能;存储功能;输入功能;输出功能;对话功能。 7:图像系统的分类:用于图形工作站的图形系统;以PC为基础的图形系统;小型智能设备上的图形系统 8:显示器的分类:阴极射线管(CRT);液晶显示器(LCD);LED(发光二极管)显示器;等离子显示器。 9:什么是CRT?其组成部分:即阴极射线管。组成有电子枪,加速结构,聚焦系统,偏转系统,荧光屏。 10:彩色阴极射线管生成彩色的方法:射线穿透法。应用:主要用于画线显示器。优点:成本低。缺点:只能产生有限几种颜色;影孔板法。 11:显示器的刷新方式经历了哪几个阶段:随机扫描显示;直视存储管式显示;光栅扫描显示。 12:什么是显示处理器,它与CPU是一回事吗?:显示处理器又称视觉处理器,是一种专门在PC,游戏机和一些移动设备上图像运算工作的微处理器,是显卡中重要组成部分。它的作用是代替CPU完成部分图形处理功能,扫描转换,几何变换,裁剪,光栅操作,纹理映射等。 13:什么是显存,它与内存的区别:显存全称显示内存,即显示卡专用内存。它负责存储显示芯片需要处理的各种数据。电脑的内存是指CPU在进行运算时的一个数据交换的中转站,数据由硬盘调出经过内存条再到CPU。区别:显存是显卡缓冲内存。内存是电脑的内部存储器。是不同的概念。 14:黑白显示器需要1个位平面;256级灰度显示器需要8个,真彩色需要24个位平面。15:OpenGL是什么?它在计算机图形学中的作用?OpenGL是一个工业标准的三维计算机图形软件接口,可以方便的用它开发出高质量的静止或动画三维彩色图形,并有多种特殊视觉效果,如光照,文理,透明度,阴影等。 16:图元:图形元素,可以编辑的最小图形单位。是图形软件用于操作和组织画面的最基本素材,是一组最简单,最通用的几何图形或字符。基本二维图元包括:点,直线,圆弧,多边形,字体符号和位图等。 17:直线的生产算法有:逐点比较法;数值微分法(DDA);中点画线法;Bresenham算法。18:采用哪种平移方法可以使任意二维直线变为第一和第二象限中的直线:逐点比较法。19:交互式图形系统的基本交换任务包括:定位,选择,文字输入,数值输出。定位任务是向应用程序指定一个点的坐标,定位中考虑的基本问题:坐标系统;分辨率;网格;反馈。选择任务是指从一个被选集中挑选出一个元素来。在作图系统中,操作命令、属性值、物种种类、物体等都可能是被选集。被选集可根据其元素的变化程度分为可变集和固定集。可变集的选择技术:指名和拾取。固定集的选择技术:指名技术、功能键、菜单技术、模式识

计算机图形学试题附答案完整版

名词解释 将图形描述转换成用像素矩阵表示的过程称为扫描转换。 1.图形 2.像素图 3.参数图 4.扫描线 5.构造实体几何表示法 6.投影 7.参数向量方程 8.自由曲线 9.曲线拟合 10.曲线插值 11.区域填充 12.扫描转换 三、填空 1.图形软件的建立方法包括提供图形程序包、和采用专用高级语言。 2.直线的属性包括线型、和颜色。 3.颜色通常用红、绿和蓝三原色的含量来表示。对于不具有彩色功能的显示系统,颜色显示为。 4.平面图形在内存中有两种表示方法,即和矢量表示法。 5.字符作为图形有和矢量字符之分。 6.区域的表示有和边界表示两种形式。 7.区域的内点表示法枚举区域内的所有像素,通过来实现内点表示。 8.区域的边界表示法枚举区域边界上的所有像素,通过给赋予同一属性值来实现边界表示。 9.区域填充有和扫描转换填充。 10.区域填充属性包括填充式样、和填充图案。 11.对于图形,通常是以点变换为基础,把图形的一系列顶点作几何变换后,

连接新的顶点序列即可产生新的变换后的图形。 12.裁剪的基本目的是判断图形元素是否部分或全部落在之内。 13.字符裁剪方法包括、单个字符裁剪和字符串裁剪。 14.图形变换是指将图形的几何信息经过产生新的图形。 15.从平面上点的齐次坐标,经齐次坐标变换,最后转换为平面上点的坐标,这一变换过程称为。 16.实体的表面具有、有界性、非自交性和闭合性。 17.集合的内点是集合中的点,在该点的内的所有点都是集合中的元素。 18.空间一点的任意邻域内既有集合中的点,又有集合外的点,则称该点为集合的。 19.内点组成的集合称为集合的。 20.边界点组成的集合称为集合的。 21.任意一个实体可以表示为的并集。 22.集合与它的边界的并集称集合的。 23.取集合的内部,再取内部的闭包,所得的集合称为原集合的。 24.如果曲面上任意一点都存在一个充分小的邻域,该邻域与平面上的(开)圆盘同构,即邻域与圆盘之间存在连续的1-1映射,则称该曲面为。 25.对于一个占据有限空间的正则(点)集,如果其表面是,则该正则集为一个实体(有效物体)。 26.通过实体的边界来表示一个实体的方法称为。 27.表面由平面多边形构成的空间三维体称为。 28.扫描表示法的两个关键要素是和扫描轨迹。 29.标量:一个标量表示。 30.向量:一个向量是由若干个标量组成的,其中每个标量称为向量的一个分量。 四、简答题 1. 什么是图像的分辨率?

计算机图形学课程设计书

计算机图形学课程设计 书 文档编制序号:[KKIDT-LLE0828-LLETD298-POI08]

课程设计(论文)任务书 理学院信息与计算科学专业2015-1班 一、课程设计(论文)题目:图像融合的程序设计 二、课程设计(论文)工作: 自2018 年1 月10 日起至2018 年1 月12日止 三、课程设计(论文) 地点: 2-201 四、课程设计(论文)内容要求: 1.本课程设计的目的 (1)熟悉Delphi7的使用,理论与实际应用相结合,养成良好的程序设计技能;(2)了解并掌握图像融合的各种实现方法,具备初步的独立分析和设计能力;(3)初步掌握开发过程中的问题分析,程序设计,代码编写、测试等基本方法;(4)提高综合运用所学的理论知识和方法独立分析和解决问题的能力; (5)在实践中认识、学习计算机图形学相关知识。 2.课程设计的任务及要求 1)基本要求: (1)研究课程设计任务,并进行程序需求分析; (2)对程序进行总体设计,分解系统功能模块,进行任务分配,以实现分工合作;(3)实现各功能模块代码; (4)程序组装,测试、完善系统。 2)创新要求: 在基本要求达到后,可进行创新设计,如改进界面、增加功能或进行代码优化。

3)课程设计论文编写要求 (1)要按照书稿的规格打印誊写课程设计论文 (2)论文包括封面、设计任务书(含评语)、摘要、目录、设计内容、设计小结(3)论文装订按学校的统一要求完成 4)参考文献: (1)David ,《计算机图形学的算法基础》,机械工业出版社 (2)Steve Cunningham,《计算机图形学》,机械工业出版社 (3) 5)课程设计进度安排 内容天数地点 程序总体设计 1 实验室 软件设计及调试 1 实验室 答辩及撰写报告 1 实验室、图书馆 学生签名: 2018年1月12日 摘要 图像融合是图像处理中重要部分,能够协同利用同一场景的多种传感器图像信息,输出一幅更适合于人类视觉感知或计算机进一步处理与分析的融合图像。它可明显的改善单一传感器的不足,提高结果图像的清晰度及信息包含量,有利于更为准确、更为可靠、更为全面地获取目标或场景的信息。图像融合主要应用于军事国防上、遥感方面、医学图像处理、机器人、安全和监控、生物监测等领域。用于较多也较成熟的是红外和可见光的融合,在一副图像上显示多种信息,突出目标。一般情况下,图像融合由

西安电子科技大学计算机图形学重点总结,缩印必备!

反走样:在光栅显示器上显示图形时,直线段或图形边界或多或少会呈锯齿状。原因是图形信号是连续的,而在光栅显示系统中,用来表示图形的却是一个个离散的象素。这种用离散量表示连续量引起的失真现象称之为走样;用于减少或消除这种效果的技术称为反走样 反走样方法主要有:提高分辨率、区域采样和加权区域采样 提高分辨率:把显示器分辨率提高一倍,锯齿宽度也减小了一倍,所以显示出的直线段看起来就平直光滑了一些。这种反走样方法是以4倍的存储器代价和扫描转换时间获得的。因此,增加分辨率虽然简单,但是不经济的方法,而且它也只能减轻而不能消除锯齿问题。 区域采样方法:假定每个象素是一个具有一定面积的小区域,将直线段看作具有一定宽度的狭长矩形。当直线段与象素有交时,求出两者相交区域的面积,然后根据相交区域面积的大小确定该象素的亮度值。 加权区域采样:相交区域对象素亮度的贡献依赖于该区域与象素中心的距离。当直线经过该象素时,该象素的亮度F是在两者相交区域A′上对滤波器进行积分的积分值 刚体:平移和旋转的组合,保持线段的长度,保持角的大小,图形不变形,为刚体变化 仿射:旋转、平移、缩放的组合为仿射变换,平行边仍然平行,错切变换也为仿射变换 较高次数逼近的三种方法:1将y和z直接表示成x的显函数即y=f(x) z=g(x)2用一个形如f(x,y,z)=0的隐式方程的解来表示曲线3曲线的参数表示 前两方法缺点:1由一个x值不能得到多个y值;这一定义不是旋转不变的;描述具有与坐标轴垂直的切线的曲线是困难的2给定方程的解可能更多;曲线段做链接时,很难确定他们的切线方向在连接点上是否相等 参数表示为什么要选择三做参数:1低于三次的函数控制曲线形状时不够灵活,高于三次的曲线会增加不必要的摆动其增加计算量2三次参数曲线是三维空间中次数最低的非平面曲线3定义高次曲线需要更多条件,这样在交互生成时会造成曲线的摆动而难以控制 G0连续:两条曲线段拼接成一条曲线 G1连续:两条曲线段拼接点处切向量方向相同。若相等(方向、大小)-C1 Gn连续:两条曲线段拼接点处切向量的阶导数方向相同。n阶导数相等-Cn B样条曲线优势:1四点加权求和,调和函数非负且和为1,具有凸壳特性2可证明Qi和Qi+1在连接点处连续3曲线段三次函数,所以整个曲线具有连续4凸壳的对曲线裁剪有用 中点生成算法: TBRL中点生成算法:

图形学场景设计

图形学场景设计

计算机图形学课程设计报告 题目自然场景设计 院(系、部) 专业班级 学号

姓名成绩

1 设计目的与要求 1.1设计题目 自然场景设计 1.2 设计目的 以小组合作的方式绘制一个自然场景,给绘制的实体添加纹理光照效果,进一步巩固所学知识,提高团队合作能力 1.3 设计要求 (1)采用真实感图形学技术设计一个自然场景(2)模拟出水、云、山体等至少三种景物(3)实现场景的漫游 (4)对设计出的图像进行光照处理 (5)将图片的纹理贴附到物体表面 2 总体设计 2.1 功能简介 创建一个900*600的Windows窗口,在窗口中显示冰箱、电灯、茶壶三个实体,根据电灯位置在

地面上绘制个实体的投影;为茶壶添加纹理;利用键盘的方向键控制冰箱旋转,实现场景漫游2.2 功能模块图 主 初始化实体绘键盘操 作函数 电灯冰箱 茶壶 2.3 软件各模块功能介绍 2.3.1冰箱和茶壶的绘制 由四边形拼接出冰箱,通过平移旋转函数放置到指定位置,同时实现茶壶的绘制,在茶壶上添加纹理效果,通过平移旋转变换放置到冰箱上面2.3.2顶灯的绘制

绘制出一个带灯罩的电灯,并且将光源放置在灯泡的位置 2.3.3 设置光照 设置光照的各种参数,为场景添加光照效果,让实体具有立体效果 2.3.4 纹理图片生成 用数组存储一幅自己设计的纹理图片,方便实体添加纹理效果时的调用 2.3.5 影子生成 根据需求为场景中的实体添加阴影效果,使得场景效果更加逼真 2.3.6 法向量设置 为场景设置法向量,确保实体在不同的角度都能被看到 3 详细设计及关键代码 3.1 光照模块详细设计 3.1.1 光照设置功能 设置光照的各种参数,为场景添加光照效果,让实体具有立体效果 3.1.2 光照设置设计

西北工业大学计算机图形学重点汇编

第一章绪论 ?计算机图形学是研究怎样用计算机生成、处理和显示图形的一门学科。 生成:在计算机内表示客观世界物体的模型,即图形建模; 显示:模型对象在计算机显示设备或其他输出设备上的显示; 处理:利用计算机实现客观世界、对象模型和输出图形这三者之间映射的一系列操作和处理过程。 ?1.点阵法:枚举出图形中所有的点来表示,强调图形由点及其点的属性(颜色)构成:像素图、位图或图像。一般地,一个图像就是一个矩阵,该矩阵的每一个元素都表示图像某行某列一个点的颜色值,矩阵的维数就是图像的宽度和高度缺点:点阵图形需要大量的存储空间;对点阵图形进行编辑、修改较困难; 点阵图的放大操作会使图形失真;JPEG, BMP, Tif, GIF, PNG 2.参数法:由图形的形状参数和属性参数来表示图形(矢量图、图形) 形状参数(必须有):几何,方程或分析表达式的系数,线段的端点坐标等 属性参数(可选):非几何,颜色、线形等DXF, OBJ, 3DS ?几何要素:刻画对象的轮廓、形状、几何元素组成等。 非几何要素:刻画对象的颜色、材质、纹理等。 ?图像:图像一定是二维的。基本单位是像素:组成图像的颜色点(或亮度点),是数字图像的最小信息单位,通常是一个整数,其大小称为像素值。 ?灰度级分辨率、颜色分辨率 图像分为两色图(黑白)、灰度图、彩色图、真彩色图 图形:图形可以是二维的、或者三维的,图形的基本信息包括它的基本几何元素(必须),拓扑关系,以及颜色、材质、纹理等可选要素 第二章图形系统与图像生成 ?计算机图形系统是进行图形处理的计算机系统,是计算机图形硬件和图形软件的集合。 图形硬件包括具有图形处理能力的计算机主机、图形显示器以及鼠标和键盘等基本交互工具,还有图形输入板、绘图仪、图形打印机等输入输出设备,以及磁盘、光盘等图形存储设备。 图形软件分为图形数据模型、图形应用软件和图形支撑软件三部分。涵盖了计算机系统软件、高级语言和专业应用软件等方面。 ?一个计算机图形系统至少应当具有计算、存储、对话、输入、输出五个方面的基本功能 ?图形系统的硬件就是指执行以上不同功能的各种设备,如计算机、鼠标、扫描仪、显示器、硬盘、绘图仪等。根据具体的业务需求,组成系统的设备是可选的。在系统中,计算机处于核心地位,其他设备与其直接相连。 星型设备,其他可选

计算机图形学

《计算机图形学》 实 验 报 告 姓名:邬维 学号: 20107989 班级:计算机科学与技术一班 指导老师:廖宁 成绩: 完成时间:2012-12-26

实验一 实验名称:Visual C++图形程序 一.实验目的 Visual C++是在Microsoft C 的基础上发展而来的,随着计算机软、硬件技术的快速发展,如今Visual C++已成为集编辑、编译、运行、调试于一体功能强大的集成编程环境。本章以Visual C++ 6.0 为对象,主要介绍V isual C++集成编成环境的使用、图形设备接口和常用图形程序设计、鼠标编程以及菜单设计等基础,目的是通过对Visual C++的学习,掌握V isual C++图形程序设计的方法,为计算机图形学原理部分的算法实现提供程序工具和方法。 二.实验环境 XP系统,Visual C++ 6.0。 三.实验内容 1.学习V isual C++图形程序设计的方法; 2.掌握V isual C++集成编成环境的使用、图形设备接口和常用图形程序设计、鼠标编程、橡皮筋交互技术、画刷与画笔以及菜单设计等; 3.利用CDC类已有的画笔划线等函数绘制一张笑脸,要求有眼睛鼻子和嘴巴,笑脸处于屏幕的中央,并加入文字。 四.实验步骤 1.先建立一个CDC工程。 2.在CCDCview找到OnDraw()函数编写一下代码: void CAAA View::OnDraw(CDC* pDC) { CAAADoc* pDoc = GetDocument(); ASSERT_V ALID(pDoc); // TODO: add draw code for native data here CPen mypen,*oldpen; mypen.CreatePen(PS_SOLID,2,RGB(0,0,0)); oldpen=pDC->SelectObject(&mypen); pDC->Ellipse(275,170,425,320); pDC->Arc(360,215,410,240,410,255,360,225); pDC->Arc(290,215,340,240,340,255,290,225); pDC->Arc(320,240,380,300,320,270,380,270); pDC->SelectObject(oldpen); pDC->TextOut(300,350,"开开心心每一天!"); pDC->MoveTo(350,240); pDC->LineTo(350,270); 3.编译、调试和运行程序,查看程序结果。

计算机图形学课程教学大纲

《计算机图形学》课程教学大纲一、课程基本信息 课程代码:110053 课程名称:计算机图形学 英文名称:Computer Graphics 课程类别:专业课 学时:72 学分: 适用对象:信息与计算科学专业本科生 考核方式:考试(平时成绩占总成绩的30%) 先修课程:高级语言程序设计、数据结构、高等代数 二、课程简介 中文简介: 计算机图形学是研究计算机生成、处理和显示图形的学科。它的重要性体现在人们越来越强烈地需要和谐的人机交互环境:图形用户界面已经成为一个软件的重要组成部分,以图形的方式来表示抽象的概念或数据已经成为信息领域的一个重要发展趋势。通过本课程的学习,使学生掌握计算机图形学的基本原理和基本方法,理解图形绘制的基本算法,学会初步图形程序设计。 英文简介: Computer Graphics is the subject which concerned with how computer builds, processes and shows graphics. Its importance has been shown in people’s more and more intensively need for harmony human-machine interface. Graphics user interface has become an important part of software. It is a significant trend to show abstract conception or data in graphics way. Through the learning of this course, students could master Computer Graphics’basic theories and methods,understand graphics basic algorithms and learn how to design basic graphics program. 三、课程性质与教学目的 《计算机图形学》是信息与计算科学专业的一门主要专业课。通过本课程的学习,使学生掌握基本的二、三维的图形的计算机绘制方法,理解光栅图形生成基本算法、几何造型技术、真实感图形生成、图形标准与图形变换等概念和知识。学会图形程序设计的基本方法,为图形算法的设计、图形软件的开发打下基础。 四、教学内容及要求 第一章绪论 (一)目的与要求 1.掌握计算机图形学的基本概念; 2.了解计算机图形学的发展、应用; 3.掌握图形系统的组成。

计算机图形学必考知识点

Phong Lighting 该模型计算效率高、与物理事实足够接近。Phong模型利用4个向量计算表面任一点的颜色值,考虑了光线和材质之间的三种相互作用:环境光反射、漫反射和镜面反射。Phong模型使用公式:I s=K s L s cosαΦα:高光系数。计算方面的优势:把r和v归一化为单位向量,利用点积计算镜面反射分量:I s=K s L s max((r,v)α,0),还可增加距离衰减因子。 在Gouraud着色这种明暗绘制方法中,对公用一个顶点的多边形的法向量取平均值,把归一化的平均值定义为该顶点的法向量,Gouraud着色对顶点的明暗值进行插值。Phong着色是在多边形内对法向量进行插值。Phong着色要求把光照模型应用到每个片元上,也被称为片元的着色。 颜色模型RGB XYZ HSV RGB:RGB颜色模式已经成为现代图形系统的标准,使用RGB加色模型的RGB三原色系统中,红绿蓝图像在概念上有各自的缓存,每个像素都分别有三个分量。任意色光F都可表示为F=r [ R ] + g [ G ] + b [ B ]。RGB颜色立方体中沿着一个坐标轴方向的距离代表了颜色中相应原色的分量,原点(黑)到体对角线顶点(白)为不同亮度的灰色 XYZ:在RGB 系统基础上,改用三个假想的原色X、Y、Z建立了一个新的色度系统, 将它匹配等能光谱的三刺激值,该系统称为视场XYZ色度系统,在XYZ空间中不能直观地评价颜色。 HSV是一种将RGB中的点在圆柱坐标系中的表示法,H色相S饱和度V明度,中心轴为灰色底黑顶白,绕轴角度为H,到该轴距离为S,沿轴高度为S。 RGB优点:笛卡尔坐标系,线性,基于硬件(易转换),基于三刺激值,缺点:难以指定命名颜色,不能覆盖所有颜色范围,不一致。 HSV优点:易于转换成RGB,直观指定颜色,’缺点:非线性,不能覆盖所有颜色范围,不一致 XYZ:覆盖所有颜色范围,基于人眼的三刺激值,线性,包含所有空间,缺点:不一致 交互式计算机程序员模型 (应用模型<->应用程序<->图形库)->(图形系统<->显示屏).应用程序和图形系统之间的接口可以通过图形库的一组函数来指定,这和接口的规范称为应用程序编程人员接口(API),软件驱动程序负责解释API的输出并把这些数据转换为能被特定硬件识别的形式。API提供的功能应该同程序员用来确定图像的概念模型相匹配。建立复杂的交互式模型,首先要从基本对象开始。良好的交互式程序需包含下述特性:平滑的显示效果。使用交互设备控制屏幕上图像的显示。能使用各种方法输入信息和显示信息。界面友好易于使用和学习。对用户的操作具有反馈功能。对用户的误操作具有容忍性。Opengl并不直接支持交互,窗口和输入函数并没有包含在API中。 简单光线跟踪、迭代光线跟踪 光线跟踪是一种真实感地显示物体的方法,该方法由Appel在1968年提出。光线跟踪方法沿着到达视点的光线的相反方向跟踪,经过屏幕上每一象素,找出与视线所交的物体表面点P0,并继续跟踪,找出影响P0点光强的所有的光源,从而算出P0点上精确的光照强度。光线跟踪器最适合于绘制具有高反射属性表面的场景。优缺点:原理简单,便于实现,能生成各种逼真的视觉效果,但计算量开销大,终止条件:光线与光源相交光线超出视线范围,达到最大递归层次。一般有三种:1)相交表面为理想漫射面,跟踪结束。2)相交表面为理想镜面,光线沿镜面反射方向继续跟踪。3)相交表面为规则透射面,光线沿规则透射方向继续跟踪。 描述光线跟踪简单方法是递归,即通过一个递归函数跟踪一条光线,其反射光想和折射光线再调用此函数本身,递归函数用来跟踪一条光线,该光线由一个点和一个方向确定,函数返回与光线相交的第一个对象表面的明暗值。递归函数会调用函数计算指定的光线与最近对象表面的交点位置。 图形学算法加速技术BVH, GRID, BSP, OCTree 加速技术:判定光线与场景中景物表面的相对位置关系,避免光线与实际不相交的景物表面的求交运算。加速器技术分为以下两种:Bounding Volume Hierarchy 简写BVH,即包围盒层次技术,是一种基于“物体”的场景管理技术,广泛应用于碰撞检测、射线相交测试之类的场合。BVH的数据结构其实就是一棵二叉树(Binary Tree)。它有两种节点(Node)类型:Interior Node 和Leaf Node。前者也是非叶子节点,即如果一个Node不是Leaf Node,它必定是Interior Node。Leaf Node 是最终存放物体/们的地方,而Interior Node存放着代表该划分(Partition)的包围盒信息,下面还有两个子树有待遍历。使用BVH需要考虑两个阶段的工作:构建(Build)和遍历(Traversal)。另一种是景物空间分割技术,包括BSP tree,KD tree Octree Grid BSP:二叉空间区分树 OCTree:划分二维平面空间无限四等分 Z-buffer算法 算法描述:1、帧缓冲器中的颜色设置为背景颜色2、z缓冲器中的z值设置成最小值(离视点最远)3、以任意顺序扫描各多边形a) 对于多边形中的每一个采样点,计算其深度值z(x,y) b) 比较z(x, y)与z缓冲器中已有的值zbuffer(x,y)如果z(x, y) >zbuffer(x, y),那么计算该像素(x, y)的光亮值属性并写入帧缓冲器更新z缓冲器zbuffer(x, y)=z(x, y) Z-buffer算法是使用广泛的隐藏面消除算法思想为保留每条投影线从COP到已绘制最近点距离,在投影后绘制多边形时更新这个信息。存储必要的深度信息放在Z缓存中,深度大于Z缓存中已有的深度值,对应投影线上已绘制的多边形距离观察者更近,故忽略该当前多边形颜色,深度小于Z缓存中的已有深度值,用这个多边形的颜色替换缓存中的颜色,并更新Z缓存的深度值。 void zBuffer() {int x, y; for (y = 0; y < YMAX; y++) for (x = 0; x < XMAX; x++) { WritePixel (x, y, BACKGROUND_VALUE); WriteZ (x, y, 1);} for each polygon { for each pixel in polygon’s projection { //plane equation doubl pz = Z-value at pixel (x, y); if (pz < ReadZ (x, y)) { // New point is closer to front of view WritePixel (x, y, color at pixel (x, y)) WriteZ (x, y, pz);}}}} 优点:算法复杂度只会随着场景的复杂度线性增加、无须排序、适合于并行实现 缺点:z缓冲器需要占用大量存储单元、深度采样与量化带来走样现象、难以处理透明物体 着色器编程方法vert. frag 着色器初始化:1、将着色器读入内存2、创建一个程序对象3、创建着色器对象4、把着色器对象绑定到程序对象5、编译着色器6、将所有的程序连接起来7、选择当前的程序对象8、把应用程序和着色器之间的uniform变量及attribute变量关联起来。 Vertex Shader:实现了一种通用的可编程方法操作顶点,输入主要有:1、属性、2、使用的常量数据3、被Uniforms使用的特殊类型4、顶点着色器编程源码。输入叫做varying变量。被使用在传统的基于顶点的操作,例如位移矩阵、计算光照方程、产生贴图坐标等。Fragment shader:计算每个像素的颜色和其他属性,实现了一种作用于片段的通用可编程方法,对光栅化阶段产生的每个片段进行操作。输入:Varying 变量、Uniforms-用于片元着色器的常量,Samples-用于呈现纹理、编程代码。输出:内建变量。 观察变换 建模变换是把对象从对象标架变换到世界标架 观察变换把世界坐标变换成照相机坐标。VC是与物理设备无关的,用于设置观察窗口观察和描述用户感兴趣的区域内部分对象,观察坐标系采用左手直角坐标系,可在用户坐标系中的任何位置、任何方向定义。其中有一坐标轴与观察方向重合同向并与观察平面垂直。观察变换是指将对象描述从世界坐标系变换到观察坐标系的过程。(1):平移观察坐标系的坐标原点,与世界坐标系的原点重合,(2):将x e,y e轴分别旋转(-θ)角与x w、y w轴重合。 规范化设备坐标系 规范化设备坐标系是与具体的物理设备无关的一种坐标系,用于定义视区,描述来自世界坐标系窗口内对象的图形。 光线与隐式表面求交 将一个对象表面定义为f(x,y,z)=f(p)=0,来自P0,方向为d的光线用参数的形式表示为P(t)=P0+td. 交点位置处参数t的值满足:f(P0+td)=0,若f是一个代数曲面,则f是形式为X i Y j Z k的多项式之和,求交就转化为寻求多项式所有根的问题,满足的情况一:二次曲面,情况二:品面求交,将光线方程带入平面方程:p*n+c=0可得到一个只需做一次除法的标量方程p=p0+td。可通过计算得到交点的参数t的值:t=(p0*n+c)/(n*d). 几何变换T R S矩阵表示 三维平移T 三维缩放S旋转绕z轴Rz( ) 100dx 010dy 001dz 0001 Sx000 0Sy00 00Sz0 0001 cos-sin00 sin cos00 0010 0001 θθ θθ 旋转绕x轴Rx(θ) 旋转绕y轴Ry(θ) 1000 0cos-sin0 0sin cos0 0001 θθ θθ cos0sin0 0100 -sin0cos0 0001 θθ θθ 曲线曲面 Bezier曲线性质:Bezier曲线的起点和终点分别是特征多边形的第一个顶点和最后一个顶点。曲线在起点和终点处的切线分别是特征多边形的第一条边和最后一条边,且切矢的模长分别为相应边长的n倍;(2)凸包性;(3)几何不变性(4)变差缩减性。端点插值。 均匀B样条曲线的性质包括:凸包性、局部性、B样条混合函数的权性、连续性、B样条多项式的次数不取决于控制函数。 G连续C连续 C0连续满足:C1连续满足: (1)(0) p(1)=(1)(0)(0) (1)(0) px qx py q qy pz qz == ???? ???? ???? ???? (1)(0) p'(1)=(1)'(0)(0) (1)(0) p x q x p y q q y p z q z == ???? ???? ???? ???? C0(G0)连续:曲线的三个分量在连接点必须对应相等 C1连续:参数方程和一阶导数都对应相等 G1连续:两曲线的切线向量成比例 三维空间中,曲线上某点的导数即是该点的切线,只要求两个曲线段连接点的导数成比例,不需要导 数相等,即p’(1)=aq’(0) 称为G1几何连续性。将该思想推广到高阶导数,就可得到C n和G n连续性。

计算机图形学

a.扫描线算法:目标:利用相邻像素之间的连贯性,提高算法效率。处理对象:简单多边形,非自交多边形(边与边之间除了顶点外无其它交点)。扫描线:平行于坐标轴的直线,一般取平行于X轴。区间:扫描线与边的交点间的线段。基本原理:将整个绘图窗口内扫描多边形的问题分解到一条条扫描线,只要完成每条扫描线的绘制就实现了多边形的扫描转换;一条扫描线与多边形的边有偶数个交点,每2个点形成一区间。步骤:(对于每一条扫描线)(1)计算扫描线与边的交点(2)交点按x坐标从小到大排序(3)交点两两配对,填充区间。算法:1、建立ET;2、将扫描线纵坐标y的初值置为ET中非空元素的最小序号,如图中,y=1;3、置AEL为空;4、执行下列步骤直至ET和AEL都为空.4.1、如ET中的第y类非空,则将其中的所有边取出并插入AEL 中;4.2、如果有新边插入AEL,则对AEL中各边排序;4.3、对AEL中的边两两配对,(1和2为一对,3和4为一对,…),将每对边中x坐标按规则取整,获得有效的填充区段,再填充.4.4、将当前扫描线纵坐标 y 值递值1;4.5、将AEL中满足y = ymax边删去(因为每条边被看作下闭上开的);4.6、对AEL中剩下的每一条边的x 递增deltax,即x = x+deltax. b.走样与反走样:走样:用离散量(像素)表示连续的量(图形)而引起的失真,称为走样,或称为混淆。光栅图形的走样现象:阶梯(锯齿)状边界、图形细节失真、狭小图形遗失:动画序列中时隐时现,产生闪烁。反走样:在图形显示过程中,用于减少或消除走样(混淆)现象的方法。方法:提高分辨率方法{方法简单,但代价非常大,显示器的水平、竖直分辩率各提高一倍,则显示器的点距减少一倍,帧缓存容量则增加到原来的4倍,而扫描转换同样大小的图元却要花4倍时间}、非加权区域采样{扫描转换线段的两点假设:像素是数学上抽象的点,它的面积为0,它的亮度由覆盖该点的图形的亮度所决定;直线段是数学上抽象直线段,它的宽度为0。而现实:像素的面积不为0;直线段的宽度至少为1个像素;假设与现实的矛盾是导致走样出现的原因之一。解决方法:改变直线段模型,线上像素灰度不等。方法步骤:1、将直线段看作具有一定宽度的狭长矩形;2、当直线段与某像素有交时,求出两者相交区域的面积;3、根据相交区域的面积,确定该像素的亮度值}、加权区域采样{权函数w(x, y),以像素A的中心为原点建立二维坐标系,w(x, y)反应了微面积元dA对整个像素亮度的贡献大小,与 dA 到像素中心距离d 成反比。实现步骤:1.求直线段与像素的相交区域2.计算的值3.上面所得到的值介于0、1之间,用它乘像素的最大灰度值,即设该像素的显示灰度。问题:计算量大。 c.为什么需要齐次坐标? 1、对多个点计算多次不同的变换时,分别利用矩阵计算各变换导致计算量大2、运算表示形式不统一:平移为“+”、旋转和放缩为“·”3、统一运算形式后,可以先合成变换运算的矩阵,再作用于图形对象。 d.Sutherland-Hodgman算法:S-H算法基本思想(亦称逐边裁剪算法):将多边形关于矩形窗口的裁剪分解为多边形关于窗口四边所在直线的裁剪。步骤:1、多边形由一系列顶点表示:V1V2…Vn2、按一定(左上右下)的次序依次裁剪; 与左边所在直线裁剪

计算机图形学中英文课程简介

计算机图形学中英文课程简介 实施和推进“双语教学”是我国高等教育适应国际化趋势、培养富有创新精神和国际视野的复合型高素质人才的重要举措。在学院领导和相关部门的关心和支持下,计算机图形学课程被推荐选为双语教学课程。 计算机图形学课程是国际计算机学科领域的一门主干课程,是国际计算机科学与技术专业本科所开设的必修课程之一。计算机图形学是最令人兴奋并且发展最快的计算机领域之一,已经成为人机交互、可视化、游戏、动画、虚拟/增强现实、计算机仿真、CAD、GIS等共性基础问题。开设本门课程的主要目的是让学生掌握计算机图形学基本内容,为将来的工作和进一步深造打下坚实的基础。 充分发挥多媒体教学的作用,初步实现双语教学,突出教学改革目的。让学生了解计算机图形系统的硬件体系结构、软件架构和典型应用。掌握计算机图形学的基本概念、基本原理、基本算法。重点掌握图形在计算机系统内部显示的全过程,包括:扫描转换、几何变换、投影、剪裁、消隐、颜色理论、交互技术、真实感显示。整个教学过程,采用自顶向下的方法,通过对OpenGL图形的编程和初步应用实践活动,逐步引导学生对图形学理论方法和技术的学习和深化。 学生在学习该门课程时,最好已经具备以下基本知识和技能:已经掌握基本 C /C++编程能力、基本数据结构、几何数学知识、简单线性算法。 教材选用美国原版教材,由新墨西哥大学ANGEL教授所著INTERACTIVE COMPUTER GRAPHICS: A TOP-DOWN APPROACH USING OPENGL (5TH EDITION) 。ANGEL教授自从1997年发布该书第一版以来,一直活跃在计算机图形学领域教学科研第一线。2009该书连续发布到了第5版,被国内外众多大学选为教材和参考书。参考书将采用Addison-Wesley 出版社的The OpenGL Programmer’s Guide (the Redbook中文称为红宝书) 和the OpenGL Reference Manual (The Blue book中文称为蓝宝书)。 Introduction to Computer Graphics Computer graphics has been widely used in human-computer interaction, visualization, game, animation, virtual / augmented reality, computer simulation, computer-aided design (CAD), geographic information system(GIS). The course is an introduction course to computer graphics, which give a broad introduction to Computer Graphics, including software, hardware and applications. A top-down approach will be used in the teaching and studying and OpenGL will be selected as basic programming environment. The prerequisites for the course is that the student should have a good knowledge of programming skills in C (or C++), basic data structures, linked lists, arrays, geometry and simple linear algebra. The outline of course the will be summarized as follows. Part 1: Introduction, Chapter 1, Lectures 1-3, What is Computer Graphics? Applications

相关主题
文本预览
相关文档 最新文档