计算机图形学项目报告

合集下载

图形学实验报告

图形学实验报告

计算机图形学实验报告直线的生成程序设计:实验目的:掌握直线段的生成算法, 并用C/WIN-TC/VC++实现算法, 包括中点法生成直线, 微分数值法生成直线段等。

实验内容:用不同的方法生成斜率不同的直线段, 比较各种方法的效果。

/////////////////////////////////////////////////////////////////////////////// CLineView drawingvoid DDALine(int x1,int y1,int x2,int y2,int color,CDC*pDC)//数值微分法{int x;int k,y=y1;k=1.0*(y2-y1)/(x2-x1);for(x=x1;x<=x2;x++){pDC->SetPixel(x,(int)(y+0.5),color);y=y+k;}}void MPLine(int x1,int y1,int x2,int y2,int color,CDC*pDC)//中点画线法{int x,y,a,b,d,d1,d2;a=y1-y2; b=x2-x1;y=y1;d=2*a+b; d1=2*a; d2=2*(a+b);pDC->SetPixel(x,y,color);for(x=x1;x<=x2;x++){if(d<0) { y++; d+=d2;}else {d+=d1;}pDC->SetPixel(x,y,color);}}void BHLine(int x1,int y1,int x2,int y2,int color,CDC*pDC)//Bresenham画线法{int x,y,dx,dy,dk;dx=abs(x2-x1);dy=abs(y2-y1);dk=2*dy-dx;y=y1;for(x=x1;x<=x2;x++){pDC->SetPixel(x,y,color);dk=dk+2*dy;if(dk>=0){ y++; dk=dk-2*dx;}}}void CLineView::OnDraw(CDC* pDC){CLineDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);DDALine(100,100,200,70,255,pDC);//数值微分法pDC->TextOut(200,70,"数值微分画线");MPLine(100,120,200,140,255,pDC);//中点画线法pDC->TextOut(200,140,"中点画线");BHLine(100,140,200,190,255,pDC);//Bresenham画线法pDC->TextOut(200,190,"Bresenham画线法");// TODO: add draw code for native data here}运行结果:2.圆的生成程序设计:实验目的:掌握用C/WIN-TC/VC++实现算法, 圆的生成算法实验内容: 用中点画圆法、Bresenham画圆法/////////////////////////////////////////////////////////////////////////////// CCircleView drawingvoid WholeCircle(int xc,int yc,int x,int y,int color,CDC*pDC){pDC->SetPixel(xc+x,yc+y,color);pDC->SetPixel(xc-x,yc+y,color);pDC->SetPixel(xc+x,yc-y,color);pDC->SetPixel(xc-x,yc-y,color);pDC->SetPixel(xc+y,yc+x,color);pDC->SetPixel(xc-y,yc+x,color);pDC->SetPixel(xc+y,yc-x,color);pDC->SetPixel(xc-y,yc-x,color);}void MidCircle(int xc,int yc,int r,int color,CDC*pDC )//中点画圆法{int x,y,d;x=0;y=r;d=1-r;WholeCircle(xc,yc,x,y,color,pDC);while(x<=y){if(d<0){ d+=2*x+3;x++;}else{ d+=2*(x-y)+5;x++; y--;}WholeCircle(xc,yc,x,y,color,pDC);}WholeCircle(xc,yc,x,y,color,pDC);}void BresenhamCircle(int xc,int yc,int r,int color,CDC*pDC)//Bresenham画圆法{ int x,y,d;x=0; y=r;d=3-2*r;while(x<y){WholeCircle(xc,yc,x,y,color,pDC);if(d<0)d=d+4*x+6;else{d=d+4*(x-y)+10;y--;}x++;}if(x==y) WholeCircle(xc,yc,x,y,color,pDC);}void CCircleView::OnDraw(CDC* pDC){CCircleDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);MidCircle(100,100,70,255,pDC);//中点画圆法pDC->TextOut(175,100,"中点画圆法");BresenhamCircle(100,250, 80, 255,pDC);//Bresenham画圆法pDC->TextOut(185,250,"Bresenham画圆法");// TODO: add draw code for native data here}运行结果:3.椭圆的生成程序设计:实验目的:掌握用C/WIN-TC/VC++实现算法, 椭圆的生成算法实验内容: 实现椭圆的算法// CMPEllipseView drawingvoid WholeEllipse(int xc,int yc,int x,int y,int color,CDC*pDC) {pDC->SetPixel(xc+x,yc+y,color);pDC->SetPixel(xc+x,yc-y,color);pDC->SetPixel(xc-x,yc+y,color);pDC->SetPixel(xc-x,yc-y,color);}void MidEllipse(int xc,int yc,int a,int b,int color,CDC*pDC) {int aa=a*a, bb=b*b;int twoaa=2*aa, twobb=2*bb;int x=0, y=b;int dx=0, dy=twoaa*y;int d=(int)(bb+aa*(-b+0.25)+0.5);WholeEllipse(xc,yc,x,y,color,pDC);while(dx<dy){x++; dx+=twobb;if(d<0)d+=bb+dx;else{ y--;dy-=twoaa;d+=bb+dx-dy;}WholeEllipse(xc,yc,x,y,color,pDC);}d=(int)(bb*(x+0.5)*(x+0.5)+aa*(y-1)*(y-1)-aa*bb+0.5);while(y>0){y--; dy-=twoaa;if(d>0)d+=aa-dy;else{ x++;dx+=twobb; d+=aa-dy+dx; }WholeEllipse(xc,yc,x,y,color,pDC);}}void CMPEllipseView::OnDraw(CDC* pDC){CMPEllipseDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);MidEllipse(200,100,100,50,255, pDC);pDC->TextOut(305,100,"中点画椭圆法");// TODO: add draw code for native data here }运行结果:4.有序边表填充算法程序设计实验目的:掌握用C/WIN-TC/VC++实现算法, 有序边生成算法实验内容: 实现有序边填充算法代码如下:#define WINDOW_HEIGHT 480#define NULL 0typedef struct tEdge /* 有序便表和活化边表的结构 */ {int ymax;float x,dx;struct tEdge *next;} Edge;typedef struct point{int x,y;} tPOINT;void InsertEdge(Edge *list,Edge *edge){Edge *p,*q = list;p = q->next;while(p){if (edge->x < p->x){p = NULL;}else{q = p;p = p->next;}}edge->next = q->next;q->next = edge;}int yNext(int k,int cnt,tPOINT *pts){int j;if ((k+1)>(cnt-1)){j = 0;}else{j = k+1;}while(pts[k].y == pts[j].y){ if ((j+1) > (cnt-1)){ j = 0;}else{ j++;}}return pts[j].y;}void MakeEdgeRec(tPOINT lower,tPOINT upper,int yComp,Edge *edge,Edge *edges[]) /* 生成有序边表的一条边 */{edge->dx = (float)(upper.x - lower.x)/(upper.y - lower.y);edge->x = lower.x;if (upper.y < yComp){edge->ymax = upper.y - 1;}else{edge->ymax = upper.y;}InsertEdge(edges[lower.y],edge);}void BuildEdgeList(int cnt,tPOINT *pts,Edge *edges[]){ Edge *edge;tPOINT v1,v2;int i,yPrev = pts[cnt-2].y;v1.x = pts[cnt-1].x;v1.y = pts[cnt-1].y;for (i = 0;i < cnt;i++){v2 = pts[i];if (v1.y != v2.y){edge = (Edge *)malloc(sizeof(Edge)); /* C语言中的malloc */if (v1.y < v2.y){MakeEdgeRec(v1,v2,yNext(i,cnt,pts),edge,edges);}else{MakeEdgeRec(v2,v1,yPrev,edge,edges);}yPrev = v1.y;v1 = v2;}}}void BuildActiveList(int scan,Edge *active,Edge *edges[]){Edge *p,*q;p = edges[scan]->next;while (p){q = p->next;InsertEdge(active,p);p = q;}}void FillScan(int scan,Edge *active,int color,CDC *pDC){int i;Edge *p1,*p2;p1 = active->next;while(p1){p2 = p1->next;for (i = p1->x;i < p2->x;i++){pDC->SetPixel((int)i,scan,color);}p1 = p2->next;}}void DeletAfter(Edge *q){Edge *p = q->next;q->next = p->next;free(p);}void UpdateActiveList(int scan,Edge *active){Edge *q = active,*p = active->next;while(p){if (scan >= p->ymax){p = p->next;DeletAfter(q);}else{p->x = p->x + p->dx;q = p;p = p->next;}}}void ResortActiveList(Edge *active){Edge *q,*p = active->next;active->next = NULL;while(p){q = p->next;InsertEdge(active,p);p = q;}}void ScanFill(int cnt,tPOINT *pts,int color,CDC *pDC) {Edge *edges[WINDOW_HEIGHT],*active;int i,scan,scanmax = 0,scanmin = WINDOW_HEIGHT;for (i = 0;i < cnt-1;i++){if (scanmax < pts[i].y){scanmax = pts[i].y;}if (scanmin > pts[i].y){scanmin = pts[i].y;}}for (scan = scanmin;scan <= scanmax;scan++){edges[scan] = (Edge *)malloc(sizeof(Edge));edges[scan]->next = NULL;}BuildEdgeList(cnt,pts,edges);active = (Edge *)malloc(sizeof(Edge));active->next = NULL;for (scan = scanmin;scan <= scanmax;scan++){BuildActiveList(scan,active,edges);if (active->next){FillScan(scan,active,color,pDC);UpdateActiveList(scan,active);ResortActiveList(active);}}}CFillView::CFillView(){// TODO: add construction code here}CFillView::~CFillView(){}BOOL CFillView::PreCreateWindow(CREATESTRUCT& cs){// TODO: Modify the Window class or styles here by modifying// the CREATESTRUCT csreturn CView::PreCreateWindow(cs);}///////////////////////////////////////////////////////////////////////////// // CFillView drawingvoid CFillView::OnDraw(CDC* pDC){CFillDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data heretPOINT points[3]={{100,80},{300,100},{300,260}};tPOINT *p = points;int color = RGB(255,2,0);ScanFill(3,p,color,pDC);}运行结果:8.Cohen-SutherLand编码裁剪算法程序设计#define LEFT 1#define RIGHT 2#define BOTTOM 4#define TOP 8typedef struct point { int x,y;} POINT1;void Encode (int x,int y,int *code,int XL,int XR,int YB,int YT,CDC *pDC) {int c=0;if(x<XL) c=c|LEFT;else if(x>XR) c=c|RIGHT;if (y<YB) c=c|BOTTOM;else if (y>YT) c=c|TOP;(*code)=c;}void C_S_Line(POINT p1,POINT p2,int XL,int XR,int YB,int YT,CDC *pDC) {int x1,x2,y1,y2,x,y;int code1,code2,code;x1=p1.x;x2=p2.x;y1=p1.y;y2=p2.y;Encode(x1,y1,&code1,XL,XR,YB,YT,pDC);Encode(x2,y2,&code2,XL,XR,YB,YT,pDC);while(code1!=0 || code2!=0){if ((code1 & code2) !=0) return;code=code1;if (code1==0) code=code2;if ((LEFT & code) !=0){x=XL;y=y1+(y2-y1)*(XL-x1)/(x2-x1);}else if((RIGHT & code)!=0){x=XR;y=y1+(y2-y1)*(XR-x1)/(x2-x1);}else if((BOTTOM & code) != 0){y=YB;x=x1+(x2-x1)*(YB-y1)/(y2-y1);}else if((TOP & code)!=0){y=YT;x=x1+(x2-x1)*(YT-y1)/(y2-y1);}if(code==code1){x1=x; y1=y;Encode(x,y,&code1,XL,XR,YB,YT,pDC);}else{x2=x; y2=y;Encode(x,y,&code2,XL,XR,YB,YT,pDC);}}p1.x=x1;p1.y=y1;p2.x=x2;p2.y=y2;pDC->MoveTo(p1.x,p1.y);pDC->LineTo(p2.x,p2.y);}void CCohenView::OnDraw(CDC* pDC){CCohenDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);POINT p1,p2,p3,p4,p5,p6,p7,p8;p1.x=35;p1.y=160;p2.x=245;p2.y=121;p3.x=120;p3.y=60;p4.x=200;p4.y=300;p5.x=169;p5.y=45;p6.x=150;p6.y=200;p7.x=120;p7.y=200;p8.x=220;p8.y=130;pDC->LineTo(120,100);pDC->LineTo(210,100);pDC->LineTo(220,180);pDC->LineTo(120,170);pDC->LineTo(110,100);C_S_Line(p1,p2,100,200,90,170,pDC); C_S_Line(p3,p4,100,200,90,170,pDC); }运行结果:6.基于链队列的种子填充算法程序设计程序代码:#define NULL 0typedef struct point{ int x,y;}POINT1;typedef struct QNode{POINT Data;struct QNode *Next;}QNode,*QPtr;typedef struct{QPtr Front;QPtr Rear;}LinkQueue;LinkQueue q;void CreateQueue(){q.Front=q.Rear=(QPtr)malloc(sizeof(QNode));q.Rear->Next=NULL;}POINT Dequeue(){QNode *p;POINT x;p=q.Front;x=q.Front->Data;q.Front=q.Front->Next;free(p);return x;}void Enqueue(POINT x){QNode *p=(QPtr)malloc(sizeof(QNode));q.Rear->Next=p;q.Rear->Data=x;q.Rear=p;}int Empty(){if( q.Front==q.Rear)return 1;else return 0;}void QueueSeedFill(int seedx, int seedy, int fcolor, int bcolor,CDC *pDC) {int color;POINT pt,p,p1,p2,p3,p4;pDC->SetPixel(seedx,seedy,fcolor);p.x=seedx;p.y=seedy;Enqueue(p);while(!Empty()){pt=Dequeue();color=pDC->GetPixel(pt.x,pt.y-1);if(color!=bcolor && color!=fcolor){pDC->SetPixel(pt.x,pt.y-1,fcolor);p1.x=pt.x;p1.y=pt.y-1;Enqueue(p1);}color= pDC->GetPixel(pt.x,pt.y+1);if(color!=bcolor && color!=fcolor){pDC->SetPixel(pt.x,pt.y+1,fcolor);p2.x=pt.x;p2.y=pt.y+1;Enqueue(p2);}color=pDC->GetPixel(pt.x-1,pt.y);if(color!=bcolor && color!=fcolor){pDC->SetPixel(pt.x-1,pt.y,fcolor);p3.x=pt.x-1;p3.y=pt.y;Enqueue(p3);}color=pDC->GetPixel(pt.x+1,pt.y);if(color!=bcolor && color!=fcolor){pDC->SetPixel(pt.x+1,pt.y,fcolor);p4.x=pt.x+1;p4.y=pt.y;Enqueue(p4);}}}void EdgeMark(int x1,int y1,int x2,int y2,int color,CDC *pDC){int i,length;float dx,dy,x=x1,y=y1;if (abs(x2-x1)>=abs (y2-y1))length=abs(x2-x1);elselength=abs(y2-y1);dx=(float)(x2-x1)/length;dy=(float)(y2-y1)/length;pDC->SetPixel((int)(x+0.5),(int)(y+0.5),color);for(i=1;i<=length;i++){x=x+dx;y=y+dy;pDC->SetPixel((int)(x+0.5),(int)(y+0.5),color);}}void QSeedFill(int cnt,POINT *pts,int seedx,int seedy,int fcolor,int bcolor,CDC *pDC){POINT v1,v2;int i;for(i=0;i<cnt-1;i++){v1=pts[i]; v2=pts[i+1];EdgeMark(v1.x,v1.y,v2.x,v2.y,bcolor,pDC);}QueueSeedFill(seedx,seedy,fcolor,bcolor,pDC); }void CQseedFillView::OnDraw(CDC* pDC){CQseedFillDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);POINT pts[7];pts[0].x=40;pts[0].y=12;pts[1].x=75;pts[1].y=45;pts[2].x=110;pts[2].y=20;pts[3].x=130;pts[3].y=70;pts[4].x=80;pts[4].y=110;pts[5].x=25;pts[5].y=60;pts[6].x=40;pts[6].y=15;QSeedFill(8,pts,70,80,2,4,pDC);}运行结果:13.Bezier曲线绘制程序设计程序代码如下:// CBezierView drawingtypedef struct point {int x,y;}POINT1;void Parabola(POINT *p,int n,CDC *pDC){int x,y,i,j,k=10;double t1,t2,t3,t,a,b,c,d;p[n].x=p[n-1].x;p[n].y=p[n-1].y;t=0.5/k;pDC->MoveTo(p[1].x,p[1].y);for(i=1;i<n-1;i++){for(j=1;j<k;j++){t1=j*t;t2=t1*t1;t3=t2*t1;a=4.0*t2-t1-4.0*t3; b=1.0-10.0*t2+12.0*t3;c=t1+8.0*t2-12.0*t3; d=4.0*t3-2.0*t2;x=(int)(a*p[i-1].x+b*p[i].x+c*p[i+1].x+d*p[i+2].x);y=(int)(a*p[i-1].y+b*p[i].y+c*p[i+1].y+d*p[i+2].y);pDC->LineTo(x,y);}pDC->LineTo(p[i+1].x,p[i+1].y);}}double powi(double v,int k){int i;double temp=1.0;if(k==0 || v==0)return 1;else{for(i=1;i<=k;i++)temp=temp*v;}return temp;}long fac(int m){int i;long temp=1;if(m==0)return 1;else{for(i=2;i<=m;i++)temp=temp*i;}return temp;}void Bezier(POINT *p,int n,CDC *pDC){int x,y,i,j,k=100;double t,t1,u,v;double temp,temp1,temp2,bi;t=1.0/k;pDC->MoveTo(p[0].x,p[0].y);for(j=1;j<k;j++){t1=j*t;u=t1;v=1-u;x=0;y=0;for(i=0;i<=n;i++){temp=(double)fac(n)/fac(i)/fac(n-i);temp1=powi(u,i);temp2=powi(v,n-i);bi=temp*temp1*temp2;x=x+bi*p[i].x;y=y+bi*p[i].y;}pDC->LineTo(x,y);}pDC->LineTo(p[n].x,p[n].y);}void BSpLine(POINT *p, int n,CDC *pDC){int x,y,i,j,k=1000;double t,t1,t2,t3,a,b,c,d;t=1.0/k;p[n].x=2*p[n-1].x-p[n-2].x;p[n].y=2*p[n-1].y-p[n-2].y;pDC->MoveTo(p[1].x,p[1].y);for(i=1;i<n-1;i++){for(j=1;j<=k;j++){t1=j*t;t2=t1*t1;t3=t2*t1;a=(3*t2-t3-3*t1+1)/6;b=(3*t3-6*t2+4)/6;c=(3*t2-3*t3+3*t1+1)/6;d=t3/6;x=(int)(a*p[i-1].x+b*p[i].x+c*p[i+1].x+d*p[i+2].x);y=(int)(a*p[i-1].y+b*p[i].y+c*p[i+1].y+d*p[i+2].y);pDC->LineTo(x,y);}}}void CardinalSpLine(POINT *p,int n,float tension,CDC *pDC) {int x,y,i,j,k=1000;double t,t1,t2,t3,a,b,c,d,s;t=1.0/k;s=(1.0-tension)/2.0;p[n].x=2*p[n-1].x-p[n-2].x;p[n].y=2*p[n-1].y-p[n-2].y;pDC->MoveTo(p[1].x,p[1].y);for(i=1;i<n-1;i++){for(j=1;j<=k;j++){t1=j*t;t2=t1*t1;t3=t2*t1;a=-s*t3+2*s*t2-s*t1;b=(2-s)*t3+(s-3)*t2+1;c=(s-2)*t3+(3-2*s)*t2+s*t1;d=s*t3-s*t2;x=(int)(a*p[i-1].x+b*p[i].x+c*p[i+1].x+d*p[i+2].x);y=(int)(a*p[i-1].y+b*p[i].y+c*p[i+1].y+d*p[i+2].y);pDC->LineTo(x,y);}}}void CBezierView::OnDraw(CDC* pDC){CBezierDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);int n=5;POINT ps[4];ps[0].x=60;ps[0].y=200;ps[1].x=50;ps[1].y=200;ps[2].x=160;ps[2].y=60;ps[3].x=200;ps[3].y=200;ps[4].x=350;ps[4].y=60;pDC->MoveTo(ps[0].x,ps[0].y);pDC->LineTo(ps[1].x,ps[1].y);pDC->LineTo(ps[2].x,ps[2].y);pDC->LineTo(ps[3].x,ps[3].y);Parabola(ps,n,pDC);CardinalSpLine(ps,n,0.5,pDC);Bezier(ps,n-1,pDC);BSpLine(ps,n,pDC);}。

