Original Bresenham's line drawing algorithm it limited to drawing lines between two integer pixel positions and does not allow subpixel rendering. However with my reformulation of this algorithm as a system of equations it seems straighforward to extend it for subpixel rendering as follows (code for version 10):
Clear[bresenhamSolve];
bresenhamSolve[p1_, p2_] /;
GreaterEqual @@ Abs[p2 - p1] && MatchQ[Sign[p2 - p1], {1, 1} | {1, 0}] :=
Block[{ab = First@Solve[{p1, p2}.{a, 1} == b], x, y}, {x, y} /.
Solve[{a x + y + err == b /. ab, -1/2 < err <= 1/2, {x, y} \[Element] Integers,
Round[p1] <= {x, y} <= Round[p2]}, {x, y, err}]];
bresenhamSolve[p1_, p2_] /;
Less @@ Abs[p2 - p1] && MatchQ[Sign[p2 - p1], {1, 1} | {0, 1}] :=
Reverse /@ bresenhamSolve[Reverse[p1], Reverse[p2]];
bresenhamSolve[p1_, p2_] :=
With[{s = 2 UnitStep[p2 - p1] - 1},
Replace[bresenhamSolve[p1 s, p2 s], {x_, y_} :> s {x, y}, {1}]];
As one can see, the only change as compared to my previous formulation is wrapping the boundary coordinates for {x, y} by Round.
This implementation has nice radial distribution of sampled pixels:
r = 20; center = {-11, 0};
pointsOnCircle = Rationalize[N@CirclePoints[center, 20, 200], 0];
ArrayPlot[SparseArray[
Rule @@@ Tally[# - center & /@
Flatten[bresenhamSolve[center, #] & /@ pointsOnCircle + r + 1, 1]], {2 r + 1,
2 r + 1}], Mesh -> True, PlotRange -> {All, All, {0, 10}}, ClippingStyle -> Red,
PixelConstrained -> True]
Unfortunately this implementation is quite slow. I tried to create more efficient version using nikie's approach but was not able to reproduce the behavior of bresenhamSolve. For example with simplest implementation
Clear[pointsOnLine]
pointsOnLine[{p1_, p2_}] :=
Array[Round[p1 + # (p2 - p1)] &, Round@Max[Abs[p2 - p1]] + 1, {0, 1}]
the distribution of sampled pixels is not so pleasing:
r = 20; center = {0, 0};
pointsOnCircle = Rationalize[N@CirclePoints[center, 20, 200], 0];
ArrayPlot[SparseArray[
Rule @@@ Tally[# - center & /@
Flatten[pointsOnLine[{center, #}] & /@ pointsOnCircle + r + 1, 1]], {2 r + 1,
2 r + 1}], Mesh -> True, PlotRange -> {All, All, {0, 10}}, ClippingStyle -> Red,
PixelConstrained -> True]
What is an efficient way to implement subpixel version of Bresenham's algorithm?

