开发者

How to scan convert right edges and slopes less than one?

I'm writing a program which will use scan conversion on triangles to fill in the pixels contained within the triangle.

One thing that has me confused is how to determine the x increment for the right ed开发者_开发技巧ge of the triangle, or for slopes less than or equal to one.

Here is the code I have to handle left edges with a slope greater than one (obtained from Computer Graphics: Principles and Practice second edition):

for(y=ymin;y<=ymax;y++)
{
    edge.increment+=edge.numerator;
    if(edge.increment>edge.denominator)
    {
        edge.x++;
        edge.increment -= edge.denominator;
    }
}

The numerator is set from (xMax-xMin), and the denominator is set from (yMax-yMin)...which makes sense as it represents the slope of the line. As you move up the scan lines (represented by the y values). X is incremented by 1/(denomniator/numerator) ...which results in x having a whole part and a fractional part.

If the fractional part is greater than one, then the x value has to be incremented by 1 (as shown in edge.increment>edge.denominator).

This works fine for any left handed lines with a slope greater than one, but I'm having trouble generalizing it for any edge, and google-ing has proved fruitless.

Does anyone know the algorithm for that?


There are 4 cases you need to consider: slope > 1, slope between 0 and 1, slope between -1 and 0, and slope less than -1.

You have coded for slope > 1. If you have slope < -1, you can determine that ahead of time, compute increment to be +1 or -1, and change x++ to x += increment.

For the cases where slope is between -1 and 1, you can have the same loop, only with x and y swapped.

EDIT: It sounds like you're trying to fill a triangle by scan converting two legs simultaneously. That's a special case that you can use, but the general way to scan convert a convex polygon (like a triangle) is to put all the points into a list and then for each scan line, draw a line between the min and max column. Here's some pseudocode for the algorithm:

// create a list of points that is the union of all segments
var points = ScanConvert(x1, y1, x2, y2)
             .Union(ScanConvert(x2, y2, x3, y3))
             .Union(ScanConvert(x1, y1, x3, y3));
// group the points by scan line, finding the leftmost and rightmost point on each line
var scanlines = from p in points
                group p by p.Y into scanline
                select new { y = scanline.Key,
                             x1 = scanline.Min(p => p.X),
                             x2 = scanline.Max(p => p.X) }
// iterate over the scan lines, drawing each segment
foreach (var scanline in scanlines)
    DrawLine(x1, y, x2, y);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