计算机图形学实验报告4

计算机图形学实验报告4

计算机图形学实验报告4一、实验目的本次计算机图形学实验旨在深入了解和掌握计算机图形学中的一些关键概念和技术,通过实际操作和编程实现,提高对图形生成、变换、渲染等方面的理解和应用能力。

二、实验环境本次实验使用的软件环境为_____,编程语言为_____,硬件环境为_____。

三、实验内容1、二维图形的绘制使用基本的绘图函数,如直线、矩形、圆形等,绘制简单的二维图形。

通过设置线条颜色、填充颜色等属性,增强图形的表现力。

2、图形的几何变换实现图形的平移、旋转和缩放操作。

观察不同变换参数对图形的影响。

3、三维图形的生成构建简单的三维模型,如立方体、球体等。

应用光照和材质效果,使三维图形更加逼真。

四、实验步骤1、二维图形的绘制首先,在编程环境中导入所需的图形库和相关模块。

然后,定义绘图窗口的大小和坐标范围。

接下来,使用绘图函数按照指定的坐标和参数绘制直线、矩形和圆形。

最后,设置图形的颜色和填充属性,使图形更加美观。

2、图形的几何变换对于平移操作,通过修改图形顶点的坐标值来实现水平和垂直方向的移动。

对于旋转操作,根据旋转角度计算新的顶点坐标,实现图形的绕中心点旋转。

