Notice that the expansion of the line width depends on the order of the
points:
* If the bigger axis value is provided as the *second* point the line
expand first to the *positive* side of the axis.
* If the bigger axis value is provided as the *first* point the line
expand first to the *negative* side of the axis.
* If the line's width is odd this doesn't matter, as the line will
expand the same amount to both sides.
This behavior should be consistent in both horizontal and vertical lines.
The previous version of the function didn't generate correct wide lines
of even width.
The most notable changes are:
* Make variable names far more descriptive about the process.
* Corrected the width calculation; we should deduct one pixel from the
width because the pixels at the center of the line doesn't count for
the triangles.
* Now we calculate *two* ratios, one for left/top displacement (dxmin)
and one for right/bottom (dxmax), this fix the behavior with lines
of even width.
It can probably be optimized.
The (previously refactored) polygon_generic function didn't draw
consistent polygons (equilateral polygons were not equilateral nor
symmetrical).
The most notable changes are:
* The horizontal edges are searched for when finding the polygon
boundaries, drawn and discarded from the edge list used to detect
intersections.
* The intersections are now checked and calculated from the current value
of the scan line (ymin) instead of in the middle (ymin + 0.5).
* Because the change in the scan line behavior, we should duplicate
the intersections in the maximum Y value of an edge or there will be
draw errors with concave and complex polygons.
* The rounds of the X coordinates in the hline function calls are
switched to draw the inner pixels.
* Removed the ugly micro-optimization of qsort at the end.
This implementation of the scan line algorithm may not be technically
correct, it's not optimized and it have problems with some edge cases,
like a wide line from (x0, y) to (x1, y + 1), therefore it should be
reviewed in the future.
The rounds used in the library are towards positive/negative infinity.
Since we're in a cartesian plane, rounds around zero are much more
convenient, so we can use positive and negative values with consistent
results.