计算机图形学项目报告
- 格式:pdf
- 大小:2.49 MB
- 文档页数:17
计算机图形学实验报告直线的生成程序设计:实验目的:掌握直线段的生成算法, 并用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一、实验目的本次计算机图形学实验旨在深入了解和掌握计算机图形学中的一些关键概念和技术,通过实际操作和编程实现,提高对图形生成、变换、渲染等方面的理解和应用能力。
二、实验环境本次实验使用的软件环境为_____,编程语言为_____,硬件环境为_____。
三、实验内容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班指导老师:***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)计算直线上的像素点坐标。
姓名:学号:目录实验一直线的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算法扫描转换圆和直线的基本原理。