对于缩放操作,将图形的顶点坐标乘以缩放因子,达到放大或缩小图形的效果。

3、三维图形的生成首先,定义三维模型的顶点坐标和三角形面的连接关系。

然后,设置光照的位置、颜色和强度等参数。

接着,为模型添加材质属性,如颜色、反射率等。

最后,使用渲染函数将三维模型显示在屏幕上。

五、实验结果与分析1、二维图形的绘制成功绘制出了各种简单的二维图形,并且通过颜色和填充的设置,使图形具有了更好的视觉效果。

例如,绘制的矩形和圆形边缘清晰,颜色鲜艳,填充均匀。

2、图形的几何变换平移、旋转和缩放操作都能够准确地实现,并且变换效果符合预期。

在旋转操作中,发现旋转角度的正负会影响旋转的方向,而缩放因子的大小直接决定了图形的缩放程度。

3、三维图形的生成生成的三维模型具有一定的立体感和真实感。

《计算机图形学》实验报告

《计算机图形学》实验报告

《计算机图形学》实验报告目录1实验2:直线的生成 (1)1.1实验要求和目的 (1)1.2实验课时 (1)1.3实验环境 (1)1.4实验内容 (1)1.5核心代码 (3)1.6实验结果 (7)1.6.1DDA算法 (10)1.6.2Mid-Bresenham算法 (11)1.7心得与体会 (12)2实验4:BSpline曲线绘制 (13)2.1实验要求和目的 (13)2.2实验课时 (13)2.3实验环境 (13)2.4实验内容 (13)2.5核心代码 (16)2.6实验结果 (18)2.6.1B-样条算法 (19)2.6.2Bezeir算法 (22)2.7心得与体会 (24)附录 (25)BSpline曲线控制点的测试数据 (25)数据1 (25)数据2 (27)数据3 (29)数据4 (30)数据5 (31)数据6 (33)数据7 (36)数据8 (38)1实验2:直线的生成1.1实验要求和目的理解直线生成的原理;掌握典型直线生成算法;掌握步处理、分析实验数据的能力;编程实现DDA算法、Bresenham中点算法;对于给定起点和终点的直线,分别调用DDA算法和Bresenham中点算法进行批量绘制,并记录两种算法的绘制时间;利用excel 等数据分析软件,将试验结果编制成表格,并绘制折线图比较两种算法的性能。

