一直都想写这篇文章,由于我本身作实验的时候困扰了好久,网上貌似没看到彻底正确的代码,或许是我没有找到。这个的算法原本很简单,因此我这里并不叙述边界标志算法通常性的算法思想了,我只讨论实践中遇到的问题,因此看这篇文章以前,你最好已经明白边界标志算法的大体流程了。接下来就讨论一下:因为咱们要用到前面的算法画直线,以及原本在计算机上画图,就是一个近似的问题,因此这个算法实践时会遇到一些问题,其实就两个问题:c++
1.画多边形的边界时,必需要用斜率大于1的算法,不然会出错。缘由:你想一下,咱们是用扫描线去扫的,它是从y=1慢慢变大,每次遇到边界就flag取反,那么若是直线算法是很精确的讨论了斜率大于1和斜率小于1的状况时,在斜率小于1的时候就会出错。由于小于1的时候是x每次增长1,y有可能不变的,由于这是一个近似的过程,因此原本理论上一条扫描线上只有一个点的,实际上却在那一条扫描线上出现了好几个点,这样咱们取反就可能会出错。因此画边界时,必定要注意。算法
2.极值点要单独讨论。在说这个问题的解决方案时,我先说下我是怎么标记边界的,首先是我要画出要填色的多边形边界,而后呢,这时背景色和边界色确定就不同了!因此呢,就能够经过获取当前点的颜色来判断是不是边界。接下来,就讨论极值点的问题,咱们知道遇到极值点,虽然是边界,可是呢,flag不取反的,因此呢,咱们画好边界之后,将极值点涂为背景色就好了,这样就能够沿用之前的算法。函数
理解以上2点,基本上就没什么错误了,程序以下(估计你不能直接使用下面代码,由于我只贴出了主要部分,理解以上两点,你确定能写出来的!):spa
//主程序code
void CPadPolyView::OnDraw(CDC* pDC)
{
CPadPolyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
COLORREF color=RGB(0,0,0);
COLORREF clr,set=RGB(255,0,0);
int flag=-1;
//先把直线画了
for(int i=0;i<m_lc.m_dot.c;i=i+2)
{
DrawBresenham(p[i][0],p[i+1][0],p[i][1],p[i+1][1],color,pDC);
}
DrawExtreamPoint(pDC);
//获得全部点
for(i=ymin;i<=ymax;i++)
{
flag=-1;
for(int j=xmin;j<=xmax;j++)
{
clr=pDC->GetPixel(j,i);
if(flag==1)
{
pDC->SetPixel(j,i,set);rem
}
if(clr==color)
{
flag=-flag;
}
}
}
}float
//因此的边界都用斜率大于1的直线算法程序
void CPadPolyView::DrawBresenham(int x1,int x2,int y1,int y2,COLORREF color,CDC* pDC)
{
int flag=0;
float k;
k=(float)(x2-x1)/(float)(y2-y1);
flag=1;
float y=y1;
float x=x1;
int m_y1,m_y2;
if(y1==y2)
{
int xmax=x2;
x=x1;
if(x1>x2)
{
x=x2;
xmax=x1;
}
for(int i=x;i<xmax;i++)
{
pDC->SetPixel(i,y1,color);
}
}
else
{
if(y1>y2)
{
m_y1=y2;
m_y2=y1;
x=x2;
}
else
{
m_y1=y1;
m_y2=y2;
x=x1;
}
for(int i=m_y1;i<m_y2;i++)
{
pDC->SetPixel(int(x+0.5),i,color);
x=x+k;
}
}
}计算机
//将极值点涂为背景色解决方案
void CPadPolyView::DrawExtreamPoint(CDC* pDC)
{
int temp=m_lc.m_dot.ec;
COLORREF color=RGB(255,255,255);
for(int i=0;i<temp;i++)
{
pDC->SetPixel(ep[i][0],ep[i][1],color);
}
}
//计算极值点的函数
void CDot::GetExtremePoint() { ec=0; int x,y,tempy,temp; int flag=1; CString str; for(int i=0;i<c;i++) { x=p[i][0]; y=p[i][1]; tempy=p[i+flag][1];//第一条边的y flag=-flag; for(int j=i+1;j<c;j++) { if((p[j][0]==x)&&(p[j][1]==y)) { temp=j%2; if(temp==0) { temp=1; } else { temp=-1; } if(p[j+temp][1]>y)//其中一个点大于y { if(tempy>y)//都大于y,不算,是极值点 { ep[ec][0]=x; ep[ec][1]=y; ec++; } } else if(p[j+temp][1]<y) { if(tempy<y) { ep[ec][0]=x; ep[ec][1]=y; ec++; } } } } } }