实验三区域填充扫描线算法.docx
《实验三区域填充扫描线算法.docx》由会员分享,可在线阅读,更多相关《实验三区域填充扫描线算法.docx(14页珍藏版)》请在冰豆网上搜索。
实验三区域填充扫描线算法
计算机图形学实验报告
班级:
计科14-3班学号:
1406010325姓名:
张磊日期:
2017.4.11成绩:
__________
1、实验题目及目的
1.1实验题目
实验三区域填充扫描线算法
1.2实验目的
掌握区域填充扫描线算法
2、实验内容及实验步骤
实验内容:
要求:
(1)画基本图形
(2)采用扫描线填充算法进行区域填充
实验步骤:
voidScanLineFill4(HDChdc,intx,inty,intoldColor,intnewColor);
扫描线填充算法
LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam);
处理主窗口的消息,WM_PAINT绘制要填充的图形
3、程序关键代码和注释
#include"stdafx.h"
#include"区域填充的扫描线算法.h"
#defineMAX_LOADSTRING100
HINSTANCEhInst;//当前实例
TCHARszTitle[MAX_LOADSTRING];//标题栏文本
TCHARszWindowClass[MAX_LOADSTRING];//主窗口类名
ATOMMyRegisterClass(HINSTANCEhInstance);
BOOLInitInstance(HINSTANCE,int);
LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
INT_PTRCALLBACKAbout(HWND,UINT,WPARAM,LPARAM);
intAPIENTRY_tWinMain(HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPTSTRlpCmdLine,
intnCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
//TODO:
在此放置代码。
MSGmsg;
HACCELhAccelTable;
//初始化全局字符串
LoadString(hInstance,IDS_APP_TITLE,szTitle,MAX_LOADSTRING);
LoadString(hInstance,IDC_MY,szWindowClass,MAX_LOADSTRING);
MyRegisterClass(hInstance);
//执行应用程序初始化:
if(!
InitInstance(hInstance,nCmdShow))
{
returnFALSE;
}
hAccelTable=LoadAccelerators(hInstance,MAKEINTRESOURCE(IDC_MY));
//主消息循环:
while(GetMessage(&msg,NULL,0,0))
{
if(!
TranslateAccelerator(msg.hwnd,hAccelTable,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return(int)msg.wParam;
}
ATOMMyRegisterClass(HINSTANCEhInstance)
{
WNDCLASSEXwcex;
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW|CS_VREDRAW;
wcex.lpfnWndProc=WndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_MY));
wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName=MAKEINTRESOURCE(IDC_MY);
wcex.lpszClassName=szWindowClass;
wcex.hIconSm=LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_SMALL));
returnRegisterClassEx(&wcex);
}
BOOLInitInstance(HINSTANCEhInstance,intnCmdShow)
{
HWNDhWnd;
hInst=hInstance;//将实例句柄存储在全局变量中
hWnd=CreateWindow(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);
if(!
hWnd)
{
returnFALSE;
}
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
returnTRUE;
}
typedefstruct{inty,xLeft,xRight;}Span;
#defineSTACK_SIZE100//maxstacksizeis100
SpanS[STACK_SIZE];
inttop=0;
voidSetStackEmpty()
{
top=0;
}
boolisStackEmpty()
{
returntop==0;
}
boolPushStack(Span*pS)
{
if(top{
S[top]=*pS;
top++;
returntrue;
}
else
returnfalse;
}
boolPopStack(Span*pS)
{
if(top>0)
{
top--;
*pS=S[top];
returntrue;
}
else
returnfalse;
}
voidScanLineFill4(HDChdc,intx,inty,intoldColor,intnewColor)
{
Spanspan;
span.y=y;
span.xLeft=x;
while(GetPixel(hdc,span.xLeft,span.y)==oldColor)
{
SetPixel(hdc,span.xLeft,span.y,newColor);
span.xLeft--;
}
if(span.xLeft==x)//notaseedpointactually
return;
else
span.xLeft++;//compansate
span.xRight=x+1;
while(GetPixel(hdc,span.xRight,span.y)==oldColor)
{
SetPixel(hdc,span.xRight,span.y,newColor);
span.xRight++;
}
if(span.xRight==x+1)//cannotextendtoright
span.xRight=x;
else
span.xRight--;//compansate
SetStackEmpty();
PushStack(&span);
while(!
isStackEmpty())
{
PopStack(&span);
SpanS;//newspan
{
S.y=span.y+1;
S.xLeft=span.xLeft;
boolxLeftNotSet=false;
while(GetPixel(hdc,S.xLeft,S.y)==oldColor)
{
S.xLeft--;
}
if(S.xLeft==span.xLeft)//xLeftisnotset
xLeftNotSet=true;
else
S.xLeft++;//compansate
inti=S.xLeft;
while(i<=span.xRight)
{
while(GetPixel(hdc,i,S.y)==oldColor)
{
if(xLeftNotSet)
{
S.xLeft=i;
xLeftNotSet=false;
}
SetPixel(hdc,i,S.y,newColor);
i++;
}
if(i>S.xLeft)
{
S.xRight=i-1;
PushStack(&S);
xLeftNotSet=true;
}
while(i<=span.xRight&&GetPixel(hdc,i,S.y)!
=oldColor)
{
i++;
}
}
}
{//similartoabove
S.y=span.y-1;
S.xLeft=span.xLeft;
boolxLeftNotSet=false;
while(GetPixel(hdc,S.xLeft,S.y)==oldColor)
{
S.xLeft--;
}
if(S.xLeft==span.xLeft)//xLeftisnotset
xLeftNotSet=true;
else
S.xLeft++;//compansate
inti=S.xLeft;
while(i<=span.xRight)
{
while(GetPixel(hdc,i,S.y)==oldColor)
{
if(xLeftNotSet)
{
S.xLeft=i;
xLeftNotSet=false;
}
SetPixel(hdc,i,S.y,newColor);
i++;
}
if(i>S.xLeft)
{
S.xRight=i-1;
PushStack(&S);
xLeftNotSet=true;
}
while(i<=span.xRight&&GetPixel(hdc,i,S.y)!
=oldColor)
{
i++;
}
}
}
}
}
LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam)
{
intwmId,wmEvent;
PAINTSTRUCTps;
HDChdc;
switch(message)
{
caseWM_COMMAND:
wmId=LOWORD(wParam);
wmEvent=HIWORD(wParam);
//分析菜单选择:
switch(wmId)
{
caseIDM_ABOUT:
DialogBox(hInst,MAKEINTRESOURCE(IDD_ABOUTBOX),hWnd,About);
break;
caseIDM_EXIT:
DestroyWindow(hWnd);
break;
default:
returnDefWindowProc(hWnd,message,wParam,lParam);
}
break;
caseWM_LBUTTONDOWN:
{
longx=LOWORD(lParam);
longy=HIWORD(lParam);
{
HDChdc=GetDC(hWnd);
ScanLineFill4(hdc,x,y,0xcccccc,0xffff00);//cyan
ReleaseDC(hWnd,hdc);
}
}
break;
caseWM_PAINT:
hdc=BeginPaint(hWnd,&ps);
//TODO:
在此添加任意绘图代码...
//画一个田字
{
HPENhPen=CreatePen(PS_SOLID,10,0xcccccc);
HGDIOBJhPenOld=SelectObject(hdc,hPen);
MoveToEx(hdc,100,100,NULL);
LineTo(hdc,300,100);
LineTo(hdc,300,300);
LineTo(hdc,100,300);
LineTo(hdc,100,100);
MoveToEx(hdc,100,200,NULL);
LineTo(hdc,300,200);
MoveToEx(hdc,200,100,NULL);
LineTo(hdc,200,300);
SelectObject(hdc,hPenOld);
DeleteObject(hPen);
}
//画一个三角形
{
HBRUSHhBr=CreateSolidBrush(0xcccccc);
HGDIOBJhBrOld=SelectObject(hdc,hBr);
POINTpt[3];
pt[0].x=400;
pt[0].y=100;
pt[1].x=500;
pt[1].y=300;
pt[2].x=600;
pt[2].y=200;
Polygon(hdc,pt,3);
SelectObject(hdc,hBrOld);
DeleteObject(hBr);
}
//提示信息
{
TCHARinfo[]=_T("在要填充的区域点击鼠标左键.");
DrawText(hdc,info,ARRAYSIZE(info)-1,&ps.rcPaint,0);
}
EndPaint(hWnd,&ps);
break;
caseWM_DESTROY:
PostQuitMessage(0);
break;
default:
returnDefWindowProc(hWnd,message,wParam,lParam);
}
return0;
}
INT_PTRCALLBACKAbout(HWNDhDlg,UINTmessage,WPARAMwParam,LPARAMlParam)
{
UNREFERENCED_PARAMETER(lParam);
switch(message)
{
caseWM_INITDIALOG:
return(INT_PTR)TRUE;
caseWM_COMMAND:
if(LOWORD(wParam)==IDOK||LOWORD(wParam)==IDCANCEL)
{
EndDialog(hDlg,LOWORD(wParam));
return(INT_PTR)TRUE;
}
break;
}
return(INT_PTR)FALSE;
}
截图:
图1未填充
图2田字图形填充
图3三角形填充
4、心得体会
(本次实验学到的和深入理解的知识点,及可能应用的场景,程序编程过程的错误及原因等)
1.通过借助栈这一数据结构,完成了区域填充的扫描线算法的实现,并利用以前所学的画圆等算法,进行综合运用,在此基础上进行扩充,设计多种图案,进行扫描线填充算法的检测,都得到了理想的结果,体现了算法的有效性;
2.栈的数据结构给种子点的操作带来了极大的方便,为算法的实现提供了便利,同时还提高了算法的复用性和可靠性;
3.此扫描线填充算法能够对多种图案进行填充,展现了算法的实用性。