1.2实验课时3学时1.3实验环境本试验提供自带实验平台·开发环境:Visual C++ 6.0·实验平台:Free_Curve(自制平台)1.4实验内容本实验提供名为 Experiment_Frame_One的平台,该平台提供基本绘制、设置、输入功能,学生在此基础上实现·平台界面:如图1.4.1所示·设置:通过view->setting菜单进入,如图1.4.2所示·输入:通过view->input…菜单进入,如图1.4.3所示·实现算法:▪DDA算法:void CExperiment_Frame_OneView::DDA(int X0, int Y0, int X1, int Y1)▪Mid_Bresenham算法:voidCExperiment_Frame_OneView::Mid_Bresenham(int X0, int Y0, int X1, int Y1)图 1.4.1 总界面图 1.4.2 设置界面图 1.4.3 输入界面1.5核心代码本次实验的核心代码如下所示。

计算机图形学第五次实验报告

计算机图形学第五次实验报告

《计算机图形学》实验报告实验十一真实感图形一、实验教学目标与基本要求初步实现真实感图形, 并实践图形的造型与变换等。

二、理论基础运用几何造型, 几何、投影及透视变换、真实感图形效果(消隐、纹理、光照等)有关知识实现。

1.用给定地形高程数据绘制出地形图;2.绘制一(套)房间,参数自定。

