计算机图形学实验报告及代码
- 格式:docx
- 大小:45.97 KB
- 文档页数:34
1、planet程序:#include <GL/glut.h>#include <stdlib.h>static int year = 0, day = 0;void init(void){glClearColor (0.0, 0.0, 0.0, 0.0);glShadeModel (GL_FLAT);}void display(void){glClear (GL_COLOR_BUFFER_BIT);glColor3f (1.0, 1.0, 1.0);glPushMatrix();glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);glutWireSphere(1.0, 20, 16); /* draw sun */glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);glTranslatef (2.0, 0.0, 0.0);glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);glutWireSphere(0.2, 10, 8); /* draw smaller planet */glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);glTranslatef (-4.0, 0.0, 0.0);glutWireSphere(0.2, 10, 8); /* draw smaller planet */ glPopMatrix();glutSwapBuffers();}void reshape (int w, int h){glViewport (0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode (GL_PROJECTION);glLoadIdentity ();gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);}void keyboard (unsigned char key, int x, int y){switch (key) {case 'd':day = (day + 10) % 360;glutPostRedisplay();break;case 'D':day = (day - 10) % 360;glutPostRedisplay();break;case 'y':year = (year + 5) % 360;glutPostRedisplay();break;case 'Y':year = (year - 5) % 360;glutPostRedisplay();break;case 27:exit(0);break;default:break;}}int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);glutInitWindowSize (500, 500);glutInitWindowPosition (100, 100);glutCreateWindow (argv[0]);init ();glutDisplayFunc(display);glutReshapeFunc(reshape);glutKeyboardFunc(keyboard);glutMainLoop();return 0;}2、robot程序:#include <GL/glut.h>#include <stdlib.h>static int shoulder = 0, elbow = 0, finger=0;void init(void){glClearColor (0.0, 0.0, 0.0, 0.0);glShadeModel (GL_FLAT);}void display(void){glClear (GL_COLOR_BUFFER_BIT);glPushMatrix();glTranslatef (-1.0, 0.0, 0.0); //胳膊转glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0);glTranslatef (1.0, 0.0, 0.0);glPushMatrix();glScalef (2.0, 0.4, 1.0);glutWireCube (1.0);glPopMatrix();glTranslatef (1.0, 0.0, 0.0); //轴心平移glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0);//手关节转glTranslatef (1.0, 0.0, 0.0);glPushMatrix();glScalef (2.0, 0.4, 1.0);glutWireCube (1.0);glPopMatrix();glTranslatef (0.7, 0.0, 0.0); //轴心平移glRotatef ((GLfloat) finger, 0.0, 0.0, 1.0);//手指转glTranslatef (0.7, 0.0, 0.0);glPushMatrix();glScalef (0.6, 0.1, 0.1);glutWireCube (1.0);glPopMatrix();glPopMatrix();glutSwapBuffers();}void reshape (int w, int h){glViewport (0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode (GL_PROJECTION);glLoadIdentity ();gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glTranslatef (0.0, 0.0, -5.0);}void keyboard (unsigned char key, int x, int y){switch (key) {case 's':shoulder = (shoulder + 5) % 360;glutPostRedisplay();break;case 'S':shoulder = (shoulder - 5) % 360;glutPostRedisplay();break;case 'e':elbow = (elbow + 5) % 360;glutPostRedisplay();break;case 'E':elbow = (elbow - 5) % 360;glutPostRedisplay();break;case 'f':finger = (finger + 5) % 45;glutPostRedisplay();break;case 'F':finger= (finger - 5) % 45;glutPostRedisplay();break;case 27:exit(0);break;default:break;}}int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);glutInitWindowSize (500, 500);glutInitWindowPosition (100, 100);glutCreateWindow (argv[0]);init ();glutDisplayFunc(display);glutReshapeFunc(reshape);glutKeyboardFunc(keyboard);glutMainLoop();return 0;}。
一、实验目的根据曲线和曲面的基础知识和常用曲线的数学基础,对其算法进行程序设计,验证算法的正确性,并通过程序结果加深对常用曲线数学模型的理解。
二、实验任务1.抛物线程序设计;2.Hermite 曲线程序设计;3.Bezier曲线的算法实现;4.B样条曲线的程序设计三、实验内容和实验步骤任务一:抛物线程序设计实现抛物线算法的C语言程序段如下:(工程名:parabola)Par(int xs,int ys,int xm,int ym,int xe,int ye) //已知起点、中点和终点三个控制点的坐标{double t,dt,ax,ay,bx,by,cx,cy;int n,i;ax=xe-2*xm+xs;ay=ye-2*ym+ys;bx=2.0*(xm-xs);by=2.0*(ym-ys);cx=xs; cy=ys;n=sqrt(ax*ax+ay*ay);n=sqrt(n*100.0);moveto(xs,ys);dt=1.0/n; t=0;for (i=0;i<=n; i++){lineto((int)(ax*t*t+bx*t+cx),(int)( ay*t*t+by*t+cy));t=t+dt;}lineto(xe,ye);}读者可以根据上述抛物线程序设计,写出抛物线参数样条曲线的程序。
任务二:Hermite 曲线程序设计P(t)=FB=TMB=[ t3 t2 t 1 ]程序设计时只考虑二维图形的显示,其代数形式为:x(t)=TMBx , Bx =[ P0x P1x R0x R1x]Ty(t)= TMBy , By =[ P0y P1y R0y R1y]T所以,只要给出Hermite曲线的起点坐标(P0x,P0y),终点坐标(P1x,P1y),以及起点处的切矢量(R0x,R0y)和终点处的切矢量(R1x,R1y),参数变量t在[0,1]的范围内分别取0.01,0.02,…,1,步长为0.01,取100个点,分别求出P(t)=[ x(t),y(t)],在计算机屏幕上显示出每个坐标点,即可绘出Hermite曲线。
计算机图形学实验报告直线的生成程序设计:实验目的:掌握直线段的生成算法, 并用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);}。
《计算机图形学》实验报告目录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核心代码本次实验的核心代码如下所示。
计算机图形学与三维建模实验报告计算机图形学实验报告openGL的基本使用1.项目代码:// 2321321.cpp : 定义控制台应用程序的入口点。
#include"stdafx.h"#include<iostream>#include<stdio.h>#include<gl/glut.h>#include<gl/glu.h>#include<gl/gl.h>using namespace std;//#include"vgl.h" opengl4.3 编程宝典第8版库函数//#include"loadshaders.h"GLfloat x=0.0,y=0.0,z=0.0;//用于平移的变量GLfloat i=1.0,j=1.0,k=1.0;//用于缩放的变量int d=1;//用于是否判断旋转的开关GLfloat angle=0.0f;//旋转角度的变量void myDisplay(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 创建透视效果视图glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(90.0f, 1.0f, 1.0f, 20.0f);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 定义4光源,从4个方向入射,第一个是白光,其他为红绿蓝{GLfloat sun_light_position[] = { -5.0f, 5.0f, 0.0f, 1.0f };GLfloat sun_light_position1[] = { 5.0f, 5.0f, 0.0f, 1.0f };GLfloat sun_light_position2[] = { -5.0f, -5.0f, 0.0f, 1.0f };GLfloat sun_light_position3[] = { 5.0f, -5.0f, 0.0f, 1.0f };GLfloat sun_light_ambient[] = { 0.0f, 0.0f, 0.0f,1.0f };GLfloat sun_light_diffuse[] = { 1.0f, 1.0f, 1.0f,1.0f };GLfloat sun_light_diffuse1[] = { 1.0f, 0.0f, 0.0f, 1.0f };GLfloat sun_light_diffuse2[] = { 0.0f, 1.0f, 0.0f, 1.0f };GLfloat sun_light_diffuse3[] = { 0.0f, 0.0f, 1.0f, 1.0f };GLfloat sun_light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };glLightfv(GL_LIGHT0, GL_POSITION,sun_light_position);glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse);glLightfv(GL_LIGHT0, GL_SPECULAR,sun_light_specular);glLightfv(GL_LIGHT1, GL_POSITION,sun_light_position1);glLightfv(GL_LIGHT1, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT1, GL_DIFFUSE, sun_light_diffuse1);glLightfv(GL_LIGHT1, GL_SPECULAR,sun_light_specular);glLightfv(GL_LIGHT2, GL_POSITION, sun_light_position2);glLightfv(GL_LIGHT2, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT2, GL_DIFFUSE, sun_light_diffuse2);glLightfv(GL_LIGHT2, GL_SPECULAR,sun_light_specular);glLightfv(GL_LIGHT3, GL_POSITION, sun_light_position3);glLightfv(GL_LIGHT3, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT3, GL_DIFFUSE, sun_light_diffuse3);glLightfv(GL_LIGHT3, GL_SPECULAR,sun_light_specular);glEnable(GL_LIGHT0);glEnable(GL_LIGHT1);glEnable(GL_LIGHT2);glEnable(GL_LIGHT3);glEnable(GL_LIGHTING);glEnable(GL_DEPTH_TEST);}//绘制坐标轴{glBegin(GL_LINE);//x轴红色glColor3f(1,0,0);glVertex3f(10,0,0);glVertex3f(-10,0,0);//y轴绿色glColor3f(0,1,0);glVertex3f(0,10,0);glVertex3f(0,-10,0);//z轴蓝色glColor3f(0,0,1);glVertex3f(0,0,10);glVertex3f(0,0,-10);glEnd();}// 定义球体的材质并绘制{GLfloat ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f };//环境颜色GLfloat diffuse[] = { 0.7f, 0.7f, 0.7f, 1.0f };//散射GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };//镜面反射GLfloat emission[] = { 0.0f, 0.0f, 0.0f, 0.5f };//发射光颜色GLfloat hininess = 50.0f; //反射指数glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, specular);glMaterialfv(GL_FRONT, GL_EMISSION, emission);glMaterialf(GL_FRONT, GL_SHININESS, shininess);glTranslatef(x,y,z);glScalef(i,j,k);if(d==1){glRotatef(angle,0.0f,0.0f,4.0f);glTranslatef(2.5f,2.5f,0.0f);}glutSolidSphere(2.0, 60.0, 60.0);}glutSwapBuffers();}void ChangeSize(GLsizei W,GLsizei H)//当视口改变时改变裁剪部分保证图形观察时不形变{GLfloat aspectRatio;if(H==0)H=1;glViewport(0,0,W,H);//视口设置glMatrixMode(GL_PROJECTION);//重置坐标系统glLoadIdentity();aspectRatio=(GLfloat)W/(GLfloat)H;if(aspectRatio<=1)//裁剪部分设置glOrtho(-2.5,2.5,-2.5/aspectRatio,2.5/aspectRatio,2.5,-2.5);elseglOrtho(-2.5*aspectRatio,2.5*aspectRatio,-2.5,2.5,2.5,-2.5);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void ProcessKeys(unsigned char ch,int a,int b){if(ch==119)//w{y+=0.1;glutPostRedisplay();}else if(ch==115)//s{y-=0.1;glutPostRedisplay();}else if(ch==97)//a{x-=0.1;glutPostRedisplay();}else if(ch==100)//d{x+=0.1;glutPostRedisplay();}else if(ch==120)//x{z-=0.1;}else if(ch==122)//z{z+=0.1;glutPostRedisplay();}else if(ch==43)//+{i+=0.1;j+=0.1;k+=0.1;glutPostRedisplay(); }else if(ch==45)//-{i-=0.1;j-=0.1;k-=0.1;}else if(ch==32)//空格键{if(d==0)d=1;else d=0;cout<<d<<endl;}//按空格开关旋转}void IdleFunc(){if(d==1){angle+=1.0f;if(angle==360.0f){angle=0.0f;}cout<<angle<<endl;myDisplay();}}int _tmain(int argc, char* argv[]){glutInit(&argc, (char**) argv);glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100,100);glutInitWindowSize(500,500);glutCreateWindow("Hello OpenGL");glutDisplayFunc(myDisplay);glutReshapeFunc(ChangeSize);glutIdleFunc(IdleFunc);glutKeyboardFunc(ProcessKeys);glutReshapeFunc(ChangeSize);glutMainLoop();return 0;}二.系统总体布局系统流程图:本系统是常规的openGL系统,初始化后先设置视角、投影、光照、材质等因素,绘制基本的图形,再通过函数判断键盘输入进行重复绘制,完成基本的平移,缩放,旋转等操作三.系统设计思路在系统设计最初,本来想直接使用默认视角后直接设置光照和平移旋转等功能,但是发现在默认视角下对物体,特别是正方体的三维效果无法很好地观察,因此采用侧视视角然后在对材质的定义上,由于立方体设置比较麻烦,最后决定画一个球体,然后在平移旋转缩放等功能的演示上,直接演示过于简单,就是一个函数的执行,因此决定采取利用键盘控制移动和缩放及旋转的方式。
计算机图形学实验报告学号:********姓名:班级:计算机 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. 了解如何利⽤OpenGL库绘制图形2. 理解glut程序框架3. 理解窗⼝到视区的变换4. 理解OpenGL实现动画的原理⼆. 实验内容1. 实现中点Bresenham算法画直线2. 实现改进Bresenham算法画直线3. 实现圆的绘制三. 实验结果1.DDA算法画直线2. 中点Bresenham算法画直线3. 改进Bresenham算法画直线4. Bresenham算法画圆四. 源程序#include#include#include "stdio.h"int m_PointNumber = 0; //动画时绘制点的数⽬int m_DrawMode = 4; //绘制模式 1 DDA算法画直线// 2 中点Bresenham算法画直线// 5 四分法绘制椭圆//绘制坐标线void DrawCordinateLine(void){int i = 0 ;//坐标线为⿊⾊glColor3f(0.0f, 0.0f ,0.0f);glBegin(GL_LINES);for (i=10;i<=250;i=i+10){glVertex2f((float)(i), 0.0f);glVertex2f((float)(i), 250.0f);glVertex2f(0.0f, (float)(i));glVertex2f(250.0f, (float)(i));}glEnd();}//绘制⼀个点,这⾥⽤⼀个正⽅形表⽰⼀个点。
void putpixel(GLsizei x, GLsizei y){glRectf(10*x,10*y,10*x+10,10*y+10);}void DDACreateLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num) {//设置颜⾊glColor3f(1.0f,0.0f,0.0f);//对画线动画进⾏控制if(num == 1)printf("DDA画线算法:各点坐标\n");else if(num==0)return;//画线算法的实现GLsizei dx,dy,epsl,k;GLfloat x,y,xIncre,yIncre;x = x0;y = y0;if(abs(dx) > abs(dy)) epsl = abs(dx);else epsl = abs(dy);xIncre = (float)dx / epsl ;yIncre = (float)dy / epsl ;for(k = 0; k<=epsl; k++){putpixel((int)(x+0.5), (int)(y+0.5));if (k>=num-1) {printf("x=%f,y=%f,取整后x=%d,y=%d\n", x, y, (int)(x+0.5),(int)(y+0.5));break;}x += xIncre;y += yIncre;if(x >= 25 || y >= 25) break;}}void BresenhamLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num) {glColor3f(1.0f,0.0f,0.0f);if(num == 1)printf("中点Bresenham算法画直线:各点坐标及判别式的值\n");else if(num==0)return;//画线算法的实现GLsizei dx,dy,d,UpIncre,DownIncre,x,y,xend=0;if(x0>x1){x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;}x=x0;y=y0;dx=x1-x0;dy=y1-y0;d=dx-2*dy;putpixel(x,y);if (x>=num-1) {break;}x++;if(d<0){y++;d+=UpIncre;}else d+=DownIncre;if(x >= 50 || y >= 50) break;}}void Bresenham2Line(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num) { glColor3f(1.0f,0.0f,0.0f);if(num == 1)printf("改进的Bresenham算法画直线:各点坐标及判别式的值\n");else if(num==0)return;//画线算法的实现GLsizei x,y,dx,dy,e;dx=x1-x0;dy=y1-y0;e=-dx;x=x0;y=y0;while (x<=x1){putpixel(x,y);if (x>=num-1) {break;}x++;e=e+2*dy;if(e>0){y++;if(x >= 50 || y >= 50) break;}}void BresenhamCircle(GLsizei x, GLsizei y, GLsizei r, GLsizei num) {glColor3f(1.0f,0.0f,0.0f);if(num == 1)printf("Bresenham算法画圆:各点坐标及判别式的值\n");x=0,y=r;GLsizei d=1-r;while (xputpixel(x,y);if (x>=num) {break;}putpixel(y,x);if (x>=num) {break;}putpixel(-y,x);if (x>=num) {break;}putpixel(-x,y);if (x>=num) {break;}putpixel(-x,-y);if (x>=num) {break;}putpixel(-y,-x);if (x>=num) {putpixel(y,-x);if (x>=num) {break;}putpixel(x,-y);if(d<0)d+=2*x+3;else{d+=2*(x-y)+5;y--;}x++;}}//初始化窗⼝void Initial(void){// 设置窗⼝颜⾊为蓝⾊glClearColor(1.0f, 1.0f, 1.0f, 1.0f);}// 窗⼝⼤⼩改变时调⽤的登记函数void ChangeSize(GLsizei w, GLsizei h){if(h == 0) h = 1;// 设置视区尺⼨glViewport(0, 0, w, h);// 重置坐标系统glMatrixMode(GL_PROJECTION); glLoadIdentity();// 建⽴修剪空间的范围if (w <= h)glOrtho (0.0f, 250.0f, 0.0f, 250.0f*h/w, 1.0, -1.0); elseglOrtho (0.0f, 250.0f*w/h, 0.0f, 250.0f, 1.0, -1.0); }void ReDraw(void){//⽤当前背景⾊填充窗⼝glClear(GL_COLOR_BUFFER_BIT);//画出坐标线DrawCordinateLine();switch(m_DrawMode){case 1:DDACreateLine(0,0,20,15,m_PointNumber); break;case 2:BresenhamLine(0,0,20,15,m_PointNumber); break;case 3:Bresenham2Line(1,1,8,6,m_PointNumber); break;case 4:BresenhamCircle(5,5,18,m_PointNumber); break;default:break;}glFlush();}//设置时间回调函数void TimerFunc(int value){if(m_PointNumber == 0)value = 1;m_PointNumber = value; glutPostRedisplay();glutTimerFunc(500, TimerFunc, value+1); }void Keyboard(unsigned char key, int x, int y){if (key == '1') m_DrawMode = 1;if (key == '2') m_DrawMode = 2;if (key == '3') m_DrawMode = 3;if (key == '4') m_DrawMode = 4;m_PointNumber = 0;glutPostRedisplay();}//void main(void)int main(int argc, char* argv[]){glutInit(&argc, argv);//初始化GLUT库OpenGL窗⼝的显⽰模式glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(800,600); glutInitWindowPosition(100,100); glutCreateWindow("基本图元绘制程序"); glutDisplayFunc(ReDraw);glutReshapeFunc(ChangeSize); glutKeyboardFunc(Keyboard);//键盘响应回调函数glutTimerFunc(500, TimerFunc, 1);// 窗⼝初始化Initial();glutMainLoop(); //启动主GLUT事件处理循环return 0;}实验⼆:⽇地⽉模型⼀. 实验⽬的1. 理解OpenGL中的变换过程2. 理解透视投影与平⾏投影的不同3. 了解深度测试⼆. 实验内容1. 通过变换调整观察的位置与⽅向三. 实验结果太阳、地球和⽉亮的运动模型图1.图2.图3.四. 源程序#include#include#include#includevoid Initial(){glEnable(GL_DEPTH_TEST); // 启⽤深度测试glFrontFace(GL_CCW); // 指定逆时针绕法表⽰多边形正⾯glClearColor(1.0f, 1.0f, 1.0f, 1.0f ); //背景为⽩⾊}void ChangeSize(int w, int h){if(h == 0) h = 1;// 设置视区尺⼨glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();// 设置修剪空间GLfloat fAspect;fAspect = (float)w/(float)h;gluPerspective(45.0, fAspect, 1.0, 500.0);/*if (w <= h)glOrtho (-nRange, nRange, nRange*h/w, -nRange*h/w, -nRange*2.0f, nRange*2.0f);elseglOrtho (-nRange*w/h, nRange*w/h, nRange, -nRange, -nRange*2.0f, nRange*2.0f); */glLoadIdentity();}void RenderScene(void){// 绕原⼦核旋转的⾓度static float fElect1 = 0.0f;static float f2=0.0f;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 重置模型视图矩阵glMatrixMode(GL_MODELVIEW);glLoadIdentity();//将图形沿z轴负向移动glTranslatef(0.0f, 0.0f, -250.0f);// 绘制红⾊的原⼦核glColor3f(1.0f, 0.0f, 0.0f);glutSolidSphere(50.0f, 15, 15);// 当前绘制颜⾊变为黄⾊glColor3f(0.0f, 0.0f, 0.0f);//绘制第⼀个电⼦//保存当前的模型视图矩阵glRotatef(fElect1, 0.0f, 1.0f, 0.0f);//绕y轴旋转⼀定的⾓度glTranslatef(80.0f, 0.0f, 0.0f);//平移⼀段距离glutSolidSphere(12.0f, 15, 15);//画出电⼦// 恢复矩阵// 第⼆个电⼦glPushMatrix();glRotatef(45.0f, 0.0f, 0.0f, 1.0f);glRotatef(f2, 0.0f, 1.0f, 0.0f);glTranslatef(-20.0f, 0.0f, 0.0f);glutSolidSphere(6.0f, 15, 15);glPopMatrix();/* // 第三个电⼦glPushMatrix();glRotatef(-45.0f,0.0f, 0.0f, 1.0f);glTranslatef(0.0f, 0.0f, 60.0f);glutSolidSphere(6.0f, 15, 15);glPopMatrix();*/// 增加旋转步长fElect1 += 10.0f;f2=fElect1*6;if(fElect1 > 360.0f){fElect1 = 10.0f;}glutSwapBuffers();}void TimerFunc(int value){glutPostRedisplay();glutTimerFunc(100, TimerFunc, 1);}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("⽇地⽉模型");glutReshapeFunc(ChangeSize);glutDisplayFunc(RenderScene);glutTimerFunc(500, TimerFunc, 1);Initial();glutMainLoop();return 0;}。
实验1 直线的绘制实验目的1、通过实验,进一步理解和掌握DDA和Bresenham算法;2、掌握以上算法生成直线段的基本过程;3、通过编程,会在TC环境下完成用DDA或中点算法实现直线段的绘制。
实验环境计算机、Turbo C或其他C语言程序设计环境实验学时2学时,必做实验。
实验内容用DDA算法或Besenham算法实现斜率k在0和1之间的直线段的绘制。
实验步骤1、算法、原理清晰,有详细的设计步骤;2、依据算法、步骤或程序流程图,用C语言编写源程序;3、编辑源程序并进行调试;4、进行运行测试,并结合情况进行调整;5、对运行结果进行保存与分析;6、把源程序以文件的形式提交;7、按格式书写实验报告。
实验代码:DDA:# include <graphics.h># include <math.h>void DDALine(int x0,int y0,int x1,int y1,int color){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);elseepsl=abs(dy);xIncre=(float)dx/(float)epsl;yIncre=(float)dy/(float)epsl;for(k=0;k<=epsl;k++){putpixel((int)(x+0.5),(int)(y+0.5),4);x+=xIncre;y+=yIncre;}}main(){int gdriver ,gmode ;gdriver = DETECT;initgraph(&gdriver , &gmode ,"C:\\TC20\\BGI");DDALine(0,0,35,26,4);getch ( );closegraph ( );}Bresenham:#include<graphics.h>#include<math.h>void BresenhamLine(int x0,int y0,int x1,int y1,int color) {int x,y,dx,dy,e;dx=x1-x0;dy=y1-y0;e=-dx;x=x0;y=y0;while(x<=x1){putpixel(x,y,color);x++;e=e+2*dy;if(e>0){y++;e=e-2*dx;}}}main(){int gdriver ,gmode ;gdriver = DETECT;initgraph(&gdriver , &gmode ,"c:\\TC20\\BGI");BresenhamLine(0, 0 , 120, 200,5 );getch ( );closegraph ( );}实验2 圆和椭圆的绘制实验目的1、通过实验,进一步理解和掌握中点算法;2、掌握以上算法生成椭圆或圆的基本过程;3、通过编程,会在TC环境下完成用中点算法实现椭圆或圆的绘制。
计算机图形学实验报告及代码第 1 章概述一、教学目标通过本章的学习,使学生能够了解计算机图形学的基本概念、研究内容;当前的发展概况;本门课程的特点和应用。
二、教学要求1.了解计算机图形学的概念和研究内容;2.了解本门课程的发展概况。
三、教学内容提要1. 计算机图形学的研究内容2. 计算机图形学发展概况3. 计算机图形学特点和应用4. 计算机图形学当前研究的课题5. 计算机图形生成和输出的流水线四、教学重点、难点及解决方法本章将主要围绕计算机图形学的基本概念进行介绍,介绍研究内容;当前的发展概况;本门课程的特点和应用等等。
五、课时安排2学时六、教学设备多媒体七、检测教学目标实现程度的具体措施和要求通过课堂提问的方式来检测学生对基本概念的掌握程度。
八、教学内容1.1 计算机图形学的研究内容计算机图形学(Computer Graphics): 研究通过计算机将数据转换为图形,并在专用显示设备上显示的原理、方法和技术的学科。
计算机图形表现形式(1).线条式(线框架图)用线段来表现图形,容易反映客观实体的内部结构,如各类工程技术中结构图的表示,机械设计中零件结构图及电路设计中的电路原理图等。
具有面模型、色彩、浓淡和明暗层次效应,适合表现客观实体的外形或外貌,如汽车、飞机、轮船等的外形设计以及各种艺术品造型设计等。
(2).真实感面模型图形跑车靓照计算机图形分类(空间)(1).二维图形(2D):在平面坐标系中定义的图形(2).三维图形(3D):在三维坐标系中定义的图形计算机图形产生方法(1).矢量法(短折线法)任何形状的曲线都用许多首尾相连的短直线(矢量)逼近。
(2).描点法(像素点串接法)每一曲线都是由一定大小的像素点组成计算机绘图方式:(1)交互式绘图允许操作者以某种方式(对话方式或命令方式)来控制和操纵图形生成过程,使得图形可以边生成、边显示、边修改,直至符合要求为止。
如AUTOCAD等(2)被动式绘图图形在生成过程中,操作者无法对图形进行操作和控制。
如C语言绘图图形的操作与处理方法(Picture Manipulation)如图形的开窗、裁剪、平移、旋转、放大、缩小、投影等各种几何变换操作的方法及其软件或硬件实现技术。
图形信息的存储,检索与交换技术:如图形信息的各种表示方法、组织形式、存取技术、图形数据库的管理、图形信息通信等。
人机交互及用户接口技术:如新型定位设备、选择设备的研究;各种交互技术,如构造技术、命令技术、选择技术、响应技术等的研究,以及用户模型、命令语言、反馈方法、窗口系统等用户接口技术的研究。
1.2 计算机图形学发展概况1962年美国麻省理工学院林肯实验室的Ivan E·Suthland,首先提出了“计算机图形学”(Computer Graphics)这一术语,引入了分层存储符号的数据结构,开发出了交互技术;可用键盘和光笔实现定位、选项和绘图。
奠定了计算机图形学基础。
60年代中期美国、英国、法国的一些汽车、飞机制造业大公司对计算机图形学开展大规模研究。
60年代后期出现了存储管式显示器,可以进行简单交互。
1.3 计算机图形学特点和应用特点:1.计算机产生的图形有规律、光滑。
它是按数学方法产生的,规矩整齐,有着像数学一样的严格性。
2.计算机产生的图形纯净美观、无噪声干扰。
3.通过计算机产生的图形不仅能描绘客观世界的各种对象,也能描绘纯粹是想像的主观世界中的各种对象。
4.交互式计算机图形显示可由用户控制,产生的图形可修改性强,且速度快、差错少。
应用领域:1.计算机辅助设计(CAD)和计算机辅助制造(CAM)计算机图形学被用来进行土建工程、机械结构和产品的设计,包括设计飞机、汽车、船舶的外形和发电厂、化工厂等的布局,也能够对电子线路或电子器件进行设计。
2.事务管理中交互式绘图绘制事务管理中的各种图形,如统计数据的二维及三维图形、直方图、线条图、表示百分比的扇形图等等,还可绘制工作进程图,库存和生产进程图以及大量的其他图形。
所有这些都以简明的形式呈现出数据的模型和趋势以增加对复杂现象的理解并促进决策的制定。
3.地理信息系统(GIS)地理信息系统是建立在地理图形基础上的信息管理系统,是图形技术、数据库技术以及管理信息的结合。
4.办公自动化和电子出版技术图形显示技术在办公自动化和事务处理中的使用,有助于数据及其相互关系的有效表达,因而有利于人们进行正确的决策。
利用交互式图形显示技术的支持可以进行资料、文稿、书刊、手册的编写、修改。
制图、制表、分页、排版。
5.计算机辅助教学(CAI)计算机辅助教学系统利用图形显示设备或电视终端,可以有声有色生动地演示物理、化学、生物、外语等教学内容,让学生(用户)使用人机交互手段,进行学习和研究,绘图或仿真操作,使整个教学过程直观形象,有利于加深理解所学知识。
6.过程控制在过程控制中,常常将计算机与现实世界中的其他设备连成一个系统。
计算机图形显示设备常用来显示系统中关键部位的状态,如炼油厂、发电厂的状态显示器可显示出由传感器送来的压力、温度、电压、电流等数据,从而使操作人员可对异常情况作出反应。
1.4 计算机图形学当前研究的课题1.造型技术研究的是如何在计算机中构造出二维、三维物件模型的基本方法和手段。
2.三维信息重建技术研究一些算法,使得计算机图形系统能自动地将三视图转换成相应的立体图。
3.图形数据库研究如何以基本的图形为数据项而建立起一个能快速查找各个图形的图形库。
4.动态绘图在交互式绘图中,不仅可以在屏幕上对图形进行修改、删除、编辑等,还可以进行动态分析。
5.CG、CAD、CAM三者一体化计算机图形学(CG)、计算机辅助设计(CAD)和计算机辅助制造(CAM)有机结合在一起,形成所谓一体化软件。
6.应用软件开发环境的通用化和标准化用户界面管理系统UIMS、窗口管理系统、网络文件格式等,并使之通用化和标准化。
7.虚拟现实环境的生成(Virtual Reality简称VR)利用计算机生成一种模拟环境(如飞机驾驶舱、操作现场等),通过多种传感、设备使用户“投入”到该环境中,实现用户与该环境直接进行自然交互的技术。
8.科学计算可视化通过对空间数据场构造中间几何图素或用图形绘制技术在屏幕上产生二维图像。
1.5 计算机图形学生成和输出的流水线再谈矢量法和描点法矢量法-向量图形-简单图形-计算机绘图命令-向量图描点法-点阵图形-复杂图形-文件存储大小-位图比较:几条自由曲线构成的图形和一幅有炫彩动物的卡通图形(1) 点阵图形点的信息;(2) 向量图形的尺寸变化;九、作业课后习题十、本章小结在本章中,对计算机图形学的基本概念和研究内容进行了概述,对发展概况和应用领域进行了说明。
第2章计算机图形系统一、教学目标通过对本章的学习,要求熟悉计算机图形系统的组成/各种图形显示器、图形输入/输出设备。
二、教学要求1、了解计算机图形系统的组成;2、了解计算机图形输入/输出设备的种类。
三、教学内容提要1.计算机图形系统的组成2.计算机图形显示器3.计算机图形输入设备计算机图形输出设备4.图形核心系统(GKS)简介5. 通用图形软件简介四、教学重点、难点及解决方法重点是熟悉计算机图形系统的组成/各种图形显示器、图形输入/输出设备。
五、课时安排4学时六、教学设备课堂教学七、检测教学目标实现程度的具体措施和要求通过课堂提问的方式来检测学生对基本概念的掌握程度。
八、教学内容2.1 计算机图形系统的组成一. 图形系统的结构由硬件和软件两部分组成。
二.图形系统的基本功能及其硬件性能要求计算机图形系统至少应具有以下五个方面基本功能:1.计算功能(1)形体设计和分析方法的程序库,描述形体的图形数据库。
(2)坐标的平移、旋转、投影、透视等几何变换程序库的数据库。
(3)曲线、曲面生成和图形相互关系的检测库。
2.存储功能在计算机内存储器和外存储器中,应能存放各种形体的几何数据及形体之间相互关系,可实现对有关数据的实时检索以及保存对图形的删除、增加、修改等信息。
3.输入功能由图形输入设备将所设计的图形形体的几何参数(例如大小、位置等)和各种绘图命令输入到图形系统中。
4.输出功能图形系统应有文字、图形、图像信息输出功能。
在显示屏幕上显示设计过程当前的状态以及经过图形编辑后的结果。
同时还能通过绘图仪、打印机等设备实现硬拷贝输出,以便长期保存。
5.对话功能可通过显示器或其他人-机交互设备直接进行人-机通信,对计算结果和图形,利用定位、拾取等手段进行修改,同时对设计者或操作员执行的错误给予必要的提示和帮助。
为了实现以上功能,对图形系统的硬件性能要求是:1.处理速度图形系统的处理速度既与图形系统硬件有关,也与图形软件的图形处理算法有关。
2.存储容量存储容量包括三部分:内存储容量、显存、外部存储容量和显示缓冲区容量。
3. 处理精度处理精度主要是指图形采集输入质量和显示输出质量:这里主要指图形分辨率、图形色彩的显示等。
而且很大一部分与所采用的图形处理软件有关。
三.图形系统分类及硬件工作平台要求1.计算机图形系统的分类根据其硬件配置和信息传递方式分为:(1) 脱机绘图系统将输入图形数据在主机内进行处理将图形处理后的图形数据送入中间介质,用磁盘或磁带控制绘图输出机输出图形脱机绘图系统是将图形数据和图形输出分别进行处理,避免计算机处于等待状态,加快计算机的工作效率。
(2) 联机绘图系统将输入图形数据在主机内进行处理计算机将图形处理信息直接送给绘图机输出图形,不需要中间介质(磁盘或磁带)传递绘图信息,处理时间缩短了。
但由于绘图机是机械速度,这样造成了计算机对绘图机等待,降低了计算机工作效率。
(3) 交互式绘图系统绘图系统将处理结果输出到图形终端(图形显示器)或图形工作站。
用户对所显示图形还可用定位、拾取和描绘等设备进行编辑和标注等。
2.计算机图形系统的硬件工作平台目前,计算机图形系统的硬件平台有如下几种:(1).微型计算机(简称微机)随着微型计算机性能进一步提高,用微型计算机实现三维形体的设计及显示能力在不断提高。
(2).工作站实际上是一类超级微型计算机,该系统主要用于工程设计,为研究、开发提供一整套软硬件工作环境支持。
工作站是具有高速的科学计算、丰富的图形处理、灵活的窗口及网络管理功能的交互式计算机系统。
美国的SUN、SGI、HP、DEC、IBM等公司均生产此类产品。
(3).中、小型计算机一般在特定的部门、单位和应用领域中采用此类环境。
它是大型信息系统建立的重要环境,这种环境中信息和数据的处理量是很大的,要求机器有极高的处理速度和极大的存储容量。
(4).大型机以大型计算机为基础,具有容量庞大的存储器和极强的计算功能,大量的显示终端及高精度、大幅面的硬拷贝设备。
还往往拥有自行开发的、功能齐全的应用软件系统。