procedure crazyLine(const ctx: TAgg2D; fromX, fromY, toX, toY: double; sloppiness: double = 0.5);

const

DEBUG: boolean = false;

var

// The idea is to draw a curve, setting two control points at random

// close to each side of the line. The longer the line, the sloppier it's drawn.

control1x, control1y: double;

control2x, control2y: double;

length: double;

offset: double;

t1X, t1Y, t2X, t2Y: double;

r: double;

begin

// Crazyline. By Steve Hanov, 2008

// Released to the public domain.

ctx.ResetPath;

ctx.NoFill;

ctx.LineColor(0, 0, 0);

// calculate the length of the line.

length := sqrt( (toX-fromX)*(toX-fromX) + (toY-fromY)*(toY-fromY));

// This offset determines how sloppy the line is drawn. It depends on the

// length, but maxes out at 20.

offset := length / 10 * sloppiness;

if (offset > 20) then

offset := 20;

// Overshoot the destination a little, as one might if drawing with a pen.

toX := toX + sloppiness * random * offset/4;

toY := toY + sloppiness * random * offset / 4;

// t1 and t2 are coordinates of a line shifted under or to the right of

// our original.

t1X := fromX + offset;

t1Y := fromY + offset;

t2X := toX + offset;

t2Y := toY + offset;

// create a control point at random along our shifted line.

r := random;

control1X := t1X + r * (t2X-t1X);

control1Y := t1Y + r * (t2Y-t1Y);

// now make t1 and t2 the coordinates of our line shifted above

// and to the left of the original.

t1X := fromX - offset;

t2X := toX - offset;

t1Y := fromY - offset;

t2Y := toY - offset;

// create a second control point at random along the shifted line.

r := random;

control2X := t1X + r * (t2X-t1X);

control2Y := t1Y + r * (t2Y-t1Y);

// draw the line!

ctx.MoveTo(fromX, fromY);

ctx.CubicCurveTo(control1X, control1Y, control2X, control2Y, toX, toY);

ctx.DrawPath;

if DEBUG then

begin

ctx.ResetPath;

ctx.NoFill;

// red - control point 1

ctx.LineColor($FF, 0, 0);

ctx.Ellipse(control1X, control1Y, 3, 3);

ctx.LineColor($E6, $E6, $EF, 150);

ctx.Line(fromX, fromY, control1X, control1Y);

// green - control point 2

ctx.LineColor(0, $FF, 0);

ctx.Ellipse(control2X, control2Y, 3, 3);

ctx.LineColor($E6, $E6, $EF, 150);

ctx.Line(toX, toY, control2X, control2Y);

end;

end;