三. 算法设计与分析真实感图形绘制过程中, 由于投影变换失去了深度信息, 往往导致图形的二义性。

要消除这类二义性, 就必须在绘制时消除被遮挡的不可见的线或面, 习惯上称之为消除隐藏线和隐藏面, 或简称为消隐, 经过消隐得到的投影图称为物体的真实图形。

消隐处理是计算机绘图中一个引人注目的问题, 目前已提出多种算法, 基本上可以分为两大类:即物体空间方法和图象空间方法。

物体空间方法是通过比较物体和物体的相对关系来决定可见与不可见的;而图象空间方法则是根据在图象象素点上各投影点之间的关系来确定可见与否的。

用这两类方法就可以消除凸型模型、凹形模型和多个模型同时存在时的隐藏面。

1).消隐算法的实现1.物体空间的消隐算法物体空间法是在三维坐标系中, 通过分析物体模型间的几何关系, 如物体的几何位置、与观察点的相对位置等, 来进行隐藏面判断的消隐算法。

世界坐标系是描述物体的原始坐标系, 物体的世界坐标描述了物体的基本形状。

为了更好地观察和描述物体, 经常需要对其世界坐标进行平移和旋转, 而得到物体的观察坐标。

物体的观察坐标能得到描述物体的更好视角, 所以物体空间法通常都是在观察坐标系中进行的。

观察坐标系的原点一般即是观察点。

物体空间法消隐包括两个基本步骤, 即三维坐标变换和选取适当的隐藏面判断算法。

选择合适的观察坐标系不但可以更好地描述物体, 而且可以大大简化和降低消隐算法的运算。

因此, 利用物体空间法进行消隐的第一步往往是将物体所处的坐标系转换为适当的观察坐标系。

这需要对物体进行三维旋转和平移变换。

常用的物体空间消隐算法包括平面公式法、径向预排序法、径向排序法、隔离平面法、深度排序法、光线投射法和区域子分法。

计算机图形学实验报告_2

计算机图形学实验报告_2

计算机图形学实验报告学号:********姓名:班级:计算机 2班指导老师:***2010.6.19实验一、Windows 图形程序设计基础1、实验目的1)学习理解Win32 应用程序设计的基本知识(SDK 编程);2)掌握Win32 应用程序的基本结构(消息循环与消息处理等); 3)学习使用VC++编写Win32 Application 的方法。

4)学习MFC 类库的概念与结构;5)学习使用VC++编写Win32 应用的方法(单文档、多文档、对话框);6)学习使用MFC 的图形编程。

2、实验内容1)使用WindowsAPI 编写一个简单的Win32 程序,调用绘图API 函数绘制若干图形。

(可选任务)2 )使用MFC AppWizard 建立一个SDI 程序,窗口内显示"Hello,Thisis my first SDI Application"。

(必选任务)3)利用MFC AppWizard(exe)建立一个SDI 程序,在文档视口内绘制基本图形(直线、圆、椭圆、矩形、多边形、曲线、圆弧、椭圆弧、填充、文字等),练习图形属性的编程(修改线型、线宽、颜色、填充样式、文字样式等)。

