logo资料库

简单的图形函数库的设计与实现.docx

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
简单图形函数库设计与实现 一、要求: 设计和实现一个图形函数库,具有绘制直线段、任意圆弧、椭圆弧、多边形 区域的阴影填充和颜色填充等功能。(仅调用画点函数) Windows API: setpixel(hdc,x,y,color) 二、设计与实现: 1. 在Visual C++ 6.0环境下设计与实现的。在Visusl C++ 6.0中创建一个 可以显示“Hello”的Win32的应用程序(Win32 Application);在 Project/Settings对话框中的Link选项卡中的Object/library modules 一栏中加入opengl32.lib, glu32.lib和glut32.lib。 步骤如下: File——〉new——〉Projects——〉Win32 Application,在Projects name 一栏输入“ zj ”——〉选择A typical “Hello world” Application; 这样就得到了一个带窗口的应用程序框架。 2. 在建成的项目下,加入两个源文件draw.cpp和show.cpp。 draw.cpp文件用于书写简单的图形函数库,也即生成各种简单图形及颜 色填充的函数在此文件中。 show.cpp文件用于调用所设计的图形函数库中的各个函数,在窗口中输 出,以便观察所设计的函数是否正确。 3. 在LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, PARAM lParam) 中调用void show(HDC hdc)(此函数在show.cpp 中 L 定义)。如图: 4. 在draw.cpp中加入下列函数: void line(HDC hdc,int x1,int y1,int x2,int y2); 画直线段函数,运用的是 Bresenham 算法。参数为直线段的两个端点坐 - 1 -
标(x1,y1),(x2,y2)。 void circle(HDC hdc,int r,int x0,int y0); 画圆函数,运用的是 “正负法” 算法,设计时采用的是把整个圆等分 成了4个部分,逐一画出,这样的画法使得画出的圆不是很圆滑,一个好 的方法是等分成4部分后,利用对称性画圆,即画第一象限的点时把对应 的第二、三、四象限的点通过对称变换一并画出。 void ellipse(HDC hdc,int x0,int y0,int a,int b); 画椭圆函数,运用的是 中点画椭圆算法 ,此算法是从相关的图形学教 材中找到的,本人觉得是个不错的算法。 void Flood_Fill_4(HDC hdc, int x,int y, COLORREF old_color,COLORREF new_color); 区域颜色填充函数, 利用的是教材中的 Flood 算法。此算法有个很大 的缺点就是对图形进行填充时,经常出现堆栈溢出的情况,所以所填充 的图形不能太大,它的优点在很简单,只需明白递归的原理就行了。 5. 在show.cpp中加入函数void show(HDC hdc),此函数主要是进行draw.cpp 中的函数的调用。调用情况如下: 调用void line(HDC hdc,int x1,int y1,int x2,int y2);画直线段 调用void circle(HDC hdc,int r,int x0,int y0); 画圆 调用void ellipse(HDC hdc,int x0,int y0,int a,int b);画椭圆 调用void Flood_Fill_4(HDC hdc, int x,int y, COLORREF old_color,COLORREF new_color);填充区域 附: 只提供draw.cpp与show.cpp中的源码(其它的是VC 6.0自动生成的框架)。 源程序: draw.cpp如下: #include "stdafx.h" #include "resource.h" #include "math.h" #define Pi 3.14159265 void line(HDC hdc,int x1,int y1,int x2,int y2); void circle(HDC hdc,int r,int x0,int y0); void ellipse(HDC hdc,int x0,int y0,int a,int b); void wholeellipse(HDC hdc,int x0,int y0,int x,int y); void Flood_Fill_4(HDC hdc, int x,int y, COLORREF old_color,COLORREF new_color); //画直线段 void line(HDC hdc,int x1,int y1,int x2,int y2) - 2 -
{ int x,y,deltax,deltay,e; //////////////////////////////////////////// if(x2>=x1){ if(y2>=y1){ deltax=x2-x1; deltay=y2-y1; e=-deltax; x=x1; y=y1; for(int i=0;i<=deltax;i++){ SetPixel(hdc,x,y,RGB(0,0,0)); if(e>=0){ y=y+1; e=e-2*deltax; } else{ x=x+1; e=e+2*deltay; } } } else{ deltax=x2-x1; y2=2*y1-y2; deltay=y2-y1; e=-deltax; x=x1; y=y1; for(int i=0;i<=deltax;i++){ SetPixel(hdc,x,2*y1-y,RGB(0,0,0)); if(e>=0){ y=y+1; e=e-2*deltax; } else{ x=x+1; e=e+2*deltay; } } } } - 3 -
else{ if(y2>=y1){ x2=2*x1-x2; deltax=x2-x1; deltay=y2-y1; e=-deltax; x=x1; y=y1; for(int i=0;i<=deltax;i++){ SetPixel(hdc,2*x1-x,y,RGB(0,0,0)); if(e>=0){ y=y+1; e=e-2*deltax; } else{ x=x+1; e=e+2*deltay; } } } else{ int temp; temp=x1; x1=x2; x2=temp; temp=y1; y1=y2; y2=temp; deltax=x2-x1; deltay=y2-y1; e=-deltax; x=x1; y=y1; for(int i=0;i<=deltax;i++){ SetPixel(hdc,x,y,RGB(0,0,0)); if(e>=0){ y=y+1; e=e-2*deltax; } else{ x=x+1; e=e+2*deltay; - 4 -
} } } } } //画圆 void circle(HDC hdc,int r,int x0,int y0) { int x,y,f; x=x0; y=y0+r; f=0; while(y >= y0){ //右下 SetPixel(hdc,x,y,RGB(0,0,0)); if(f>0){ f=f-2*(y-y0)+1; y=y-1; } else{ f=f+2*(x-x0)+1; x=x+1; } } x=x0-r; y=y0; f=0; while(x<=x0){ //左下 SetPixel(hdc,x,y,RGB(0,0,0)); if(f>0){ f=f+2*(x-x0)+1; x=x+1; } else{ f=f+2*(y-y0)+1; y=y+1; } } x=x0; y=y0-r; f=0; while(y<=y0){ //左上 SetPixel(hdc,x,y,RGB(0,0,0)); - 5 -
if(f>0){ f=f+2*(y-y0)+1; y=y+1; } else{ f=f-2*(x-x0)+1; x=x-1; } } x=x0+r; y=y0; f=0; while(x>=x0){ //右上 SetPixel(hdc,x,y,RGB(0,0,0)); if(f>0){ f=f-2*(x-x0)+1; x=x-1; } else{ f=f-2*(y-y0)+1; y=y-1; } } } //中点画椭圆算法 void ellipse(HDC hdc,int x0,int y0,int a,int b) { int a1=a*a, b1=b*b; int a2=2*a1, b2=2*b1; int x=0, y=b; int d; int dx=0, dy=a2*y; d = (int) (b1 + a1 * (-b + 0.25) + 0.5); wholeellipse(hdc,x0,y0,x,y); while(dx
dy -= a2; d += b1 + dx - dy; y--; } wholeellipse(hdc,x0,y0,x,y); } d =(int) (b1*(x+0.5)*(x+0.5)+a1*(y-1)*(y-1)-a1*b1-0.5); while(y>0) { y--; dy -= a2; if(d>0) d += a1-dy; else{ x++; dx += b2; d += a1-dy+dx; } wholeellipse(hdc,x0,y0,x,y); } } void wholeellipse(HDC hdc,int x0,int y0,int x,int y) { SetPixelV(hdc,x0+x,y0+y, RGB(0,0,0)); SetPixelV(hdc,x0-x,y0+y, RGB(0,0,0)); SetPixelV(hdc,x0+x,y0-y, RGB(0,0,0)); SetPixelV(hdc,x0-x,y0-y, RGB(0,0,0)); } //区域颜色填充,Flood算法 void Flood_Fill_4(HDC hdc, int x,int y, COLORREF old_color,COLORREF new_color) { if( GetPixel(hdc,x,y)==old_color){ SetPixel(hdc,x,y,new_color); Flood_Fill_4(hdc,x,y+1,old_color,new_color); Flood_Fill_4(hdc,x,y-1,old_color,new_color); Flood_Fill_4(hdc,x-1,y,old_color,new_color); Flood_Fill_4(hdc,x+1,y,old_color,new_color); } } show.cpp如下: - 7 -
#include "stdafx.h" #include "resource.h" void line(HDC hdc,int x1,int y1,int x2,int y2); void circle(HDC hdc,int r,int x0,int y0); void ellipse(HDC hdc,int x0,int y0,int a,int b); void Flood_Fill_4(HDC hdc, int x,int y, COLORREF old_color,COLORREF new_color); void show(HDC hdc) { //////////////////////////////////////////////////////////////// line(hdc,100,200,250,200); line(hdc,100,200,350,500); line(hdc,250,200,80,800); Flood_Fill_4(hdc,150,250,RGB(255,255,255),RGB(195,195,195));//区域填充 //////////////////////////////////////////////////////////////// line(hdc,300,75,430,345); line(hdc,450,150,650,0); circle(hdc,20,345,220); circle(hdc,19,430,215); ellipse(hdc,400,220,85,55); //画直线段1 //画直线段2 //画圆1 //画圆2 //画一个椭圆 Flood_Fill_4(hdc,345,220,RGB(255,255,255),RGB(195,195,195));//区域填充 Flood_Fill_4(hdc,430,215,RGB(255,255,255),RGB(215,215,220));//区域填充 Flood_Fill_4(hdc,400,220,RGB(255,255,255),RGB(100,220,175));//区域填充 } - 8 -
分享到:
收藏