计算机图形学实验报告.docx
《计算机图形学实验报告.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
计算机图形学实验报告
实验成绩:
《计算机图形学》实验报告2
班级:
1420551
专业:
网络工程
学号:
姓名
《计算机图形学》课程实验报告
(二)
班级
实验日期
2016.11.7
学号
实验名称
多边形有效边表填充算法
实
验
目
的
及
要
求
1.有效边表和桶表的数据结构
2.颜色对话框的调用方法
3.动态链表的排序方法
算
法
步
骤
1.调用颜色对话框读取填充色
2.根据实例多边形顶点坐标值,计算扫描线的最大值与最小值
3.用多边形覆盖的扫描线动态建立桶节点
4.循环访问多边形的所有顶点
5.对每个同节点连接的边表,根据x|ymin值的大小进行排序
6.循环访问每个桶结点,将桶内每个节点的边表合并成有效边表,并循环访问有效边表
7.从有效边表中取出扫描线上相邻两节点进行配对
8.循环下一桶节点,按照Xi+1=X+k(k=1/k)修改有效边表,同时合并桶内的新边表,形成新的有效边表
9.当同节点不为空转(6),负责删除桶表和边表的头结点,算法结束
调
试
过
程
结
果
定义类
1.定义有效边表类CART
2.定义桶类CBucket
3.定义填充类CFill
4.修改CTestview类
实验结果:
填充前的界面
调色板界面
填充后的界面
附
录
1.CAET类:
classCAET
{public:
CAET();
virtual~CAET();
public:
doublex;//当前扫描线与有效边交点的x坐标
intyMax;//边的最大y值
doublek;//斜率的倒数(x的增量)
CPi2ps;//边的起点
CPi2pe;//边的终点
CAET*pNext;};
2.CBucket:
classCBucket
{
CBucket();
virtual~CBucket();
intScanLine;//扫描线
CAET*pET;//桶上的边表指针
CBucket*pNext;
};
3.CFill:
classCFill
CFill();
virtual~CFill();
voidSetPoint(CPi2*p,int);//初始化
voidCreateBucket();//创建桶
voidCreateEdge();//边表
voidAddET(CAET*);//合并ET表
voidETOrder();//ET表排序
voidGouraud(CDC*);//填充多边形
voidClearMemory();//清理内存
voidDeleteAETChain(CAET*pAET);//删除边表
protected:
intPNum;//顶点个数
CPi2*P;//顶点坐标动态数组
CAET*pHeadE,*pCurrentE,*pEdge;//有效边表结点指针
CBucket*pHeadB,*pCurrentB;//桶表结点指针
CFill:
:
CFill()
PNum=0;
P=NULL;
pEdge=NULL;
pHeadB=NULL;
pHeadE=NULL;
}
~CFill()
{if(P!
=NULL)
{delete[]P;
P=NULL;}
ClearMemory();}
voidCFill:
SetPoint(CPi2*p,intm)
P=newCPi2[m];//创建一维动态数组
for(inti=0;i{P[i]=p[i];}PNum=m;}voidCFill::CreateBucket()//创建桶表{intyMin,yMax;yMin=yMax=P[0].y;for(inti=0;i{if(P[i].y{yMin=P[i].y;//扫描线的最小值}if(P[i].y>yMax){yMax=P[i].y;//扫描线的最大值}}for(inty=yMin;y<=yMax;y++){if(yMin==y)//如果是扫描线的最小值{pHeadB=newCBucket;//建立桶的头结点pCurrentB=pHeadB;//pCurrentB为CBucket当前结点指针pCurrentB->ScanLine=yMin;pCurrentB->pET=NULL;//没有链接边表pCurrentB->pNext=NULL;}else//其他扫描线{pCurrentB->pNext=newCBucket;//建立桶的其他结点pCurrentB=pCurrentB->pNext;pCurrentB->ScanLine=y;pCurrentB->pET=NULL;pCurrentB->pNext=NULL;}}}voidCFill::CreateEdge()//创建边表{for(inti=0;i{pCurrentB=pHeadB;intj=(i+1)%PNum;//边的另一个顶点,P[i]和P[j]点对构成边if(P[i].y{pEdge=newCAET;pEdge->x=P[i].x;//计算ET表的值pEdge->yMax=P[j].y;pEdge->k=(P[j].x-P[i].x)/(P[j].y-P[i].y);//代表1/kpEdge->ps=P[i];//绑定顶点和颜色pEdge->pe=P[j];pEdge->pNext=NULL;while(pCurrentB->ScanLine!=P[i].y)//在桶内寻找当前边的yMin{pCurrentB=pCurrentB->pNext;//移到yMin所在的桶结点}}if(P[j].y{pEdge=newCAET;pEdge->x=P[j].x;pEdge->yMax=P[i].y;pEdge->k=(P[i].x-P[j].x)/(P[i].y-P[j].y);pEdge->ps=P[i];pEdge->pe=P[j];pEdge->pNext=NULL;while(pCurrentB->ScanLine!=P[j].y){pCurrentB=pCurrentB->pNext;}}if(P[i].y!=P[j].y){pCurrentE=pCurrentB->pET;if(pCurrentE==NULL){pCurrentE=pEdge;pCurrentB->pET=pCurrentE;}else{while(pCurrentE->pNext!=NULL){pCurrentE=pCurrentE->pNext;}pCurrentE->pNext=pEdge;}}}}voidCFill::Gouraud(CDC*pDC)//填充多边形{CAET*pT1=NULL,*pT2=NULL;pHeadE=NULL;for(pCurrentB=pHeadB;pCurrentB!=NULL;pCurrentB=pCurrentB->pNext){for(pCurrentE=pCurrentB->pET;pCurrentE!=NULL;pCurrentE=pCurrentE->pNext){pEdge=newCAET;pEdge->x=pCurrentE->x;pEdge->yMax=pCurrentE->yMax;pEdge->k=pCurrentE->k;pEdge->ps=pCurrentE->ps;pEdge->pe=pCurrentE->pe;pEdge->pNext=NULL;AddET(pEdge);}ETOrder();pT1=pHeadE;if(pT1==NULL)return;while(pCurrentB->ScanLine>=pT1->yMax)//下闭上开{CAET*pAETTEmp=pT1;pT1=pT1->pNext;deletepAETTEmp;pHeadE=pT1;if(pHeadE==NULL)return;}if(pT1->pNext!=NULL){pT2=pT1;pT1=pT2->pNext;}while(pT1!=NULL){if(pCurrentB->ScanLine>=pT1->yMax)//下闭上开{CAET*pAETTemp=pT1;pT2->pNext=pT1->pNext;pT1=pT2->pNext;deletepAETTemp;}else{pT2=pT1;pT1=pT2->pNext;}}BOOLbInFlag=FALSE;//区间内外测试标志,初始值为假表示区间外部doublexb,xe;//扫描线与有效边相交区间的起点和终点坐标for(pT1=pHeadE;pT1!=NULL;pT1=pT1->pNext){if(FALSE==bInFlag){xb=pT1->x;bInFlag=TRUE;}else{xe=pT1->x;for(doublex=xb;x{pDC->SetPixelV(Round(x),pCurrentB->ScanLine,RGB(pT1->ps.c.red*255,pT1->ps.c.green*255,pT1->ps.c.blue*255));}bInFlag=FALSE;}}for(pT1=pHeadE;pT1!=NULL;pT1=pT1->pNext)//边的连续性{pT1->x=pT1->x+pT1->k;}}}voidCFill::AddET(CAET*pNewEdge)//合并ET表{CAET*pCE=pHeadE;if(pCE==NULL){pHeadE=pNewEdge;pCE=pHeadE;}else{while(pCE->pNext!=NULL){pCE=pCE->pNext;}pCE->pNext=pNewEdge;}}voidCFill::ETOrder()//边表的冒泡排序算法{CAET*pT1,*pT2;intCount=1;pT1=pHeadE;if(pT1==NULL){return;}if(pT1->pNext==NULL)//如果该ET表没有再连ET表{return;//桶结点只有一条边,不需要排序}while(pT1->pNext!=NULL)//统计边结点的个数{Count++;pT1=pT1->pNext;}for(inti=0;i{CAET**pPre=&pHeadE;pT1=pHeadE;for(intj=0;j{pT2=pT1->pNext;if((pT1->x>pT2->x)||((pT1->x==pT2->x)&&(pT1->k>pT2->k))){pT1->pNext=pT2->pNext;pT2->pNext=pT1;*pPre=pT2;pPre=&(pT2->pNext);//调整位置为下次遍历准备}else{pPre=&(pT1->pNext);pT1=pT1->pNext;}}}}voidCFill::ClearMemory()//安全删除所有桶与桶上连接的边{DeleteAETChain(pHeadE);CBucket*pBucket=pHeadB;while(pBucket!=NULL)//针对每一个桶{CBucket*pBucketTemp=pBucket->pNext;DeleteAETChain(pBucket->pET);deletepBucket;pBucket=pBucketTemp;}pHeadB=NULL;pHeadE=NULL;}voidCFill::DeleteAETChain(CAET*pAET){while(pAET!=NULL){CAET*pAETTemp=pAET->pNext;deletepAET;pAET=pAETTemp;}}4.修改CTestview类1).定义了ReadPoint()函数voidCTestView::ReadPoint()//点表{P[0].x=50;P[0].y=100;P[1].x=-150;P[1].y=300;P[2].x=-250;P[2].y=50;P[3].x=-150;P[3].y=-250;P[4].x=0;P[4].y=-50;P[5].x=100;P[5].y=-250;P[6].x=300;P[6].y=150;}2)绘制图形函数DrawGraph()voidCTestView::DrawGraph()//绘制图形{CRectrect;//定义客户区GetClientRect(&rect);//获得客户区的大小CDC*pDC=GetDC();//定义设备上下文指针pDC->SetMapMode(MM_ANISOTROPIC);//自定义坐标系pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口比例pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区比例,且x轴水平向右,y轴垂直向上pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);//矩形与客户区重合if(!bFill)DrawPolygon(pDC);//绘制多边形elseFillPolygon(pDC);//填充多边形ReleaseDC(pDC);//释放DC}3)绘制多边形边界函数DrawPolygon()voidCTestView::DrawPolygon(CDC*pDC)//绘制多边形边界{CLine*line=newCLine;CP2t;for(inti=0;i<7;i++)//绘制多边形{if(i==0){line->MoveTo(pDC,P[i]);t=P[i];}else{line->LineTo(pDC,P[i]);}}line->LineTo(pDC,t);//闭合多边形deleteline;}4)填充多边形函数FillPolygon()voidCTestView::FillPolygon(CDC*pDC)//填充多边形{for(inti=0;i<7;i++)//转储顶点坐标,y坐标取为整数{P1[i].x=P[i].x;P1[i].y=Round(P[i].y);P1[i].c=CRGB(bRed/255.0,bGreen/255.0,bBlue/255.0);}CFill*fill=newCFill;//动态分配内存fill->SetPoint(P1,7);//初始化Fill对象fill->CreateBucket();//建立桶表fill->CreateEdge();//建立边表fill->Gouraud(pDC);//填充多边形deletefill;//撤销内存}5)菜单函数voidCTestView::OnDrawpic(){//TODO:AddyourcommandhandlercodehereCOLORREFGetClr=RGB(0,0,0);//调色板颜色CColorDialogccd(GetClr,CC_SOLIDCOLOR);if(IDOK==ccd.DoModal())//调用颜色对话框选取填充色GetClr=ccd.GetColor();elsereturn;bRed=GetRValue(GetClr);//获取红色分量bGreen=GetGValue(GetClr);//获取绿色分量bBlue=GetBValue(GetClr);//获取蓝色分量bFill=TRUE;Invalidate();}实验地点专业软件实验室指导教师李丽亚
{P[i]=p[i];}
PNum=m;
CreateBucket()//创建桶表
intyMin,yMax;
yMin=yMax=P[0].y;
for(inti=0;i{if(P[i].y{yMin=P[i].y;//扫描线的最小值}if(P[i].y>yMax){yMax=P[i].y;//扫描线的最大值}}for(inty=yMin;y<=yMax;y++){if(yMin==y)//如果是扫描线的最小值{pHeadB=newCBucket;//建立桶的头结点pCurrentB=pHeadB;//pCurrentB为CBucket当前结点指针pCurrentB->ScanLine=yMin;pCurrentB->pET=NULL;//没有链接边表pCurrentB->pNext=NULL;}else//其他扫描线{pCurrentB->pNext=newCBucket;//建立桶的其他结点pCurrentB=pCurrentB->pNext;pCurrentB->ScanLine=y;pCurrentB->pET=NULL;pCurrentB->pNext=NULL;}}}voidCFill::CreateEdge()//创建边表{for(inti=0;i{pCurrentB=pHeadB;intj=(i+1)%PNum;//边的另一个顶点,P[i]和P[j]点对构成边if(P[i].y{pEdge=newCAET;pEdge->x=P[i].x;//计算ET表的值pEdge->yMax=P[j].y;pEdge->k=(P[j].x-P[i].x)/(P[j].y-P[i].y);//代表1/kpEdge->ps=P[i];//绑定顶点和颜色pEdge->pe=P[j];pEdge->pNext=NULL;while(pCurrentB->ScanLine!=P[i].y)//在桶内寻找当前边的yMin{pCurrentB=pCurrentB->pNext;//移到yMin所在的桶结点}}if(P[j].y{pEdge=newCAET;pEdge->x=P[j].x;pEdge->yMax=P[i].y;pEdge->k=(P[i].x-P[j].x)/(P[i].y-P[j].y);pEdge->ps=P[i];pEdge->pe=P[j];pEdge->pNext=NULL;while(pCurrentB->ScanLine!=P[j].y){pCurrentB=pCurrentB->pNext;}}if(P[i].y!=P[j].y){pCurrentE=pCurrentB->pET;if(pCurrentE==NULL){pCurrentE=pEdge;pCurrentB->pET=pCurrentE;}else{while(pCurrentE->pNext!=NULL){pCurrentE=pCurrentE->pNext;}pCurrentE->pNext=pEdge;}}}}voidCFill::Gouraud(CDC*pDC)//填充多边形{CAET*pT1=NULL,*pT2=NULL;pHeadE=NULL;for(pCurrentB=pHeadB;pCurrentB!=NULL;pCurrentB=pCurrentB->pNext){for(pCurrentE=pCurrentB->pET;pCurrentE!=NULL;pCurrentE=pCurrentE->pNext){pEdge=newCAET;pEdge->x=pCurrentE->x;pEdge->yMax=pCurrentE->yMax;pEdge->k=pCurrentE->k;pEdge->ps=pCurrentE->ps;pEdge->pe=pCurrentE->pe;pEdge->pNext=NULL;AddET(pEdge);}ETOrder();pT1=pHeadE;if(pT1==NULL)return;while(pCurrentB->ScanLine>=pT1->yMax)//下闭上开{CAET*pAETTEmp=pT1;pT1=pT1->pNext;deletepAETTEmp;pHeadE=pT1;if(pHeadE==NULL)return;}if(pT1->pNext!=NULL){pT2=pT1;pT1=pT2->pNext;}while(pT1!=NULL){if(pCurrentB->ScanLine>=pT1->yMax)//下闭上开{CAET*pAETTemp=pT1;pT2->pNext=pT1->pNext;pT1=pT2->pNext;deletepAETTemp;}else{pT2=pT1;pT1=pT2->pNext;}}BOOLbInFlag=FALSE;//区间内外测试标志,初始值为假表示区间外部doublexb,xe;//扫描线与有效边相交区间的起点和终点坐标for(pT1=pHeadE;pT1!=NULL;pT1=pT1->pNext){if(FALSE==bInFlag){xb=pT1->x;bInFlag=TRUE;}else{xe=pT1->x;for(doublex=xb;x{pDC->SetPixelV(Round(x),pCurrentB->ScanLine,RGB(pT1->ps.c.red*255,pT1->ps.c.green*255,pT1->ps.c.blue*255));}bInFlag=FALSE;}}for(pT1=pHeadE;pT1!=NULL;pT1=pT1->pNext)//边的连续性{pT1->x=pT1->x+pT1->k;}}}voidCFill::AddET(CAET*pNewEdge)//合并ET表{CAET*pCE=pHeadE;if(pCE==NULL){pHeadE=pNewEdge;pCE=pHeadE;}else{while(pCE->pNext!=NULL){pCE=pCE->pNext;}pCE->pNext=pNewEdge;}}voidCFill::ETOrder()//边表的冒泡排序算法{CAET*pT1,*pT2;intCount=1;pT1=pHeadE;if(pT1==NULL){return;}if(pT1->pNext==NULL)//如果该ET表没有再连ET表{return;//桶结点只有一条边,不需要排序}while(pT1->pNext!=NULL)//统计边结点的个数{Count++;pT1=pT1->pNext;}for(inti=0;i{CAET**pPre=&pHeadE;pT1=pHeadE;for(intj=0;j{pT2=pT1->pNext;if((pT1->x>pT2->x)||((pT1->x==pT2->x)&&(pT1->k>pT2->k))){pT1->pNext=pT2->pNext;pT2->pNext=pT1;*pPre=pT2;pPre=&(pT2->pNext);//调整位置为下次遍历准备}else{pPre=&(pT1->pNext);pT1=pT1->pNext;}}}}voidCFill::ClearMemory()//安全删除所有桶与桶上连接的边{DeleteAETChain(pHeadE);CBucket*pBucket=pHeadB;while(pBucket!=NULL)//针对每一个桶{CBucket*pBucketTemp=pBucket->pNext;DeleteAETChain(pBucket->pET);deletepBucket;pBucket=pBucketTemp;}pHeadB=NULL;pHeadE=NULL;}voidCFill::DeleteAETChain(CAET*pAET){while(pAET!=NULL){CAET*pAETTemp=pAET->pNext;deletepAET;pAET=pAETTemp;}}4.修改CTestview类1).定义了ReadPoint()函数voidCTestView::ReadPoint()//点表{P[0].x=50;P[0].y=100;P[1].x=-150;P[1].y=300;P[2].x=-250;P[2].y=50;P[3].x=-150;P[3].y=-250;P[4].x=0;P[4].y=-50;P[5].x=100;P[5].y=-250;P[6].x=300;P[6].y=150;}2)绘制图形函数DrawGraph()voidCTestView::DrawGraph()//绘制图形{CRectrect;//定义客户区GetClientRect(&rect);//获得客户区的大小CDC*pDC=GetDC();//定义设备上下文指针pDC->SetMapMode(MM_ANISOTROPIC);//自定义坐标系pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口比例pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区比例,且x轴水平向右,y轴垂直向上pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);//矩形与客户区重合if(!bFill)DrawPolygon(pDC);//绘制多边形elseFillPolygon(pDC);//填充多边形ReleaseDC(pDC);//释放DC}3)绘制多边形边界函数DrawPolygon()voidCTestView::DrawPolygon(CDC*pDC)//绘制多边形边界{CLine*line=newCLine;CP2t;for(inti=0;i<7;i++)//绘制多边形{if(i==0){line->MoveTo(pDC,P[i]);t=P[i];}else{line->LineTo(pDC,P[i]);}}line->LineTo(pDC,t);//闭合多边形deleteline;}4)填充多边形函数FillPolygon()voidCTestView::FillPolygon(CDC*pDC)//填充多边形{for(inti=0;i<7;i++)//转储顶点坐标,y坐标取为整数{P1[i].x=P[i].x;P1[i].y=Round(P[i].y);P1[i].c=CRGB(bRed/255.0,bGreen/255.0,bBlue/255.0);}CFill*fill=newCFill;//动态分配内存fill->SetPoint(P1,7);//初始化Fill对象fill->CreateBucket();//建立桶表fill->CreateEdge();//建立边表fill->Gouraud(pDC);//填充多边形deletefill;//撤销内存}5)菜单函数voidCTestView::OnDrawpic(){//TODO:AddyourcommandhandlercodehereCOLORREFGetClr=RGB(0,0,0);//调色板颜色CColorDialogccd(GetClr,CC_SOLIDCOLOR);if(IDOK==ccd.DoModal())//调用颜色对话框选取填充色GetClr=ccd.GetColor();elsereturn;bRed=GetRValue(GetClr);//获取红色分量bGreen=GetGValue(GetClr);//获取绿色分量bBlue=GetBValue(GetClr);//获取蓝色分量bFill=TRUE;Invalidate();}实验地点专业软件实验室指导教师李丽亚
if(P[i].y{yMin=P[i].y;//扫描线的最小值}if(P[i].y>yMax){yMax=P[i].y;//扫描线的最大值}}for(inty=yMin;y<=yMax;y++){if(yMin==y)//如果是扫描线的最小值{pHeadB=newCBucket;//建立桶的头结点pCurrentB=pHeadB;//pCurrentB为CBucket当前结点指针pCurrentB->ScanLine=yMin;pCurrentB->pET=NULL;//没有链接边表pCurrentB->pNext=NULL;}else//其他扫描线{pCurrentB->pNext=newCBucket;//建立桶的其他结点pCurrentB=pCurrentB->pNext;pCurrentB->ScanLine=y;pCurrentB->pET=NULL;pCurrentB->pNext=NULL;}}}voidCFill::CreateEdge()//创建边表{for(inti=0;i{pCurrentB=pHeadB;intj=(i+1)%PNum;//边的另一个顶点,P[i]和P[j]点对构成边if(P[i].y{pEdge=newCAET;pEdge->x=P[i].x;//计算ET表的值pEdge->yMax=P[j].y;pEdge->k=(P[j].x-P[i].x)/(P[j].y-P[i].y);//代表1/kpEdge->ps=P[i];//绑定顶点和颜色pEdge->pe=P[j];pEdge->pNext=NULL;while(pCurrentB->ScanLine!=P[i].y)//在桶内寻找当前边的yMin{pCurrentB=pCurrentB->pNext;//移到yMin所在的桶结点}}if(P[j].y{pEdge=newCAET;pEdge->x=P[j].x;pEdge->yMax=P[i].y;pEdge->k=(P[i].x-P[j].x)/(P[i].y-P[j].y);pEdge->ps=P[i];pEdge->pe=P[j];pEdge->pNext=NULL;while(pCurrentB->ScanLine!=P[j].y){pCurrentB=pCurrentB->pNext;}}if(P[i].y!=P[j].y){pCurrentE=pCurrentB->pET;if(pCurrentE==NULL){pCurrentE=pEdge;pCurrentB->pET=pCurrentE;}else{while(pCurrentE->pNext!=NULL){pCurrentE=pCurrentE->pNext;}pCurrentE->pNext=pEdge;}}}}voidCFill::Gouraud(CDC*pDC)//填充多边形{CAET*pT1=NULL,*pT2=NULL;pHeadE=NULL;for(pCurrentB=pHeadB;pCurrentB!=NULL;pCurrentB=pCurrentB->pNext){for(pCurrentE=pCurrentB->pET;pCurrentE!=NULL;pCurrentE=pCurrentE->pNext){pEdge=newCAET;pEdge->x=pCurrentE->x;pEdge->yMax=pCurrentE->yMax;pEdge->k=pCurrentE->k;pEdge->ps=pCurrentE->ps;pEdge->pe=pCurrentE->pe;pEdge->pNext=NULL;AddET(pEdge);}ETOrder();pT1=pHeadE;if(pT1==NULL)return;while(pCurrentB->ScanLine>=pT1->yMax)//下闭上开{CAET*pAETTEmp=pT1;pT1=pT1->pNext;deletepAETTEmp;pHeadE=pT1;if(pHeadE==NULL)return;}if(pT1->pNext!=NULL){pT2=pT1;pT1=pT2->pNext;}while(pT1!=NULL){if(pCurrentB->ScanLine>=pT1->yMax)//下闭上开{CAET*pAETTemp=pT1;pT2->pNext=pT1->pNext;pT1=pT2->pNext;deletepAETTemp;}else{pT2=pT1;pT1=pT2->pNext;}}BOOLbInFlag=FALSE;//区间内外测试标志,初始值为假表示区间外部doublexb,xe;//扫描线与有效边相交区间的起点和终点坐标for(pT1=pHeadE;pT1!=NULL;pT1=pT1->pNext){if(FALSE==bInFlag){xb=pT1->x;bInFlag=TRUE;}else{xe=pT1->x;for(doublex=xb;x{pDC->SetPixelV(Round(x),pCurrentB->ScanLine,RGB(pT1->ps.c.red*255,pT1->ps.c.green*255,pT1->ps.c.blue*255));}bInFlag=FALSE;}}for(pT1=pHeadE;pT1!=NULL;pT1=pT1->pNext)//边的连续性{pT1->x=pT1->x+pT1->k;}}}voidCFill::AddET(CAET*pNewEdge)//合并ET表{CAET*pCE=pHeadE;if(pCE==NULL){pHeadE=pNewEdge;pCE=pHeadE;}else{while(pCE->pNext!=NULL){pCE=pCE->pNext;}pCE->pNext=pNewEdge;}}voidCFill::ETOrder()//边表的冒泡排序算法{CAET*pT1,*pT2;intCount=1;pT1=pHeadE;if(pT1==NULL){return;}if(pT1->pNext==NULL)//如果该ET表没有再连ET表{return;//桶结点只有一条边,不需要排序}while(pT1->pNext!=NULL)//统计边结点的个数{Count++;pT1=pT1->pNext;}for(inti=0;i{CAET**pPre=&pHeadE;pT1=pHeadE;for(intj=0;j{pT2=pT1->pNext;if((pT1->x>pT2->x)||((pT1->x==pT2->x)&&(pT1->k>pT2->k))){pT1->pNext=pT2->pNext;pT2->pNext=pT1;*pPre=pT2;pPre=&(pT2->pNext);//调整位置为下次遍历准备}else{pPre=&(pT1->pNext);pT1=pT1->pNext;}}}}voidCFill::ClearMemory()//安全删除所有桶与桶上连接的边{DeleteAETChain(pHeadE);CBucket*pBucket=pHeadB;while(pBucket!=NULL)//针对每一个桶{CBucket*pBucketTemp=pBucket->pNext;DeleteAETChain(pBucket->pET);deletepBucket;pBucket=pBucketTemp;}pHeadB=NULL;pHeadE=NULL;}voidCFill::DeleteAETChain(CAET*pAET){while(pAET!=NULL){CAET*pAETTemp=pAET->pNext;deletepAET;pAET=pAETTemp;}}4.修改CTestview类1).定义了ReadPoint()函数voidCTestView::ReadPoint()//点表{P[0].x=50;P[0].y=100;P[1].x=-150;P[1].y=300;P[2].x=-250;P[2].y=50;P[3].x=-150;P[3].y=-250;P[4].x=0;P[4].y=-50;P[5].x=100;P[5].y=-250;P[6].x=300;P[6].y=150;}2)绘制图形函数DrawGraph()voidCTestView::DrawGraph()//绘制图形{CRectrect;//定义客户区GetClientRect(&rect);//获得客户区的大小CDC*pDC=GetDC();//定义设备上下文指针pDC->SetMapMode(MM_ANISOTROPIC);//自定义坐标系pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口比例pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区比例,且x轴水平向右,y轴垂直向上pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);//矩形与客户区重合if(!bFill)DrawPolygon(pDC);//绘制多边形elseFillPolygon(pDC);//填充多边形ReleaseDC(pDC);//释放DC}3)绘制多边形边界函数DrawPolygon()voidCTestView::DrawPolygon(CDC*pDC)//绘制多边形边界{CLine*line=newCLine;CP2t;for(inti=0;i<7;i++)//绘制多边形{if(i==0){line->MoveTo(pDC,P[i]);t=P[i];}else{line->LineTo(pDC,P[i]);}}line->LineTo(pDC,t);//闭合多边形deleteline;}4)填充多边形函数FillPolygon()voidCTestView::FillPolygon(CDC*pDC)//填充多边形{for(inti=0;i<7;i++)//转储顶点坐标,y坐标取为整数{P1[i].x=P[i].x;P1[i].y=Round(P[i].y);P1[i].c=CRGB(bRed/255.0,bGreen/255.0,bBlue/255.0);}CFill*fill=newCFill;//动态分配内存fill->SetPoint(P1,7);//初始化Fill对象fill->CreateBucket();//建立桶表fill->CreateEdge();//建立边表fill->Gouraud(pDC);//填充多边形deletefill;//撤销内存}5)菜单函数voidCTestView::OnDrawpic(){//TODO:AddyourcommandhandlercodehereCOLORREFGetClr=RGB(0,0,0);//调色板颜色CColorDialogccd(GetClr,CC_SOLIDCOLOR);if(IDOK==ccd.DoModal())//调用颜色对话框选取填充色GetClr=ccd.GetColor();elsereturn;bRed=GetRValue(GetClr);//获取红色分量bGreen=GetGValue(GetClr);//获取绿色分量bBlue=GetBValue(GetClr);//获取蓝色分量bFill=TRUE;Invalidate();}实验地点专业软件实验室指导教师李丽亚
yMin=P[i].y;//扫描线的最小值
if(P[i].y>yMax)
yMax=P[i].y;//扫描线的最大值
for(inty=yMin;y<=yMax;y++)
if(yMin==y)//如果是扫描线的最小值
{pHeadB=newCBucket;//建立桶的头结点
pCurrentB=pHeadB;//pCurrentB为CBucket当前结点指针
pCurrentB->ScanLine=yMin;
pCurrentB->pET=NULL;//没有链接边表
pCurrentB->pNext=NULL;
else//其他扫描线
{pCurrentB->pNext=newCBucket;//建立桶的其他结点
pCurrentB=pCurrentB->pNext;
pCurrentB->ScanLine=y;
pCurrentB->pET=NULL;
pCurrentB->pNext=NULL;}}}
CreateEdge()//创建边表
for(inti=0;i{pCurrentB=pHeadB;intj=(i+1)%PNum;//边的另一个顶点,P[i]和P[j]点对构成边if(P[i].y{pEdge=newCAET;pEdge->x=P[i].x;//计算ET表的值pEdge->yMax=P[j].y;pEdge->k=(P[j].x-P[i].x)/(P[j].y-P[i].y);//代表1/kpEdge->ps=P[i];//绑定顶点和颜色pEdge->pe=P[j];pEdge->pNext=NULL;while(pCurrentB->ScanLine!=P[i].y)//在桶内寻找当前边的yMin{pCurrentB=pCurrentB->pNext;//移到yMin所在的桶结点}}if(P[j].y{pEdge=newCAET;pEdge->x=P[j].x;pEdge->yMax=P[i].y;pEdge->k=(P[i].x-P[j].x)/(P[i].y-P[j].y);pEdge->ps=P[i];pEdge->pe=P[j];pEdge->pNext=NULL;while(pCurrentB->ScanLine!=P[j].y){pCurrentB=pCurrentB->pNext;}}if(P[i].y!=P[j].y){pCurrentE=pCurrentB->pET;if(pCurrentE==NULL){pCurrentE=pEdge;pCurrentB->pET=pCurrentE;}else{while(pCurrentE->pNext!=NULL){pCurrentE=pCurrentE->pNext;}pCurrentE->pNext=pEdge;}}}}voidCFill::Gouraud(CDC*pDC)//填充多边形{CAET*pT1=NULL,*pT2=NULL;pHeadE=NULL;for(pCurrentB=pHeadB;pCurrentB!=NULL;pCurrentB=pCurrentB->pNext){for(pCurrentE=pCurrentB->pET;pCurrentE!=NULL;pCurrentE=pCurrentE->pNext){pEdge=newCAET;pEdge->x=pCurrentE->x;pEdge->yMax=pCurrentE->yMax;pEdge->k=pCurrentE->k;pEdge->ps=pCurrentE->ps;pEdge->pe=pCurrentE->pe;pEdge->pNext=NULL;AddET(pEdge);}ETOrder();pT1=pHeadE;if(pT1==NULL)return;while(pCurrentB->ScanLine>=pT1->yMax)//下闭上开{CAET*pAETTEmp=pT1;pT1=pT1->pNext;deletepAETTEmp;pHeadE=pT1;if(pHeadE==NULL)return;}if(pT1->pNext!=NULL){pT2=pT1;pT1=pT2->pNext;}while(pT1!=NULL){if(pCurrentB->ScanLine>=pT1->yMax)//下闭上开{CAET*pAETTemp=pT1;pT2->pNext=pT1->pNext;pT1=pT2->pNext;deletepAETTemp;}else{pT2=pT1;pT1=pT2->pNext;}}BOOLbInFlag=FALSE;//区间内外测试标志,初始值为假表示区间外部doublexb,xe;//扫描线与有效边相交区间的起点和终点坐标for(pT1=pHeadE;pT1!=NULL;pT1=pT1->pNext){if(FALSE==bInFlag){xb=pT1->x;bInFlag=TRUE;}else{xe=pT1->x;for(doublex=xb;x{pDC->SetPixelV(Round(x),pCurrentB->ScanLine,RGB(pT1->ps.c.red*255,pT1->ps.c.green*255,pT1->ps.c.blue*255));}bInFlag=FALSE;}}for(pT1=pHeadE;pT1!=NULL;pT1=pT1->pNext)//边的连续性{pT1->x=pT1->x+pT1->k;}}}voidCFill::AddET(CAET*pNewEdge)//合并ET表{CAET*pCE=pHeadE;if(pCE==NULL){pHeadE=pNewEdge;pCE=pHeadE;}else{while(pCE->pNext!=NULL){pCE=pCE->pNext;}pCE->pNext=pNewEdge;}}voidCFill::ETOrder()//边表的冒泡排序算法{CAET*pT1,*pT2;intCount=1;pT1=pHeadE;if(pT1==NULL){return;}if(pT1->pNext==NULL)//如果该ET表没有再连ET表{return;//桶结点只有一条边,不需要排序}while(pT1->pNext!=NULL)//统计边结点的个数{Count++;pT1=pT1->pNext;}for(inti=0;i{CAET**pPre=&pHeadE;pT1=pHeadE;for(intj=0;j{pT2=pT1->pNext;if((pT1->x>pT2->x)||((pT1->x==pT2->x)&&(pT1->k>pT2->k))){pT1->pNext=pT2->pNext;pT2->pNext=pT1;*pPre=pT2;pPre=&(pT2->pNext);//调整位置为下次遍历准备}else{pPre=&(pT1->pNext);pT1=pT1->pNext;}}}}voidCFill::ClearMemory()//安全删除所有桶与桶上连接的边{DeleteAETChain(pHeadE);CBucket*pBucket=pHeadB;while(pBucket!=NULL)//针对每一个桶{CBucket*pBucketTemp=pBucket->pNext;DeleteAETChain(pBucket->pET);deletepBucket;pBucket=pBucketTemp;}pHeadB=NULL;pHeadE=NULL;}voidCFill::DeleteAETChain(CAET*pAET){while(pAET!=NULL){CAET*pAETTemp=pAET->pNext;deletepAET;pAET=pAETTemp;}}4.修改CTestview类1).定义了ReadPoint()函数voidCTestView::ReadPoint()//点表{P[0].x=50;P[0].y=100;P[1].x=-150;P[1].y=300;P[2].x=-250;P[2].y=50;P[3].x=-150;P[3].y=-250;P[4].x=0;P[4].y=-50;P[5].x=100;P[5].y=-250;P[6].x=300;P[6].y=150;}2)绘制图形函数DrawGraph()voidCTestView::DrawGraph()//绘制图形{CRectrect;//定义客户区GetClientRect(&rect);//获得客户区的大小CDC*pDC=GetDC();//定义设备上下文指针pDC->SetMapMode(MM_ANISOTROPIC);//自定义坐标系pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口比例pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区比例,且x轴水平向右,y轴垂直向上pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);//矩形与客户区重合if(!bFill)DrawPolygon(pDC);//绘制多边形elseFillPolygon(pDC);//填充多边形ReleaseDC(pDC);//释放DC}3)绘制多边形边界函数DrawPolygon()voidCTestView::DrawPolygon(CDC*pDC)//绘制多边形边界{CLine*line=newCLine;CP2t;for(inti=0;i<7;i++)//绘制多边形{if(i==0){line->MoveTo(pDC,P[i]);t=P[i];}else{line->LineTo(pDC,P[i]);}}line->LineTo(pDC,t);//闭合多边形deleteline;}4)填充多边形函数FillPolygon()voidCTestView::FillPolygon(CDC*pDC)//填充多边形{for(inti=0;i<7;i++)//转储顶点坐标,y坐标取为整数{P1[i].x=P[i].x;P1[i].y=Round(P[i].y);P1[i].c=CRGB(bRed/255.0,bGreen/255.0,bBlue/255.0);}CFill*fill=newCFill;//动态分配内存fill->SetPoint(P1,7);//初始化Fill对象fill->CreateBucket();//建立桶表fill->CreateEdge();//建立边表fill->Gouraud(pDC);//填充多边形deletefill;//撤销内存}5)菜单函数voidCTestView::OnDrawpic(){//TODO:AddyourcommandhandlercodehereCOLORREFGetClr=RGB(0,0,0);//调色板颜色CColorDialogccd(GetClr,CC_SOLIDCOLOR);if(IDOK==ccd.DoModal())//调用颜色对话框选取填充色GetClr=ccd.GetColor();elsereturn;bRed=GetRValue(GetClr);//获取红色分量bGreen=GetGValue(GetClr);//获取绿色分量bBlue=GetBValue(GetClr);//获取蓝色分量bFill=TRUE;Invalidate();}实验地点专业软件实验室指导教师李丽亚
{pCurrentB=pHeadB;
intj=(i+1)%PNum;//边的另一个顶点,P[i]和P[j]点对构成边
if(P[i].y
pEdge=newCAET;
pEdge->x=P[i].x;//计算ET表的值
pEdge->yMax=P[j].y;
pEdge->k=(P[j].x-P[i].x)/(P[j].y-P[i].y);//代表1/k
pEdge->ps=P[i];//绑定顶点和颜色
pEdge->pe=P[j];
pEdge->pNext=NULL;
while(pCurrentB->ScanLine!
=P[i].y)//在桶内寻找当前边的yMin
pCurrentB=pCurrentB->pNext;//移到yMin所在的桶结点
if(P[j].y
pEdge->x=P[j].x;
pEdge->yMax=P[i].y;
pEdge->k=(P[i].x-P[j].x)/(P[i].y-P[j].y);
pEdge->ps=P[i];
=P[j].y)
if(P[i].y!
pCurrentE=pCurrentB->pET;
if(pCurrentE==NULL)
pCurrentE=pEdge;
pCurrentB->pET=pCurrentE;
else
while(pCurrentE->pNext!
pCurrentE=pCurrentE->pNext;
pCurrentE->pNext=pEdge;
Gouraud(CDC*pDC)//填充多边形
CAET*pT1=NULL,*pT2=NULL;
for(pCurrentB=pHeadB;pCurrentB!
=NULL;pCurrentB=pCurrentB->pNext)
for(pCurrentE=pCurrentB->pET;pCurrentE!
=NULL;pCurrentE=pCurrentE->pNext)
pEdge->x=pCurrentE->x;
pEdge->yMax=pCurrentE->yMax;
pEdge->k=pCurrentE->k;
pEdge->ps=pCurrentE->ps;
pEdge->pe=pCurrentE->pe;
AddET(pEdge);
ETOrder();
pT1=pHeadE;
if(pT1==NULL)
return;
while(pCurrentB->ScanLine>=pT1->yMax)//下闭上开
CAET*pAETTEmp=pT1;
pT1=pT1->pNext;
deletepAETTEmp;
pHeadE=pT1;
if(pHeadE==NULL)
if(pT1->pNext!
pT2=pT1;
pT1=pT2->pNext;
while(pT1!
if(pCurrentB->ScanLine>=pT1->yMax)//下闭上开
CAET*pAETTemp=pT1;
pT2->pNext=pT1->pNext;
deletepAETTemp;
BOOLbInFlag=FALSE;//区间内外测试标志,初始值为假表示区间外部
doublexb,xe;//扫描线与有效边相交区间的起点和终点坐标
for(pT1=pHeadE;pT1!
=NULL;pT1=pT1->pNext)
if(FALSE==bInFlag)
xb=pT1->x;
bInFlag=TRUE;
xe=pT1->x;
for(doublex=xb;x{pDC->SetPixelV(Round(x),pCurrentB->ScanLine,RGB(pT1->ps.c.red*255,pT1->ps.c.green*255,pT1->ps.c.blue*255));}bInFlag=FALSE;}}for(pT1=pHeadE;pT1!=NULL;pT1=pT1->pNext)//边的连续性{pT1->x=pT1->x+pT1->k;}}}voidCFill::AddET(CAET*pNewEdge)//合并ET表{CAET*pCE=pHeadE;if(pCE==NULL){pHeadE=pNewEdge;pCE=pHeadE;}else{while(pCE->pNext!=NULL){pCE=pCE->pNext;}pCE->pNext=pNewEdge;}}voidCFill::ETOrder()//边表的冒泡排序算法{CAET*pT1,*pT2;intCount=1;pT1=pHeadE;if(pT1==NULL){return;}if(pT1->pNext==NULL)//如果该ET表没有再连ET表{return;//桶结点只有一条边,不需要排序}while(pT1->pNext!=NULL)//统计边结点的个数{Count++;pT1=pT1->pNext;}for(inti=0;i{CAET**pPre=&pHeadE;pT1=pHeadE;for(intj=0;j{pT2=pT1->pNext;if((pT1->x>pT2->x)||((pT1->x==pT2->x)&&(pT1->k>pT2->k))){pT1->pNext=pT2->pNext;pT2->pNext=pT1;*pPre=pT2;pPre=&(pT2->pNext);//调整位置为下次遍历准备}else{pPre=&(pT1->pNext);pT1=pT1->pNext;}}}}voidCFill::ClearMemory()//安全删除所有桶与桶上连接的边{DeleteAETChain(pHeadE);CBucket*pBucket=pHeadB;while(pBucket!=NULL)//针对每一个桶{CBucket*pBucketTemp=pBucket->pNext;DeleteAETChain(pBucket->pET);deletepBucket;pBucket=pBucketTemp;}pHeadB=NULL;pHeadE=NULL;}voidCFill::DeleteAETChain(CAET*pAET){while(pAET!=NULL){CAET*pAETTemp=pAET->pNext;deletepAET;pAET=pAETTemp;}}4.修改CTestview类1).定义了ReadPoint()函数voidCTestView::ReadPoint()//点表{P[0].x=50;P[0].y=100;P[1].x=-150;P[1].y=300;P[2].x=-250;P[2].y=50;P[3].x=-150;P[3].y=-250;P[4].x=0;P[4].y=-50;P[5].x=100;P[5].y=-250;P[6].x=300;P[6].y=150;}2)绘制图形函数DrawGraph()voidCTestView::DrawGraph()//绘制图形{CRectrect;//定义客户区GetClientRect(&rect);//获得客户区的大小CDC*pDC=GetDC();//定义设备上下文指针pDC->SetMapMode(MM_ANISOTROPIC);//自定义坐标系pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口比例pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区比例,且x轴水平向右,y轴垂直向上pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);//矩形与客户区重合if(!bFill)DrawPolygon(pDC);//绘制多边形elseFillPolygon(pDC);//填充多边形ReleaseDC(pDC);//释放DC}3)绘制多边形边界函数DrawPolygon()voidCTestView::DrawPolygon(CDC*pDC)//绘制多边形边界{CLine*line=newCLine;CP2t;for(inti=0;i<7;i++)//绘制多边形{if(i==0){line->MoveTo(pDC,P[i]);t=P[i];}else{line->LineTo(pDC,P[i]);}}line->LineTo(pDC,t);//闭合多边形deleteline;}4)填充多边形函数FillPolygon()voidCTestView::FillPolygon(CDC*pDC)//填充多边形{for(inti=0;i<7;i++)//转储顶点坐标,y坐标取为整数{P1[i].x=P[i].x;P1[i].y=Round(P[i].y);P1[i].c=CRGB(bRed/255.0,bGreen/255.0,bBlue/255.0);}CFill*fill=newCFill;//动态分配内存fill->SetPoint(P1,7);//初始化Fill对象fill->CreateBucket();//建立桶表fill->CreateEdge();//建立边表fill->Gouraud(pDC);//填充多边形deletefill;//撤销内存}5)菜单函数voidCTestView::OnDrawpic(){//TODO:AddyourcommandhandlercodehereCOLORREFGetClr=RGB(0,0,0);//调色板颜色CColorDialogccd(GetClr,CC_SOLIDCOLOR);if(IDOK==ccd.DoModal())//调用颜色对话框选取填充色GetClr=ccd.GetColor();elsereturn;bRed=GetRValue(GetClr);//获取红色分量bGreen=GetGValue(GetClr);//获取绿色分量bBlue=GetBValue(GetClr);//获取蓝色分量bFill=TRUE;Invalidate();}实验地点专业软件实验室指导教师李丽亚
pDC->SetPixelV(Round(x),pCurrentB->ScanLine,RGB(pT1->ps.c.red*255,pT1->ps.c.green*255,pT1->ps.c.blue*255));
bInFlag=FALSE;
=NULL;pT1=pT1->pNext)//边的连续性
pT1->x=pT1->x+pT1->k;
AddET(CAET*pNewEdge)//合并ET表
CAET*pCE=pHeadE;
if(pCE==NULL)
pHeadE=pNewEdge;
pCE=pHeadE;
while(pCE->pNext!
pCE=pCE->pNext;
pCE->pNext=pNewEdge;
ETOrder()//边表的冒泡排序算法
CAET*pT1,*pT2;
intCount=1;
if(pT1->pNext==NULL)//如果该ET表没有再连ET表
return;//桶结点只有一条边,不需要排序
while(pT1->pNext!
=NULL)//统计边结点的个数
Count++;
for(inti=0;i{CAET**pPre=&pHeadE;pT1=pHeadE;for(intj=0;j{pT2=pT1->pNext;if((pT1->x>pT2->x)||((pT1->x==pT2->x)&&(pT1->k>pT2->k))){pT1->pNext=pT2->pNext;pT2->pNext=pT1;*pPre=pT2;pPre=&(pT2->pNext);//调整位置为下次遍历准备}else{pPre=&(pT1->pNext);pT1=pT1->pNext;}}}}voidCFill::ClearMemory()//安全删除所有桶与桶上连接的边{DeleteAETChain(pHeadE);CBucket*pBucket=pHeadB;while(pBucket!=NULL)//针对每一个桶{CBucket*pBucketTemp=pBucket->pNext;DeleteAETChain(pBucket->pET);deletepBucket;pBucket=pBucketTemp;}pHeadB=NULL;pHeadE=NULL;}voidCFill::DeleteAETChain(CAET*pAET){while(pAET!=NULL){CAET*pAETTemp=pAET->pNext;deletepAET;pAET=pAETTemp;}}4.修改CTestview类1).定义了ReadPoint()函数voidCTestView::ReadPoint()//点表{P[0].x=50;P[0].y=100;P[1].x=-150;P[1].y=300;P[2].x=-250;P[2].y=50;P[3].x=-150;P[3].y=-250;P[4].x=0;P[4].y=-50;P[5].x=100;P[5].y=-250;P[6].x=300;P[6].y=150;}2)绘制图形函数DrawGraph()voidCTestView::DrawGraph()//绘制图形{CRectrect;//定义客户区GetClientRect(&rect);//获得客户区的大小CDC*pDC=GetDC();//定义设备上下文指针pDC->SetMapMode(MM_ANISOTROPIC);//自定义坐标系pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口比例pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区比例,且x轴水平向右,y轴垂直向上pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);//矩形与客户区重合if(!bFill)DrawPolygon(pDC);//绘制多边形elseFillPolygon(pDC);//填充多边形ReleaseDC(pDC);//释放DC}3)绘制多边形边界函数DrawPolygon()voidCTestView::DrawPolygon(CDC*pDC)//绘制多边形边界{CLine*line=newCLine;CP2t;for(inti=0;i<7;i++)//绘制多边形{if(i==0){line->MoveTo(pDC,P[i]);t=P[i];}else{line->LineTo(pDC,P[i]);}}line->LineTo(pDC,t);//闭合多边形deleteline;}4)填充多边形函数FillPolygon()voidCTestView::FillPolygon(CDC*pDC)//填充多边形{for(inti=0;i<7;i++)//转储顶点坐标,y坐标取为整数{P1[i].x=P[i].x;P1[i].y=Round(P[i].y);P1[i].c=CRGB(bRed/255.0,bGreen/255.0,bBlue/255.0);}CFill*fill=newCFill;//动态分配内存fill->SetPoint(P1,7);//初始化Fill对象fill->CreateBucket();//建立桶表fill->CreateEdge();//建立边表fill->Gouraud(pDC);//填充多边形deletefill;//撤销内存}5)菜单函数voidCTestView::OnDrawpic(){//TODO:AddyourcommandhandlercodehereCOLORREFGetClr=RGB(0,0,0);//调色板颜色CColorDialogccd(GetClr,CC_SOLIDCOLOR);if(IDOK==ccd.DoModal())//调用颜色对话框选取填充色GetClr=ccd.GetColor();elsereturn;bRed=GetRValue(GetClr);//获取红色分量bGreen=GetGValue(GetClr);//获取绿色分量bBlue=GetBValue(GetClr);//获取蓝色分量bFill=TRUE;Invalidate();}实验地点专业软件实验室指导教师李丽亚
CAET**pPre=&pHeadE;
for(intj=0;j{pT2=pT1->pNext;if((pT1->x>pT2->x)||((pT1->x==pT2->x)&&(pT1->k>pT2->k))){pT1->pNext=pT2->pNext;pT2->pNext=pT1;*pPre=pT2;pPre=&(pT2->pNext);//调整位置为下次遍历准备}else{pPre=&(pT1->pNext);pT1=pT1->pNext;}}}}voidCFill::ClearMemory()//安全删除所有桶与桶上连接的边{DeleteAETChain(pHeadE);CBucket*pBucket=pHeadB;while(pBucket!=NULL)//针对每一个桶{CBucket*pBucketTemp=pBucket->pNext;DeleteAETChain(pBucket->pET);deletepBucket;pBucket=pBucketTemp;}pHeadB=NULL;pHeadE=NULL;}voidCFill::DeleteAETChain(CAET*pAET){while(pAET!=NULL){CAET*pAETTemp=pAET->pNext;deletepAET;pAET=pAETTemp;}}4.修改CTestview类1).定义了ReadPoint()函数voidCTestView::ReadPoint()//点表{P[0].x=50;P[0].y=100;P[1].x=-150;P[1].y=300;P[2].x=-250;P[2].y=50;P[3].x=-150;P[3].y=-250;P[4].x=0;P[4].y=-50;P[5].x=100;P[5].y=-250;P[6].x=300;P[6].y=150;}2)绘制图形函数DrawGraph()voidCTestView::DrawGraph()//绘制图形{CRectrect;//定义客户区GetClientRect(&rect);//获得客户区的大小CDC*pDC=GetDC();//定义设备上下文指针pDC->SetMapMode(MM_ANISOTROPIC);//自定义坐标系pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口比例pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区比例,且x轴水平向右,y轴垂直向上pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);//矩形与客户区重合if(!bFill)DrawPolygon(pDC);//绘制多边形elseFillPolygon(pDC);//填充多边形ReleaseDC(pDC);//释放DC}3)绘制多边形边界函数DrawPolygon()voidCTestView::DrawPolygon(CDC*pDC)//绘制多边形边界{CLine*line=newCLine;CP2t;for(inti=0;i<7;i++)//绘制多边形{if(i==0){line->MoveTo(pDC,P[i]);t=P[i];}else{line->LineTo(pDC,P[i]);}}line->LineTo(pDC,t);//闭合多边形deleteline;}4)填充多边形函数FillPolygon()voidCTestView::FillPolygon(CDC*pDC)//填充多边形{for(inti=0;i<7;i++)//转储顶点坐标,y坐标取为整数{P1[i].x=P[i].x;P1[i].y=Round(P[i].y);P1[i].c=CRGB(bRed/255.0,bGreen/255.0,bBlue/255.0);}CFill*fill=newCFill;//动态分配内存fill->SetPoint(P1,7);//初始化Fill对象fill->CreateBucket();//建立桶表fill->CreateEdge();//建立边表fill->Gouraud(pDC);//填充多边形deletefill;//撤销内存}5)菜单函数voidCTestView::OnDrawpic(){//TODO:AddyourcommandhandlercodehereCOLORREFGetClr=RGB(0,0,0);//调色板颜色CColorDialogccd(GetClr,CC_SOLIDCOLOR);if(IDOK==ccd.DoModal())//调用颜色对话框选取填充色GetClr=ccd.GetColor();elsereturn;bRed=GetRValue(GetClr);//获取红色分量bGreen=GetGValue(GetClr);//获取绿色分量bBlue=GetBValue(GetClr);//获取蓝色分量bFill=TRUE;Invalidate();}实验地点专业软件实验室指导教师李丽亚
pT2=pT1->pNext;
if((pT1->x>pT2->x)||((pT1->x==pT2->x)&&(pT1->k>pT2->k)))
pT1->pNext=pT2->pNext;
pT2->pNext=pT1;
*pPre=pT2;
pPre=&(pT2->pNext);//调整位置为下次遍历准备
pPre=&(pT1->pNext);
ClearMemory()//安全删除所有桶与桶上连接的边
DeleteAETChain(pHeadE);
CBucket*pBucket=pHeadB;
while(pBucket!
=NULL)//针对每一个桶
CBucket*pBucketTemp=pBucket->pNext;
DeleteAETChain(pBucket->pET);
deletepBucket;
pBucket=pBucketTemp;
DeleteAETChain(CAET*pAET)
{while(pAET!
{CAET*pAETTemp=pAET->pNext;
deletepAET;
pAET=pAETTemp;}}
1).定义了ReadPoint()函数
voidCTestView:
ReadPoint()//点表
P[0].x=50;P[0].y=100;
P[1].x=-150;P[1].y=300;
P[2].x=-250;P[2].y=50;
P[3].x=-150;P[3].y=-250;
P[4].x=0;P[4].y=-50;
P[5].x=100;P[5].y=-250;
P[6].x=300;P[6].y=150;
2)绘制图形函数DrawGraph()
DrawGraph()//绘制图形
CRectrect;//定义客户区
GetClientRect(&rect);//获得客户区的大小
CDC*pDC=GetDC();//定义设备上下文指针
pDC->SetMapMode(MM_ANISOTROPIC);//自定义坐标系
pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口比例
pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区比例,且x轴水平向右,y轴垂直向上
pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点
rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);//矩形与客户区重合
if(!
bFill)
DrawPolygon(pDC);//绘制多边形
FillPolygon(pDC);//填充多边形
ReleaseDC(pDC);//释放DC
3)绘制多边形边界函数DrawPolygon()
DrawPolygon(CDC*pDC)//绘制多边形边界
CLine*line=newCLine;
CP2t;
for(inti=0;i<7;i++)//绘制多边形
{if(i==0)
{line->MoveTo(pDC,P[i]);
t=P[i];}
{line->LineTo(pDC,P[i]);}}
line->LineTo(pDC,t);//闭合多边形
deleteline;}
4)填充多边形函数FillPolygon()
FillPolygon(CDC*pDC)//填充多边形
{for(inti=0;i<7;i++)//转储顶点坐标,y坐标取为整数
{P1[i].x=P[i].x;
P1[i].y=Round(P[i].y);
P1[i].c=CRGB(bRed/255.0,bGreen/255.0,bBlue/255.0);}
CFill*fill=newCFill;//动态分配内存
fill->SetPoint(P1,7);//初始化Fill对象
fill->CreateBucket();//建立桶表
fill->CreateEdge();//建立边表
fill->Gouraud(pDC);//填充多边形
deletefill;//撤销内存
5)菜单函数
OnDrawpic()
//TODO:
Addyourcommandhandlercodehere
COLORREFGetClr=RGB(0,0,0);//调色板颜色
CColorDialogccd(GetClr,CC_SOLIDCOLOR);
if(IDOK==ccd.DoModal())//调用颜色对话框选取填充色
GetClr=ccd.GetColor();
bRed=GetRValue(GetClr);//获取红色分量
bGreen=GetGValue(GetClr);//获取绿色分量
bBlue=GetBValue(GetClr);//获取蓝色分量
bFill=TRUE;
Invalidate();
实验地点
专业软件实验室
指导教师
李丽亚
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1