定义图形数据结构Point\Line\Circle 等保存一些简单图形数据(在文档类中),并在视图类OnDraw 中绘制。

3、实验过程1)使用MFC AppWizard(exe)建立一个SDI 程序,选择单文档;2)在View类的OnDraw()函数中添加图形绘制代码,说出字符串“Hello,Thisis my first SDI Application”,另外实现各种颜色、各种边框的线、圆、方形、多边形以及圆弧的绘制;3)在类视图中添加图形数据point_pp,pp_circle的类,保存简单图形数据,通过在OnDraw()函数中调用,实现线、圆的绘制。

4、实验结果正确地在指定位置显示了"Hello,This is my first SDI Application"字符串,成功绘制了圆,椭圆,方形,多边形以及曲线圆弧、椭圆弧,同时按指定属性改绘了圆、方形和直线。

计算机图形学报告

计算机图形学报告

计算机图形学报告计算机图形学,这门神奇的学科就像是一个充满魔法的宝藏箱,藏着无数让我们惊叹不已的秘密和乐趣。

从小学到高中,我们在不同的学科里探索知识的海洋,但计算机图形学就像是其中一颗独特而耀眼的明珠。

我还记得有一次,我在公园里散步,看到一群小朋友在玩一个简单的游戏。

他们在地上画了一个大大的棋盘,然后用小石子当作棋子。

这看似简单的画面,其实就是计算机图形学在生活中的一个小小体现。

棋盘的线条,石子的形状,还有它们在地上的布局,这不就是图形的组合与呈现嘛。

计算机图形学,简单来说,就是研究如何用计算机生成、处理和显示图形的学科。

它可不是那种只存在于实验室或者高科技公司里的神秘玩意儿,而是实实在在融入了我们生活的方方面面。

就拿我们每天都离不开的手机来说吧。

那些精美的图标、炫酷的游戏画面、清晰的视频通话,背后都离不开计算机图形学的功劳。

想象一下,如果手机屏幕上的图像模糊不清、颜色失真,那得多扫兴啊!在学习中,计算机图形学也有着重要的作用。

比如数学里的几何图形,通过计算机图形学的技术,我们可以更加直观地看到各种图形的变化和关系。

物理课上的实验模拟,化学分子的结构展示,都因为有了计算机图形学而变得更加生动有趣,让我们更容易理解那些复杂的概念。

再来说说我们喜欢的动画片和电影。

那些逼真的人物形象、美轮美奂的场景,都是通过计算机图形学一点点创作出来的。

制作团队要考虑光线、阴影、材质等各种因素,才能让我们看到仿佛真实存在的虚拟世界。

而且,计算机图形学在医学领域也大显身手呢!医生可以通过三维图形更准确地诊断病情,制定手术方案。

建筑师能利用它来设计出更具创意和实用性的建筑。

还记得我小时候,特别喜欢玩那种拼图游戏。

每次把一块块零碎的图片拼成一个完整的画面,都有一种满满的成就感。

而计算机图形学,就像是一个超级强大的拼图高手,把无数的像素点组合成我们眼前精彩的世界。

在未来,计算机图形学的发展更是让人充满期待。

也许有一天,我们能够通过虚拟现实技术,真正身临其境般地走进一个完全由计算机图形构建的世界,那该是多么奇妙的体验啊!总之,计算机图形学就像是一位神奇的魔法师,不断地给我们的生活带来惊喜和变化。

计算机图形学实验报告

计算机图形学实验报告
实验目的:通过本次实验,深入了解并掌握计算机图形学的基本原理和相关技术,培养对图形处理的理解和能力。

实验内容:
1. 图像的基本属性
- 图像的本质及表示方法
- 像素和分辨率的概念
- 灰度图像和彩色图像的区别
2. 图像的处理技术
- 图像的采集和处理
- 图像的变换和增强
- 图像的压缩和存储
3. 计算机图形学的应用
- 图像处理在生活中的应用
- 计算机辅助设计中的图形学应用
- 三维建模和渲染技术
实验步骤和结果:
1. 在计算机图形学实验平台上加载一张测试图像,分析其像素构成
和基本属性。

2. 运用图像处理技术,对测试图像进行模糊、锐化、色彩调整等操作,观察处理后的效果并记录。

3. 学习并掌握计算机图形学中常用的处理算法,如卷积、滤波等,
尝试应用到测试图像上并进行实验验证。

4. 探讨计算机图形学在数字媒体制作、虚拟现实、计算机辅助设计
等领域的应用案例,并总结其在实践中的重要性和价值。

结论:
通过本次实验,我对计算机图形学有了更深入的了解,掌握了图像
处理技术的基本原理和应用方法。

计算机图形学作为一门重要的学科,对多个领域有着广泛的应用前景,有助于提高数字媒体技术、虚拟现
实技术等领域的发展水平。

希望在未来的学习和工作中能进一步深化
对计算机图形学理论和实践的研究,不断提升自己在这一领域的专业
能力和创新意识。

《计算机图形学》实验报告

《计算机图形学》实验报告一、实验目的计算机图形学是一门研究如何利用计算机生成、处理和显示图形的学科。

通过本次实验,旨在深入理解计算机图形学的基本原理和算法,掌握图形的生成、变换、渲染等技术,并能够运用所学知识解决实际问题,提高对图形学的应用能力和编程实践能力。

二、实验环境本次实验使用的编程语言为 Python,使用的图形库为 Pygame。

开发环境为 PyCharm。

三、实验内容1、直线的生成算法DDA 算法(Digital Differential Analyzer)Bresenham 算法DDA 算法是通过计算直线的斜率来确定每个像素点的位置。

它的基本思想是根据直线的斜率和起始点的坐标,逐步计算出直线上的每个像素点的坐标。

