2008. szeptember 26., péntek
How to draw dotted or dashed lines using a pen with a width greater than 1
Problem/Question/Abstract:
How to draw dotted or dashed lines using a pen with a width greater than 1
Answer:
I once got around this silly limitation by writing a wrapper procedure that would figure out where each dot or dash belonged, and draw many tiny line segments using a solid pen. One of the parameters to the procedure was a string indicating the pattern, which looked like morse code (any arrangement of dots and dashes is allowed).
However, the procedure is ugly. It will handle polylines, and if a polyline vertex falls right in the middle of a dash, then the dash will bend around the corner correctly.
The LineTo method of TCanvas cannot reliably render dashed lines more than one pixel wide. This procedure provides a workaround.
{Copyright (c) 1996 G. Williams}
procedure PlotDashedLine(const Canvas: TCanvas; const Vertices: array of TPoint;
const Pattern: string; const DashLength: Integer);
var
PenDown: Boolean;
Index: Integer;
procedure PlotTo(const Position: TPoint);
begin
with Canvas, Position do
if (PenDown) then
LineTo(X, Y)
else
MoveTo(X, Y);
end;
function Advance(const Distance: Integer): Boolean;
var
DistanceRemaining: Single;
DistanceToNextVertex: Single;
begin
Result := false;
DistanceRemaining := Distance;
DistanceToNextVertex := PointDist(Canvas.PenPos, Vertices[Index]);
while (DistanceRemaining > DistanceToNextVertex) do
begin
DistanceRemaining := DistanceRemaining - DistanceToNextVertex;
PlotTo(Vertices[Index]);
Inc(Index);
if (Index > High(Vertices)) then
Exit;
DistanceToNextVertex := PointDist(Canvas.PenPos, Vertices[Index]);
end;
with Canvas.PenPos do
if (FltEqual(DistanceToNextVertex, 0)) then
PlotTo(Vertices[Index])
else
PlotTo(Point(Round(X + DistanceRemaining / DistanceToNextVertex * (Vertices[Index].X - X)), Round(Y + DistanceRemaining / DistanceToNextVertex * (Vertices[Index].Y - Y))));
Result := true;
end;
var
PatternIndex: Integer;
OldPenStyle: TPenStyle;
begin
OldPenStyle := Canvas.Pen.Style;
Canvas.Pen.Style := psSolid;
Canvas.MoveTo(Vertices[0].X, Vertices[0].Y);
PatternIndex := 1;
Index := 1;
while (true) do
begin
PenDown := true;
case Pattern[PatternIndex] of
'.':
if not (Advance(0)) then
Break;
'-':
if not (Advance(DashLength)) then
Break;
else
ShowError('');
end;
PenDown := false;
if not (Advance(DashLength)) then
Break;
Inc(PatternIndex);
if (PatternIndex > Length(Pattern)) then
PatternIndex := 1;
end;
Canvas.Pen.Style := OldPenStyle;
end;
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése