Scanning line-General polygon Filling Algorithm
The algorithm has the following learning points:
(1) Positive and Negative 1 Thoughts
(2) Processing of Boundary Conditions
(3) Data Structure Selection
Code:
Sweep. h
# Ifndef sweep_h
# Define sweep_h
Struct edge {
Int nxty;
Int curx;
Int dx, Dy; // increment of the scanning line
Edge * NXT;
};
// Scan Line main Algorithm
Void sweep (int p [] [2], int N, void (* setpixel) (INT, INT ));
# Endifsweep. cpp
# Include "sweep. H"
# Include <algorithm>
Using namespace STD;
Const int maxn = 1024;
Int CP [maxn] [2], N;
Inline bool CMP (int I, Int J ){
Return CP [I] [1] <CP [J] [1] | (CP [I] [1] = CP [J] [1] & CP [I] [0] <CP [J] [0]);
}
Edge * E [maxn], * H, * pH, * data;
Void insert (INT ly, int PX, int IND ){
Int Y1, Y2, Y, NXT, pre, flag = 0;
NXT = (IND + 1) % N; Pre = (Ind-1 + n) % N;
Y = CP [ind] [1]; Y1 = CP [NXT] [1]; y2 = CP [pre] [1];
If (Y1> Y2) Swap (Y1, Y2 );
If (Y1 <Y & Y <Y2 ){
// A unit must be shortened.
Flag = 1;
}
H = E [ly]; pH = NULL;
While (h ){
If (H-> dy> CP [ind] [1] | (H-> DY = CP [ind] [1] & H-> DX> CP [ind] [0]) break;
PH = h;
H = H-> NXT;
}
Data = new edge;
Data-> curx = px; data-> nxty = CP [ind] [1]; data-> dx = CP [ind] [0]-Px; data-> DY = CP [ind] [1]-ly; data-> NXT = NULL;
If (FLAG) Data-> nxty --;
If (ph ){
Data-> NXT = Ph-> NXT;
Ph-> NXT = data;
} Else {
Data-> NXT = E [ly];
E [ly] = data;
}
}
Int ex [maxn] [maxn], ne [maxn];
Inline int ABS (int ){
Return a> 0? A:-;
}
Void makepoint (INT line, edge * h ){
Int dx = H-> dx, dy = H-> dy, CNT = 0;
Int X, Y, flag = 1;
If (h-> dx) * (H-> Dy) <0) Flag = 0;
For (y = line, x = H-> curx; y <= H-> nxty; y ++ ){
Ex [y] [NE [y] ++] = X;
CNT + = 2 * ABS (dx );
While (CNT> = 2 * ABS (dy )){
CNT-= 2 * ABS (dy );
If (FLAG) x ++;
Else X --;
}
}
}
Void sweep (int p [] [2], int NN, void (* setpixel) (INT, INT )){
// Sort all vertices in ascending order of Y coordinates, and sort all vertices in ascending order of Y coordinates.
N = nn;
Int I, J, K, IND, NXT, pre;
Int * num = new int [N]; // vertex index;
For (I = 0; I <n; I ++) num [I] = I;
Memcpy (CP, P, sizeof (CP ));
Sort (Num, num + N, CMP );
// Create an ordered edge table
Memset (E, 0, sizeof (e ));
For (I = 0; I <n; I ++ ){
IND = num [I];
NXT = (IND + 1) % N;
Pre = (Ind-1 + n) % N;
If (P [NXT] [1]> P [ind] [1]) insert (P [ind] [1], p [ind] [0], NXT );
If (P [pre] [1]> P [ind] [1]) insert (P [ind] [1], p [ind] [0], pre );
}
// Process the active edge list
Memset (ne, 0, sizeof (NE ));
For (I = 0; I <maxn; I ++ ){
H = E [I]; pH = NULL;
While (h ){
Makepoint (I, H );
H = H-> NXT;
}
Sort (ex [I], ex [I] + NE [I]);
For (j = 0; j <ne [I]; j + = 2)
For (k = ex [I] [J]; k <= ex [I] [J + 1]; k ++)
Setpixel (K, I );
}
} Sweepline. cpp
# Include <stdlib. h>
# Include <stdio. h>
# Include <Gl/glut. h>
# Include "sweep. H"
Void myinit ();
Void setpixel (int x, int y );
Void mydisplay ();
Int main (INT argc, char ** argv ){
Gluinit (& argc, argv );
Fig );
Gluinitwindowsize (640,480 );
Gluinitwindowposition (100,150 );
Glucreatewindow ("sweepline ");
Gludisplayfunc (mydisplay );
Myinit ();
Glumainloop ();
Return 0;
}
Void setpixel (int x, int y ){
Glbegin (gl_points );
Glvertex2i (x, y );
Glend ();
}
Void myinit (){
Glclearcolor (1.0, 1.0, 1.0, 0.0 );
Glcolor3f (0.0, 0.0, 0.0 );
Glmatrixmode (gl_projection );
Glloadidentity ();
Gluortho2d (0.0, 640.0, 0.0, 480.0 );
}
Void mydisplay (){
Int I, J;
Glclear (gl_color_buffer_bit );
Int P [5] [2];
P [0] [0] = 100; P [0] [1] = 300;
P [1] [0] = 200; P [1] [1] = 50;
P [2] [0] = 300; P [2] [1] = 100;
P [3] [0] = 400; P [3] [1] = 0;
P [4] [0] = 350; P [4] [1] = 470;
Sweep (p, 5, setpixel );
Glflush ();
}
Http://zhidao.baidu.com/question/40582214.html