Chapter Three Part II Output Primitives CH 3-P2 - 1 Outline • In this chapter the following topics are there: Part I: – Line drawing algorithms. – Circle generating algorithm – Ellipse generating algorithm Part II: – Filled-Area primitives. CH 3-P2 - 2 Different types of Polygons • Simple Convex • Simple Concave • Non-simple : self-intersecting Convex Concave Self-intersecting CH 3-P2 - 3 Filling 2D Shapes • How do we fill shapes? Solid Fill Pattern Fill Texture Fill CH 3-P2 - 4 Filled- Area Primitives A standard output primitive in general graphics packages is a solidcolor or patterned polygon area. There are two basic approaches to area filling on raster systems: 1. The scan-line approach - Determine the overlap intervals for scan lines that cross the area. - It is typically used in general graphics packages to fill polygons, circles, ellipses 2. Filling approaches (Boundary fill Algorithm) - Start from a given interior position and paint outward from this point until we encounter the specified boundary conditions. - Useful with more complex boundaries and in interactive painting systems. CH 3-P2 - 5 Scan-Line Fill Algorithm (cont.) 1. Find Minimum enclosed rectangle. 2. Find out number of scan lines in that rectangle. 3. For each scan line crossing a polygon, the area-fill algorithm locates the intersection points of the scan line with the polygon edges. 4. These intersection points are then sorted from left to right, and the corresponding frame-buffer positions between each intersection pair are set to the specified fill color. Minimum Enclosed rectangle CH 3-P2 - 6 Scan-Line Fill Algorithm(cont.) Generally, no. of intersection points between scan line and polygon edges are even numbers.(Some exceptions are there like if scan line is passing through vertex). Fill all the pixels within pairs. Intersection points are updated for each scan line. Stop when scan line has reached ymax. CH 3-P2 - 7 Special cases CH 3-P2 - 8 Scan line intersecting at vertex If scan line intersect at vertex then count that as a two intersections points. CH 3-P2 - 9 What is difference between scan line y and y’…? 1. 2. For scan line y, the edges at the intersection vertex are at the same side of scan line For scan line y’, the edges are on the either side of the vertex. Traverse along the polygon boundary clockwise or anticlockwise and observe the relative change in y-values of the edges on either side of the vertex (i.e. we move from one edge to another) If end points y values of two consecutive edges monotonic increase or decrease count the middle vertex as a single intersection point for the scan line passing through it. CH 3-P2 - 10 Another method for special case • One method for implementing the adjustment to the vertex intersection count is to shorten some polygon edges to split those vertices that should be counted as one intersection 1. When the end point y coordinates of the two edges are increasing , the y value of the upper endpoint for the current edge is decreased by 1 Current edge CH 3-P2 - 11 Scan Line Polygon Fill Algorithm • When the endpoint y values are monotonically decreasing, we decrease the y coordinate of the upper endpoint of the edge following the current edge Current edge CH 3-P2 - 12 Algorithm Steps for Scan-line Filling The scan conversion algorithm works as follows i. Find intersection points each scan-line with all edges ii. Sort intersection points in x-direction. iii. Make pairs of intersection points. iv. Fill the “in” pixels Special cases to be handled: i. Horizontal edges should be excluded ii. Vertices lying on scan-lines handled by shortening of edges, • Coherence between scan-lines tells us that Edges that intersect scan-line y are likely to intersect y + 1 X changes predictably from scan-line y to y + 1 (Incremental Calculation Possible) (Xk + 1, Yk + 1) (Xk , Yk ) Scan Line yk + 1 Scan Line yk CH 3-P2 - 13 • The slope of the edge is constant from one scan line to the next: – let m denote the slope of the edge. yk 1 yk 1 1 xk 1 xk m • Each successive x is computed by adding the inverse of the slope and rounding to the nearest integer CH 3-P2 - 14 Integer operations • Recall that slope is the ratio of two integers: y m x • So, incremental calculation of x can be expressed as y xk 1 xk x CH 3-P2 - 15 Filled- Area Primitives (cont.) Calculations performed in scan-conversion and other graphics algorithms typically take advantage of various coherence properties of a scene that is to be displayed. Coherence is simply that the properties of one part of a scene are related in some way to other parts of the scene so that the relationship can be used to reduce processing. Coherence methods often involve incremental calculations applied along a single scan line or between successive scan lines. CH 3-P2 - 16 Boundary-Fill Algorithm (Seed Fill) Start at a point inside a region and paint the interior outward toward the boundary. If the boundary is specified in a single color, the fill algorithm proceeds outward pixel by pixel until the boundary color is encountered. It is useful in interactive painting packages, where interior points are easily selected. The inputs of the this algorithm are: • • • Coordinates of the interior point (x, y) Fill Color Boundary Color CH 3-P2 - 17 Boundary-Fill Algorithm (Seed Fill) • Approach – Select a seed point inside a region – Move outwards from the seed point, setting neighboring pixels until the region is filled Seed point Move outwards to neighbors Stop when the region is filled CH 3-P2 - 18 Boundary-Fill Algorithm (cont.) Starting from (x, y), the algorithm tests neighboring pixels to determine whether they are of the boundary color. If not, they are painted with the fill color, and their neighbors are tested. This process continues until all pixels up to the boundary have been tested. There are two methods for proceeding to neighboring pixels from the current test position: CH 3-P2 - 19 Boundary-Fill Algorithm (cont.) 1. The 4-connected method. 2. The 8-connected method. CH 3-P2 - 20 Boundary-Fill Algorithm (cont.) void boundaryFill4 (int x, int y, int fillColor, int borderColor) { int interiorColor; /* set current color to fillColor, then perform following operations. */ interiorColor = getPixel (x, y); if ( (interiorColor != borderColor) && (interiorColor != fillColor) ) { setPixel (x, y); // set color of pixel to fillColor boundaryFill4 (x + 1, y, fillColor, borderColor); boundaryFill4 (x - 1, y, fillColor, borderColor); boundaryFill4 (x, y + 1, fillColor, borderColor); boundaryFill4 (x, y - 1, fillColor, borderColor); } } CH 3-P2 - 21 Boundary-Fill Algorithm (cont.) Seed pixel Boundary pixel CS 380 CH 3-P2 - 22 Boundary-Fill Algorithm (cont.) CH 3-P2 - 23 Boundary-Fill Algorithm (cont.) 4-connected and 8-connected methods involve heavy recursion which may consume memory and time. More efficient methods are used. These methods fill horizontal pixel spans across scan line. This called a Pixel Span method. We need only stack a beginning position for each horizontal pixel span, instead of stacking all unprocessed neighboring positions around the current position, where spans are defined as the contiguous horizontal string of positions. CH 3-P2 - 24 Pixel Span Method • • • • • Start from the initial interior point, then fill in the contiguous span of pixels on this starting scan line. Then we locate and stack starting positions for spans on the adjacent scan lines, where spans are defined as the contiguous horizontal string of positions bounded by pixels displayed in the area border color. At each subsequent step, we unstack the next start position and repeat the process. An example of how pixel spans could be filled using this approach is illustrated for the 4-connected fill region in the following figure. CH 3-P2 - 25 Pixel Span Method (cont.) CH 3-P2 - 26 Pixel Span Method (cont.) CH 3-P2 - 27 Flood-Fill Algorithm Sometimes we want to fill in (or recolor) an area that is not defined within a single color boundary. We can paint such areas by replacing a specified interior color instead of searching for a boundary color value. This approach is called a flood-fill algorithm. CH 3-P2 - 28 Flood-Fill Algorithm (cont.) We start from a specified interior point (x, y) and reassign all pixel values that are currently set to a given interior color with the desired fill color. If the area we want to paint has more than one interior color, we can first reassign pixel values so that all interior points have the same color. Using either a 4-connected or 8-connected approach, we then step through pixel positions until all interior points have been repainted. CH 3-P2 - 29 Flood-Fill Algorithm (cont.) void floodFill4 (int x, int y, int fillColor, int interiorColor) { int color; /* set current color to fillColor, then perform following operations. */ color=getPixel (x, y); if (color = interiorColor) { setPixel (x, y); // set color of pixel to fillColor floodFill4 (x + 1, y, fillColor, interiorColor); floodFill4 (x - 1, y, fillColor, interiorColor); floodFill4 (x, y + 1, fillColor, interiorColor); floodFill4 (x, y - 1, fillColor, interiorColor); } } CH 3-P2 - 30 Flood-Fill Algorithm (cont.) Seed pixel Original image and seed point CS 380 Image after 4-connected flood fill CH 3-P2 - 31 Inside-Outside Tests Area-filling algorithms and other graphics processes often need to identify interior regions of objects. To identify interior regions of an object graphics packages normally use either: 1. Odd-Even rule 2. Nonzero winding number rule CH 3-P2 - 32 Inside-Outside Tests Odd-Even rule (Odd Parity Rule, Even-Odd Rule): 1. draw a line from any position P to a distant point outside the coordinate extents of the object and counting the number of edge crossings along the line. 2. If the number of polygon edges crossed by this line is odd then P is an interior point. Else P is an exterior point CH 3-P2 - 33 CH 3-P2 - 34 Inside-Outside Tests Nonzero Winding Number Rule : Counts the number of times the polygon edges wind around a particular point in the counterclockwise direction. This count is called the winding number, and the interior points of a two-dimensional object are defined to be those that have a nonzero value for the winding number. 1. Initializing the winding number to 0. 2. Imagine a line drawn from any position P to a distant point beyond the coordinate extents of the object. CH 3-P2 - 35 Inside-Outside Tests Nonzero Winding Number Rule : 3. Count the number of edges that cross the line in each direction. We add 1 to the winding number every time we intersect a polygon edge that crosses the line from right to left, and We subtract 1 every time we intersect an edge that crosses from left to right. 3. If the winding number is nonzero, then P is defined to be an interior point Else P is taken to be an exterior point. CH 3-P2 - 36 CH 3-P2 - 37 Text and Characters •Two general techniques character generation used for – Bitmapped (raster) – Stroked (outline) 30/9/2008 Lecture 2 38 CH 3-P2 - 38 Text and Characters (Bitmapped (raster)) Each character represented (stored) as a 2-D array – Each element corresponds to a pixel in a rectangular “character cell” – Simplest: each element is a bit (1=pixel on, 0=pixel off) 00111000 01101100 11000110 11000110 11111110 11000110 11000110 00000000 30/9/2008 Lecture 2 39 CH 3-P2 - 39 Text and Characters (Stroked (outline)) Each character represented (stored) as a series of line segments – sometimes as more complex primitives Parameters needed to draw each stroke – endpoint coordinates for line segments 30/9/2008 Lecture 2 40 CH 3-P2 - 40 Characters Characteristics Characteristics of Bitmapped Characters • Each character in set requires same amount of memory to store • Characters can only be scaled by integer scaling factors • Difficult to rotate characters by arbitrary angles • Fast as compare to other technique Characteristics of Stroked Characters • Number of stokes (storage space) depends on complexity of character • Each stroke must be scan converted so more time to display • Easily scaled and rotated arbitrarily – just transform each stroke 30/9/2008 Lecture 2 41 CH 3-P2 - 41