Region Fill Algorithm
one. Objective:
Master the basic principle and realization of ordered table method, understand simple interactive technology. two. Requirements:
1. Boundary seed interaction input;
2. The example contains a concave-convex polygon type;
3. Support color selection, pattern editing. three. Content:
1. Realization of Ordered table method;
Find out the maximum minimum xmin,xmax,ymax,ymin of the transverse ordinate of the intersection point (x1,y1) of the scan line and the polygon each side. Using the maximum minimum value of the transverse ordinate of each side point of the finding, a table (float m_ymax[n],m_ymin[n],m_xa[n],m_dx[n]) is arranged from small to large, and then the polygon is filled according to this table. Some of these function descriptions:
void Ccgfqlinedemoview::p fillscan (cdc* PDC)
void FillPolygon (int n, cpoint *points, CDC *PDC)//table method implementation
void Ploadpolygon (int pnumbers,cpoint *points)//Polygon Loading
void Pinsertline (float x1, float y1,float x2, float y2)/find intersection
void Pinclude ();
void Pupdatexvalue ();
void Pxsort (intbegin, int i)//Set up ordered table, sort each intersection size 2. Implement seed filling algorithm:
Algorithm principle:
(1) top pixel out stack;
(2) filling the left and right pixels of the stack pixel along the scan line until the boundary pixel is encountered, that is, the entire interval containing the pixel is filled with a pixel per stack;
(3) The leftmost and the most right pixels in the above range are recorded as X1 and X2 respectively;
(4) in the interval [x1,x2], check whether the pixels of the upper and lower scan lines adjacent to the current scan line are all boundary pixels or filled pixels, and if there are non boundary and unfilled pixels, the right pixel of each interval is taken as the seed pixel into the stack.
The implementation function of the algorithm is void Scanlinefill (cdc* PDC, CPoint point, int color0)
Four. Key code: (1) void Ccgwp_fqlinedemoview::onmousemove (UINT nflags,cpoint point)
void Ccgwp_fqlinedemoview::onmousemove (UINT nflags, CPoint point)
{
//todo:add your message handler code here d/or Call Default
if (m_pnumbers) {
m_pdc->setrop2 (2);
M_pdc->moveto (M_paccord[m_pnumbers-1]);
M_pdc->lineto (m_mousepoint);
M_mousepoint = point;
M_pdc->moveto (M_paccord[m_pnumbers-1]);
M_pdc->lineto (M_mousepoint);
}
Cview::onmousemove (nflags, point);
(2) void Ccgwp_fqlinedemoview::onlbuttondown (UINT nflags,cpoint point)
void Ccgwp_fqlinedemoview::onlbuttondown (UINT nflags, CPoint point)
{
//todo:add your message handler code here and/or call default
ccgwp_fqlinedemodoc* PDoc = (ccgwp_fqlinedemodoc*) getdocument ();
if (pdoc->sign) {
if (M_pnumbers < N) {
m_paccord[m_pnumbers] = point;
m_pnumbers++;
M_mousepoint = point;
}
}
else{
m_temppoint = point;
if (Pdoc->seedfillmode)
Ccgwp_fqlinedemoview::scanlinefill (M_PDC, M_temppoint,rgb (0,0,255));
Cview::onlbuttondown (nflags, point);
(3) void Ccgwp_fqlinedemoview::onlbuttondblclk (UINT nflags, Cpointpoint)
void Ccgwp_fqlinedemoview::onlbuttondblclk (UINT nflags, CPoint point)
{
//todo:add Your message Handler code he Re and/or call default
ccgwp_fqlinedemodoc* PDoc = (ccgwp_fqlinedemodoc*) getdocument ();
if (pdoc->sign)
{
m_pdc->moveto (m_paccord[m_pnumbers-1]);
M_pdc->lineto (M_paccord[0]);
M_paccord[m_pnumbers] = m_paccord[0];
m_pnumbers++; The value at this point is the number of vertices plus 1
sprintf (stringnumber, "%d", m_pnumbers-1);
M_pdc->textout (100,200,stringnumber);
FillPolygon (M_pnumbers, M_paccord, M_PDC);
m_pnumbers = 0; Prevents the mouse from dragging when underlining
cview::onlbuttondblclk (nflags, point);
}
(4) void Ccgwp_fqlinedemoview::fillpolygon (int n, CPoint *points, CDC*PDC)
void Ccgwp_fqlinedemoview::fillpolygon (int n, cpoint *points, CDC *pdc)
{ccgwp_fqlinedemodoc*
pDoc = (ccgwp_ fqlinedemodoc*) getdocument ();
m_edgenumbers = 0;
Ploadpolygon (n, points),//Load polygon, record M_ymax[n],m_ymin[n],m_xa[n],m_dx[n] to record each edge
m_begin = m_end = 0;
M_scan = (int) m_ymax[0];
Pinclude ();
m_xa[n value while
(M_begin!= m_end) {
Pfillscan (PDC)
for Pupdatexvalue (); m_scan--;
Pinclude ();
Pupdatexvalue ();
} Enter the loop when the number of edges is not equal to the number of sides that have been deleted
(5) void Ccgwp_fqlinedemoview::p loadpolygon (Intpnumbers,cpoint *points)
void Ccgwp_fqlinedemoview::p loadpolygon (int pnumbers,cpoint *points)
{
float x1,y1,x2,y2;
x1 = points[0].x; y1 = points[0].y+0.5;
for (int i = 1; i < pnumbers i++) {
x2 = points[i].x; y2 = points[i].y+0.5;
if (y1-y2)
pinsertline (x1,y1,x2,y2);
x1 = x2; y1 = y2;
}
(6) void Ccgwp_fqlinedemoview::p insertline (floatx1, float y1,float x2, float y2)
void Ccgwp_fqlinedemoview::p insertline (float x1, float y1,
float x2, float y2)
{
int i;
float ymax,ymin;
ymax = (y2 > y1)? Y2: y1;
Ymin = (y2 < y1)? Y2:y1;
i = m_edgenumbers;
while (i > 0 && ymax > m_ymax[i-1]) {
m_ymax[i] = m_ymax[i-1];
M_ymin[i] = m_ymin[i-1];
M_dx[i] = m_dx[i-1];
M_xa[i] = m_xa[i-1];
i--;
}
M_ymax[i] = Ymax;
M_ymin[i] = ymin;
if (y2 > y1) m_xa[i] = x2;
else m_xa[i] = x1;
M_dx[i] = (x1-x2)/(y2-y1);
m_edgenumbers++;
}
(7) Void Ccgwp_fqlinedemoview::p include ()
void Ccgwp_fqlinedemoview::p include ()
{while
(M_end < m_edgenumbers && M_ymax[m_end] > M_scan) {
M_xa[m_end] = m_xa[m_end]-0.5 * m_dx[m_end];
m_end++
}
}
(8) void Ccgwp_fqlinedemoview::p updatexvalue ()
void Ccgwp_fqlinedemoview::p updatexvalue ()
{
int i,start = M_begin;
for (i = START I < m_end i++) {
if (M_scan > M_ymin[i]) {
M_xa[i] + = M_dx[i];
Pxsort (M_begin, i);
} else {for
(int j = i; j > m_begin; j--)
{
m_ymin[j] = m_ymin[j-1];
M_XA[J] = m_xa[j-1];
M_DX[J] = m_dx[j-1];
}
m_begin++
}}
}
(9) void Ccgwp_fqlinedemoview::p xsort (intbegin, int i)
void Ccgwp_fqlinedemoview::p xsort (int Begin, int i)
{
float temp;
while (i > Begin && m_xa[i] < m_xa[i-1]) {
temp = m_xa[i];
M_xa[i] = m_xa[i-1];
M_XA[I-1] = temp;
temp = M_ymin[i];
M_ymin[i] = m_ymin[i-1];
M_YMIN[I-1] = temp;
temp = M_dx[i];
M_dx[i] = m_dx[i-1];
M_DX[I-1] = temp;
i--
}
}
(a) Voidccgwp_fqlinedemoview::p fillscan (cdc* PDC)
void Ccgwp_fqlinedemoview::p fillscan (cdc* PDC)
{
int x=0,y=0;
ccgwp_fqlinedemodoc* PDoc = (ccgwp_fqlinedemodoc*) getdocument ();
if (Pdoc->seedfillmode = = 0) {
pdc->setrop2);
for (int i = M_begin I < m_end i + 2) {
if (pdoc->solidfillmode) {
Pdc->moveto (m_xa[i ), M_scan); 9/>pdc->lineto (m_xa[i+1], m_scan);
} else {
y = M_scan;
for (int x = m_xa[i]; x < m_xa[i+1], + x)
if (m_patterndata[y%7][x%6])
pdc->setpixel (x, Y, RGB (0,0,255));
}
}
}
}
(one) void Ccgwp_fqlinedemoview::onrbuttondown (Uintnflags, CPoint Point)
void Ccgwp_fqlinedemoview::onrbuttondown (UINT nflags, CPoint point)
{
//todo:add Your message Handler code he Re and/or call default
ccgwp_fqlinedemodoc* PDoc = (ccgwp_fqlinedemodoc*) getdocument ();
Pdoc->sign =!pdoc->sign;
Cview::onrbuttondown (nflags, point);
(a) void Ccgwp_fqlinedemoview::scanlinefill (CDC*PDC, CPoint point, int color0)
void Ccgwp_fqlinedemoview::scanlinefill (cdc* PDC, CPoint point, int color0) {ccgwp_fqlinedemodoc* PDoc = (ccgwp_fqline
demodoc*) getdocument ();
int clr,color;
int X,y,x0,y0,xl,xr,flag,xnextspan;
istack=0;
PDC->SETROP2 (10);
X=point.x;
Y=point.y;
Y0=y;
Push (X,y);
Color=pdc->setpixel (X,Y,COLOR0);
while (Istack >0) {pop (x,y);
Clr=pdc->setpixel (X,y,rgb (255,0,255));
x0=x+1;
while (Pdc->getpixel (x0,y)!=color) {Pdc->setpixel (X0,y,rgb (255,0,255));
x0++; } xr=x0-1;
the right pixel x0=x-1;
while (Pdc->getpixel (x0,y)!=color) {Pdc->setpixel (X0,y,rgb (255,0,255));
x0--; } xl=x0+1;
leftmost pixel X0=XL;
y=y+1;
while (X0<=XR) {flag=0; while (Pdc->getpixel (x0,y)!=color && pdc->getpixel (x0,y)!=clr && x0<xr) {if (flag
==0) flag=1;
x0++; } if (flag==1) {if (X0==XR && pdc->getpixel (x0,y)!=color && pdc->getpixel (x0,y)!=c LR) push (x0,y);
else push (x0-1,y);
flag=0;
} xnextspan=x0;
while (Pdc->getpixel (x0,y) ==color | |
Pdc->getpixel (x0,y) ==clr && x0<=xr) x0++;
if (xnextspan==x0) x0++;
} X0=XL;
Y=y-2;
while (X0<=XR) {flag=0; while (Pdc->getpixel (x0,y)!=color && pdc->getpixel (x0,y)!=clr && x0<xr) {if (flag
==0) flag=1;
x0++; } if (flag==1) {if (X0==XR && pdc->getpixel (x0,y)!=color && pdc->getpixel (x0,y)!=c
LR) push (x0,y);
else push (x0-1,y);
flag=0;
} xnextspan=x0;
while (Pdc->getpixel (x0,y) ==color | |
Pdc->getpixel (x0,y) ==clr && x0<=xr) x0++;
if (xnextspan==x0) x0++;
}
}
}
(Voidccgwp_fqlinedemoview)::p ush (int x, int y)
void Ccgwp_fqlinedemoview::p ush (int x, int y)
{
if (istack>1000) return
;
else
{
istack++;
stackx[istack]=x;
Stacky[istack]=y
}
}
(Intccgwp_fqlinedemoview)::p op (int &x, int &y)
int Ccgwp_fqlinedemoview::p op (int &x, int &y)
{
if (istack<=0) return-1;
X=stackx[istack];
Y=stacky[istack];
istack--;
return istack;
} <strong>
</strong>
Five. Results and Analysis:
1. Ordered table-editing method:
2. Seed Line Scanning method:
to generate a polygon:
through the comparison, the sequential table method is more efficient and the seed filling algorithm is more flexible.