Polygon Area filling algorithm-scanning line Seed Filling Algorithm

Source: Internet
Author: User

Http://blog.csdn.net/orbit/article/details/7343236

1.3 scanning line Seed Filling Algorithm

The two seed filling algorithms described in sections 1.1 and 1.2 have the advantage of being very simple. The disadvantage is that recursive algorithms are used, which not only requires a large amount of stack space to store adjacent points, and the efficiency is not high. In order to reduce recursive calls in algorithms and reduce stack space usage, many improved algorithms are proposed, one of which is the scanning line Seed Filling Algorithm. The scanning line Seed Filling Algorithm no longer uses recursion to process the adjacent points of "4-Unicom" and "8-Unicom", but fills the pixel segment along the horizontal scanning line, process the adjacent points of "4-China Unicom" and "8-China Unicom" in a segment. In this way, you only need to press the starting point of each horizontal pixel segment into a special stack during algorithm processing, instead of pushing all adjacent points not processed around the current position into the stack like a recursive algorithm, this saves stack space. It should be said that the scanning line Filling Algorithm is just an idea to avoid recursion and improve efficiency. The Injection Filling Algorithm and the boundary Filling Algorithm mentioned above can be improved to the scanning line filling algorithm, the following describes the scanning line Seed Filling Algorithm combined with the boundary filling algorithm.

The basic process of the scanning line Seed Filling Algorithm is as follows: when the seed point (X, Y) is given, first, fill in the scanning line of the seed point in the left and right directions, respectively, a section in the given area, and write down the range of this section [xleft, xright], then, determine the upper and lower scanning lines that are connected to the CIDR block, and save them in sequence. Repeat this process until the filling ends.

The scanning line Seed Filling Algorithm can be implemented in the following four steps:

 

(1) Initialize an empty stack to store the seed points and import the seed points (x, y) into the stack;

 

(2) judge whether the stack is empty. If the stack is empty, end the algorithm. Otherwise, the top element of the stack is taken out as the seed point (x, y) of the current scanning line, and Y is the current scanning line;

 

(3) starting from the seed point (x, y), fill in the left and right directions along the current scanning line until the boundary. The coordinates of the left and right endpoints of the CIDR blocks are xleft and xright respectively;

 

