In the document found at http://members.chello.at/easyfilter/bresenham.html it walks through the process of creating curves based arround the Bresenham's Algorithm, and it ends with an algorithm to create anti-aliased thick lines, but how can this be aplied to the Quadratic Bezier Curves (the Anti Aliased version found on the same site)?
I tried change the plotQuadBezierSegAA function's last line to use the algorithm of the thick line, but obviously it did not worked as it is computing the other pixels one by one. (I changed from plotLineAA(x0,y0, x2,y2); to plotLineWidth(x0, y0, x2, y2, wd);)
I also tried to draw more curves slightly shifted until it had the wanted thickness, but it creates problems with the anti aliasing colors. (A for loop that shifted by the x and y step (xx and yy variables) and recursively called the plotQuadBezierSegWidth).
None of this tries actualy worked, so could please someone help me acomplish the thickness in this curves. (The algorithm so far is the one from plotQuadBezierSegAA found on that site).
Code for the shifting:
void plotQuadBezierSegAA(int x0, int y0, int x1, int y1, int x2, int y2, int wd)
{
int sx = x2-x1, sy = y2-y1;
long xx = x0-x1, yy = y0-y1, xy; /* relative values for checks */
double dx, dy, err, ed, cur = xx*sy-yy*sx; /* curvature */
assert(xx*sx >= 0 && yy*sy >= 0); /* sign of gradient must not change */
if (sx*(long)sx+sy*(long)sy > xx*xx+yy*yy) { /* begin with longer part */
x2 = x0; x0 = sx+x1; y2 = y0; y0 = sy+y1; cur = -cur; /* swap P0 P2 */
}
if (cur != 0)
{ /* no straight line */
xx += sx; xx *= sx = x0 < x2 ? 1 : -1; /* x step direction */
yy += sy; yy *= sy = y0 < y2 ? 1 : -1; /* y step direction */
// SHIFTING HERE
plotQuadBezierSegAA(x0 + xx, y0 + yy, x1 + xx, y1 + yy, x2 + xx, y2 + yy, wd - 1);
xy = 2*xx*yy; xx *= xx; yy *= yy; /* differences 2nd degree */
if (cur*sx*sy < 0) { /* negated curvature? */
xx = -xx; yy = -yy; xy = -xy; cur = -cur;
}
dx = 4.0*sy*(x1-x0)*cur+xx-xy; /* differences 1st degree */
dy = 4.0*sx*(y0-y1)*cur+yy-xy;
xx += xx; yy += yy; err = dx+dy+xy; /* error 1st step */
do {
cur = fmin(dx+xy,-xy-dy);
ed = fmax(dx+xy,-xy-dy); /* approximate error distance */
ed = 255/(ed+2*ed*cur*cur/(4.*ed*ed+cur*cur));
setPixelAA(x0,y0, ed*fabs(err-dx-dy-xy)); /* plot curve */
if (x0 == x2 && y0 == y2) return;/* last pixel -> curve finished */
x1 = x0; cur = dx-err; y1 = 2*err+dy < 0;
if (2*err+dx > 0) { /* x step */
if (err-dy < ed) setPixelAA(x0,y0+sy, ed*fabs(err-dy));
x0 += sx; dx -= xy; err += dy += yy;
}
if (y1) { /* y step */
if (cur < ed) setPixelAA(x1+sx,y0, ed*fabs(cur));
y0 += sy; dy -= xy; err += dx += xx;
}
} while (dy < dx); /* gradient negates -> close curves */
}
plotLineAA(x0,y0, x2,y2); /* plot remaining needle to end */
}
In the scratchpad (js file here: http://members.chello.at/easyfilter/bresenham.js lines 909 to 1049) it uses the plotQuadRationalBezierWidth with the w set as 1 to compute a normal Bezier curve with a specified amount of width for the thickness of the line (the wd parameter).
The ported c code from the file:
Example (Thickness 5px):
Example (Thickness 1px):