Bresenham 算法则是一种基于误差的直线生成算法。

它通过比较误差值来决定下一个像素点的位置,从而减少了计算量,提高了效率。

在实验中,我们分别实现了这两种算法,并比较了它们的性能和效果。

2、圆的生成算法中点画圆算法中点画圆算法的核心思想是通过判断中点的位置来确定圆上的像素点。

通过不断迭代计算中点的位置,逐步生成整个圆。

在实现过程中,需要注意边界条件的处理和误差的计算。

3、图形的变换平移变换旋转变换缩放变换平移变换是将图形在平面上沿着指定的方向移动一定的距离。

旋转变换是围绕一个中心点将图形旋转一定的角度。

缩放变换则是改变图形的大小。

通过矩阵运算来实现这些变换,可以方便地对图形进行各种操作。

4、图形的填充种子填充算法扫描线填充算法种子填充算法是从指定的种子点开始,将相邻的具有相同颜色或属性的像素点填充为指定的颜色。

扫描线填充算法则是通过扫描图形的每一行,确定需要填充的区间,然后进行填充。

在实验中,我们对不同形状的图形进行了填充,并比较了两种算法的适用情况。

四、实验步骤1、直线生成算法的实现定义直线的起点和终点坐标。

根据所选的算法(DDA 或Bresenham)计算直线上的像素点坐标。

计算机图形学实验报告


实验结果与结论
• 在本次实验中,我们成功地实现了复杂场景的渲染,得到了具有较高真实感和视觉效果的图像。通过对比 实验前后的效果,我们发现光线追踪和着色器的运用对于提高渲染质量和效率具有重要作用。同时,我们 也发现场景图的构建和渲染脚本的编写对于实现复杂场景的渲染至关重要。此次实验不仅提高了我们对计 算机图形学原理的理解和实践能力,也为我们后续深入研究渲染引擎的实现提供了宝贵经验。
2. 通过属性设置和变换操作,实现了对图形的定 制和调整,加深了对图形属性的理解。
4. 实验的不足之处:由于时间限制,实验只涉及 了基本图形的绘制和变换,未涉及更复杂的图形 处理算法和技术,如光照、纹理映射等。需要在 后续实验中进一步学习和探索。
02
实验二:实现动画效果
实验目的
掌握动画的基本原 理和实现方法
04
实验四:渲染复杂场景
实验目的
掌握渲染复杂场景的基本流程和方法 理解光线追踪和着色器在渲染过程中的作用
熟悉渲染引擎的实现原理和技巧 提高解决实际问题的能力
实验步骤
• 准备场景文件 • 使用3D建模软件(如Blender)创建或导入场景模型,导出为常用的3D格式(如.obj或.fbx)。 • 导入场景文件 • 在渲染引擎(如Unity或Unreal Engine)中导入准备好的场景文件。 • 构建场景图 • 根据场景的层次结构和光照需求,构建场景图(Scene Graph)。 • 设置光照和材质属性 • 为场景中的物体设置光照和材质属性(如漫反射、镜面反射、透明度等)。 • 编写渲染脚本 • 使用编程语言(如C或JavaScript)编写渲染脚本,控制场景中物体的渲染顺序和逻辑。 • 运行渲染程序 • 运行渲染程序,观察渲染结果。根据效果调整光照、材质和渲染逻辑。 • 导出渲染图像 • 将渲染结果导出为图像文件(如JPEG或PNG),进行后续分析和展示。

计算机图形学实验报告

姓名:学号:目录实验一直线的DDA算法一、【实验目的】1.掌握DDA算法的基本原理。

2.掌握DDA直线扫描转换算法。

3.深入了解直线扫描转换的编程思想。

二、【实验内容】1.利用DDA的算法原理,编程实现对直线的扫描转换。

2.加强对DDA算法的理解和掌握。

三、【测试数据及其结果】四、【实验源代码】#include<stdlib.h>#include<math.h>#include<GL/glut.h>#include<stdio.h>GLsizei winWidth=500;GLsizei winHeight=500;void Initial(void){glClearColor(1.0f,1.0f,1.0f,1.0f); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0,200.0,0.0,150.0);}void DDALine(int x0,int y0,int x1,int y1) {glColor3f(1.0,0.0,0.0);int dx,dy,epsl,k;float x,y,xIncre,yIncre;dx=x1-x0; dy=y1-y0;x=x0; y=y0;if(abs(dx)>abs(dy)) epsl=abs(dx); else epsl=abs(dy);xIncre=(float)dx/(float)epsl;yIncre=(float)dy/(float)epsl;for(k=0;k<=epsl;k++){glPointSize(3);glBegin(GL_POINTS);glVertex2i(int(x+0.5),(int)(y+0.5));glEnd();x+=xIncre;y+=yIncre;}}void Display(void){glClear(GL_COLOR_BUFFER_BIT); DDALine(100,100,200,180); glFlush();}void winReshapeFcn(GLint newWidth, GLint newHeight){glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, GLdouble(newWidth), 0.0, GLdouble(newHeight));glClear(GL_COLOR_BUFFER_BIT);winWidth=newWidth;winHeight=newHeight;}int main(int argc,char*argv[]){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(400,300);glutInitWindowPosition(100,120);glutCreateWindow("line");Initial();glutDisplayFunc(Display);glutReshapeFunc(winReshapeFcn);glutMainLoop();return 0;}实验二Bresenham绘制直线和圆一、【实验目的】1.掌握Bresenham算法扫描转换圆和直线的基本原理。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

