In this section, we're talking about the filling of the closed curve, why do we have this thing?
When we recursive a scene, we use to push the box as a sign, if not push the box, then run to the white run, and the repetition of the judgement is the best is the same coordinates
Including these coordinates interchange position (the same sort result), then one scene porter coordinates can move to another scene Porter's position (solve the algorithm part again detailed say)
Since the scene has more than one box, each box can be moved in several directions, the repeated search efficiency is not high, at first I want to delete the path part, only detect can be moved to the target
To improve the efficiency of execution, is to lazy, and then think that since it is a gift, lazy is not a time, also a face to others then abandoned the AX algorithm
The goal is very obvious, the calibration all can reach the position, the detection time does not have to seek his sister's road, directly detects whether is filled can
So how do you fill a closed curve? The simplest logic is:
1. In the surrounding 4 or 8 directions, record all the points that are not boundaries, are not filled, and fill
2. Recursively these points until no new points are detected
Recursion, recursion, is this self-delivery? Sin! The wicked recursion, the poor stack ...
The implementation of the above method is very simple, but a lot of points will be repeatedly detected several times, the efficiency is not too high
Another approach is what we're talking about: Scan line seed fill algorithm
The main logical ideas are:
1. Change coordinates to line segments, record leftmost and most right breakpoints, fill segments, join queues (instead of recursion)
2. Fill in the queue first, check the previous line and the next line, add the adjacent segments, remove from the queue
3. Repeat 1-2 until the queue does not have any line segments
Example source code, see Resources for details
Scan line fills (with loops instead of recursion, players must be within the boundary closed curve) int Fnstagescan (Pqueue pqueue, Pstage pstage) {UINT x0, xl, XR, y0, XID; UINT flag;//, Cpstack s; Pstar p;//uint snum;union {UINT *pdata; BYTE *pnum;}; UINT X, Y;int i;//first clear 0 non-type bit Y = Pstage->sizex * pstage->sizey; X = Y% 4;pnum = Pstage->matrix;while (x--) {*pnum++ &= smt_filter;//qing 0 non-type information}y/= 4;while (y--) {*pdata++ &= SMT_M atrix;//Clear 0 Non-type information}//empty the stack, seed into the stack s = pqueue->stacks;p = S->stars;p->x = Pstage->posx;p->y = Pstage->posy;s ->count = 1; while (s->count) {X = p->x; Y = p->y;p--;s->count--;p num = &pstage->matrix[y * Pstage->sizex + x];*pnum |= SMT_OPENED;//Me.PSet (x0, Y), newvalue x0 = X + 1;pnum++; Fills the right side not the box nor the boundary of the Unit while ((*pnum & smt_masked) = = 0)//me.point (x0, Y) <> boundaryvalue{//if (x0 >= pSt Age->sizex) break;//to the far right (map control) *pnum |= smt_opened;pnum++; x0++;} XR = x0-1;//Right-most coordinate x0 = X-1;pnum = &pstage->matrix[y * Pstage->sizex + x0]; Fills the left side not the box nor the boundary of the Unit while ((*pnum & smt_masked) = = 0)//me.point (x0, Y) <> boundaryvalue{//if (x0 < 0) b reak;//to the leftmost (map control) *pnum |= smt_opened;pnum--; x0--;} XL = x0 + 1;//leftmost pixel//Check the previous scan line and the next scan line, if there are non-boundary and unfilled pixels, then select the seed pixels representing the successive intervals into the stack. y0 = Y; for (i = 1; I >=-1; I-= 2) {x0 = XR; Y = y0 + i; while (x0 >= xl) {flag = 0;//passes the unfilled point to the left until the boundary, recording the x-coordinate of the last point pnum = &pstage->matrix[y * Pstage->sizex + x0];//c = me.point (x0, Y)//while (((*pnum & smt_masked) = = 0) && ((*pnum & Amp smt_opened) = = 0) && (x0 >= XL) while (((*pnum & smt_opnmsk) = = 0) && (x0 >= xl)) {//(c <> Boundaryvalue) and (c <> newvalue) and (x0 >= XL) if (flag = = 0) {flag = 1; XID = x0;} pnum--;//C = me.point (x0, Y) x0--;} The rightmost filled pixel is pressed into the stack if (flag = = 1) {p++;p->x = Xid;p->y = y;s->count++;//S.push (point (Xid,y)); Flag = 0;} Check to see if the current fill line is interrupted, and if interrupted, look for the first filled pixel on the left pnum = &pstage->matrix[y * Pstage->sizex + x0];//c = me.point ( X0, Y) while (*pnum & Smt_opnmsk) {//(c = boundaryvalue) or (c = newvalue) ' Determines whether the current point is a boundary or a box or whether the current point is a filled point if (x0 = = 0) break;//to the far left (...) pnum--; x0--;//If the current point is a boundary point or a filled point, according to the previous judgment, the current point must not exceed the left edge, then the current point moves to the left}}//loop while (x0 >= XL)}//next for (i = 1; I >= -1; I-= 2)}//Loop while (!s.isempty ()) return 1;}
In order to store space, I only fill specific flag bits, queue fixed size, more compact structure, test execution effect:
Left ARROW to draw the end of the segment, right click on any one of the points within the closed curve is filled complete, see resource bundle.
To the news: Push box game automatic solution algorithm design (III.)