(4) Check the pixels of the Y-1 and Y + 1 scanning lines adjacent to the current scanning line in the range [xleft, xright], and search for the lines from xleft to xright, if there are non-boundary and unfilled pixels, find the rightmost of these adjacent pixels and press them into the stack as the seed points, and then return step (2;

 

The most important part of this algorithm is step (4), which is to find a new seed point from the first and next scanning lines of the current scanning line. What is hard to understand here is why we only check the pixels in the new scan online range [xleft, xright? What if the actual range of the new scanning line is larger (and discontinuous) than this range? I have checked many books and papers on computer graphics, and I have not provided any special instructions on this. This makes many people have lingering doubts about this course. With the idea of "destroying people", this article will explain it and hope to lift everyone's doubts.

If the range of the actual points on the New Scan Line is greater than the [xleft, xright] range of the current scan line, and the interval is continuous, the (3) step of the algorithm handles this situation. (4:

Figure (4) Increase and continuity of the new scanning line range

Assuming that the scanned line currently processed is the first row of the yellow point, a Range [6, 10] can be obtained after Step 1 processing. Then, in step 2, search right from the 4th columns of the adjacent lines 6th and 8th, and then confirm that the two red points are the seeds of the 6th and 6th rows, respectively, then, two seed points (6, 10) and (8, 10) are added to the stack in order. The next loop will process (8, 10) This seed point. According to step 4 of the algorithm, it will be filled to the left and right from (8, 10), because there is no border point in the middle, therefore, it will be filled until the boundary is met. Therefore, although the actual area of the 8th rows is larger than the range [6, 10] of the 7th rows, it is still correctly filled.

If the range of the actual points on the new scanning line is larger than the [xleft, xright] range of the current scanning line, and there is a boundary point in the middle, how does the algorithm deal with it? Although there is no clear method to deal with this situation in the algorithm description, the method for determining the seed points of the upper and lower adjacent scanning lines in step 1 and the principle of right-clicking are also described, in fact, it implies a method to bypass obstacle points from adjacent scanning lines. The following figure uses (5) as an example:

Figure (5) increase of new scanning line interval and discontinuous

After processing 3rd rows in step 1, the algorithm determines the range [7, 9]. Although the actual range of the adjacent 5th rows is larger than that of the range [7, 9, 6) This boundary blocks the position so that after determining the seed point (4, 9), you can fill the left with only the area between the 7th and 10th columns on the right, the area between columns 3rd and columns 5th on the left is not filled. Although it is an adjacent row of 5th rows, the first scan of 4th rows only determines (4, 9) A seed point based on the right principle. However, after processing the 3rd rows, the left part of the 4th rows serves as the adjacent row under the 3rd rows, and the scanning opportunity is obtained again. The range of the fifth row is [3, 9], and the obstacle point of the Fifth Column is crossed to the left. When the fifth row is scanned for 3rd Times, it starts from column 6th and searches to the right, you can determine the seed point (4,
5 ). In this way, there are two seed points in the 4th rows, and they can be completely filled.

It can be seen that for a row with a barrier point, the link between adjacent edges can span the barrier point and complete filling can be obtained through multiple scans. The algorithm has implicitly processed this situation. According to the four steps summarized in this section, the implementation of the scanning line Seed Filling Algorithm is as follows:

263 void scanlineseedfill (int x, int y, int new_color, int boundary_color)

264 {

265 STD: Stack <point> STK;

266

267 STK. Push (point (x, y); // step 2, seed point inbound

268 while (! STK. Empty ())

269 {

270 point seed = STK. Top (); // step 3, obtain the current seed point

271 STK. Pop ();

272

273 // step 2, fill in to left and right

274 int COUNT = filllineright (seed. X, seed. Y, new_color, boundary_color); // to 'cf? Right 'd3? Fill in 'CC? Fill 'b3?

275 int xright = seed. x + count-1;

276 COUNT = filllineleft (seed. X-1, seed. Y, new_color, boundary_color); // to 'cf? 'D7? Fill in 'CC? Fill 'b3?

277 int xleft = seed. X-count;

278

279 // Step 2: process two adjacent scanning lines

280 searchlinenewseed (STK, xleft, xright, seed. Y-1, new_color, boundary_color );

281 searchlinenewseed (STK, xleft, xright, seed. Y + 1, new_color, boundary_color );

282}

283}

The filllineright () and filllineleft () functions fill the color from the right and left of the seed points until the border points are met, and return the number of filled points. These two functions return the number of fill points to adjust the range of the scanning line where the current seed point is located [xleft, xright]. The searchlinenewseed () function completes the operations described in step 1 of the algorithm, that is, it searches for the seed points on the new scanning line and adds the seed points to the stack, the interval of the new scan line is determined by the xleft and xright parameters:

234 void searchlinenewseed (STD: Stack <point> & STK, int xleft, int xright,

235 int y, int new_color, int boundary_color)

236 {

237 int XT = xleft;

238 bool findnewseed = false;

239

240 while (XT <= xright)

241 {

242 findnewseed = false;

243 while (ispixelvalid (XT, Y, new_color, boundary_color) & (XT <xright ))

244 {

245 findnewseed = true;

246 XT ++;

247}

248 If (findnewseed)

249 {

250 if (ispixelvalid (XT, Y, new_color, boundary_color) & (XT = xright ))

251 STK. Push (point (XT, y ));

252 else

253 STK. Push (point (XT-1, y ));

254}

255

256/* skip the inactive point to the right (when there is an obstacle point on the right side of the processing range )*/

257 int xspan = skipinvalidinline (XT, Y, xright, new_color, boundary_color );

258 XT + = (xspan = 0 )? 1: xspan;

259/* handle special cases to exit the while (x <= xright) loop */

260}

261}

 

The while loop of the outermost layer is used to ensure that the right end of the interval [xleft, xright] is separated into multiple segments by obstacle points, which can be correctly processed through the outer while loop, you can ensure that a seed point is found for each segment (for the condition of the obstacle point on the left end of the interval, see the example shown in figure (5), which is implicitly completed in the algorithm ). The while loop in the inner layer is only used to find a filling point at the rightmost of each segment as the seed point. The skipinvalidinline () function is used to skip the obstacle points in the interval and determine the start position of the next separator. The last line of code in the loop is a bit strange. In fact, it only uses a small "trick" to ensure that the loop can exit correctly when a real boundary point is encountered. This is not a commendable practice. There is a better way to implement such software control. The purpose of this article is to make the code brief and let readers focus on the algorithm processing logic, rather than complex and difficult cycle control conditions.

The implementation of the algorithm is actually in the scanlineseedfill () and searchlinenewseed () functions. The mysterious scanning line Seed Filling Algorithm is not complex, right? So far, we have already introduced several common seed filling algorithms. Next we will introduce two filling algorithms suitable for vector image area filling, namely the scanning line algorithm and the edge sign filling algorithm, note that the scanning line Filling Algorithm Suitable for vector graphics is sometimes called the "ordered edge table method", which is different from the scanning line Seed Filling Algorithm.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.