pLight->Light[29].SetGlobal(1000,160, 200);
for(int i= 0; i < LightNum; i++)
{
pLight->Light[i].L_Diffuse=CRGB(0.1,1.0,0.1); //光源的漫反射颜色
pLight->Light[i].L_Specular=CRGB(1.0,1.0,1.0);//光源镜面高光颜色
// CTestView drawing
void CTestView::OnDraw(CDC* pDC)
{
CTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
InitParameter();
}
pMaterial=new CMaterial;//一维材质动态数组
pMaterial->M_Diffuse=CRGB(0.0,0.1,0.0);//材质对漫反射光的反射率
pMaterial->M_Ambient=CRGB(0.0,0.0,0.0);//材质对环境光的反射率
pMaterial->M_Exp=50.0;//高光指数
ReadPoint();
ReadFace();
DoubleBuffer();
}
/////////////////////////////////////////////////////////////////////
// CTestView printing
BOOL CTestView::OnPreparePrinting(CPrintInfo* pInfo)
IMPLEMENT_DYNCREATE(CTestView,CView)
BEGIN_MESSAGE_MAP(CTestView,CView) //{{AFX_MSG_MAP(CTestView) ON_WM_KEYDOWN() ON_WM_MOUSEWHEEL() ON_COMMAND(ID_MENU_FrameHide,OnMENUFrameHide) ON_COMMAND(ID_MENU_Light, OnMENULight) ON_WM_TIMER() ON_UPDATE_COMMAND_UI(ID_PLAY,OnUpdatePlay) ON_COMMAND(ID_PLAY, OnPlay) ON_COMMAND(ID_MENU_DrawFrame,OnMENUDrawFrame)
软流水线示意图如下:
四:功能说明 (1)通过菜单控制显示未消隐水晶线框透视模型、消隐水晶线框
透视模型、多光源真实感水晶模型。 (2)通过菜单控制播放水晶旋转动画。 (3)使用上下键盘方向键旋转水晶,通过左右方向键盘移动水晶。 (4)使用鼠标滚轮放大或者缩小水晶。
五:成员分工
杨秀隆:负责水晶模型整体框架的构建。 魏陈强:负责模型的移动、放大缩小的实现以及完成报告的撰写。 唐民翰:负责水晶模型颜色、材质、背景的选择以及开题报告的 撰写。
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
ON_WM_ERASEBKGND() //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT,CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////// // CTestView construction/destruction CTestView::CTestView() { // TODO: add construction code here R=800,d=700,Phi=86,Theta=0,Play=FALSE,nChoice=3,move=0; LightNum = 30;//光源数量 pLight=new CLighting(LightNum); pLight->Light[ 0].SetGlobal(1000, 75,-170); pLight->Light[ 1].SetGlobal(1000, 75, 170); pLight->Light[ 2].SetGlobal(1000, 10,-100); pLight->Light[ 3].SetGlobal(1000, 10, 100); pLight->Light[ 4].SetGlobal(1000, 20,-110); pLight->Light[ 5].SetGlobal(1000, 20, 110); pLight->Light[ 6].SetGlobal(1000, 40,-120); pLight->Light[ 7].SetGlobal(1000, 40, 120); pLight->Light[ 8].SetGlobal(1000, 60,-130); pLight->Light[ 9].SetGlobal(1000, 60, 130); pLight->Light[10].SetGlobal(1000, 75,-200); pLight->Light[11].SetGlobal(1000, 75, 200); pLight->Light[12].SetGlobal(1000,110, 130); pLight->Light[13].SetGlobal(1000,110,-130); pLight->Light[14].SetGlobal(1000,110,- 80); pLight->Light[15].SetGlobal(1000,110, 80); pLight->Light[16].SetGlobal(1000,110,- 40); pLight->Light[17].SetGlobal(1000,110, 40); pLight->Light[18].SetGlobal(1000,110,- 20); pLight->Light[19].SetGlobal(1000,110, 20); pLight->Light[20].SetGlobal(1000,130,-200); pLight->Light[21].SetGlobal(1000,130, 200); pLight->Light[22].SetGlobal(1000,140,-230); pLight->Light[23].SetGlobal(1000,140, 230); pLight->Light[24].SetGlobal(1000,150,-200); pLight->Light[25].SetGlobal(1000,150, 200); pLight->Light[26].SetGlobal(1000,150,-300); pLight->Light[27].SetGlobal(1000,150, 300); pLight->Light[28].SetGlobal(1000,160,-200);
// CTestView diagnostics
计算机图形学项目报告
课程名称:计算机图形学 项目名称:水晶模型软流水线演示 项目成员:杨秀隆 魏陈强 唐民翰 指导老师:杨晨晖 完成日期:2011 年 12 月 5 日
一:概况 计算机图形学(Computer Graphics,简称 CG)是一种使用数学算
法将二维或三维图形转化为计算机显示器的栅格形式的科学。简单地 说,计算机图形学的主要研究内容就是研究如何在计算机中表示图 形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。 计算机图形学一个主要的目的就是要利用计算机产生令人赏心悦目 的真实感图形。为此,必须建立图形所描述的场景的几何表示,再用 某种光照模型,计算在假想的光源、纹理、材质属性下的光照明效果。 所以计算机图形学与另一门学科计算机辅助几何设计有着密切的关 系。事实上,图形学也把可以表示几何场景的曲线曲面造型技术和实 体造型技术作为其主要的研究内容。同时,真实感图形计算的结果是 以数字图像的方式提供的,计算机图形学也就和图像处理有着密切的 关系。
二:项目要求 利用图形学课上所学的相关算法和渲染技术,利用 MFC 绘制一个
3D 模型,模型的光源、颜色、材质可灵活选择,并且能够显示模型 的线框模型、未消隐线框模型、消隐线框模型以及光照模型,以此实 现模型的软流水线演示。
三:实验思路 参考《课程设计》中钻石模型的例子,应用本学期学到的图形学
方面的知识,构造出一个简单的3D 水晶模型,其中性质、材质、颜 色等属性可以自定义,模型包括线框模、未消隐线框模型、消隐线框 模型、真实感光照模型等。
}
void CTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////
相关文档
最新文档