Does anyone know a good way of drawing dotted or dashed lines using a pen
with a greater width than 1???
I don't know why Microsoft have limited this functionallity of pens. I have
managed to draw straight dotted and dashed lines using the LineDDA but I
would also like this functionallity to draw thick-dotted circles and other
curves... anyone know how to do this?
Thanks in advance, i'm tearing my hair out over this one!!!
Graham Murt
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 work-around.
Copyright (c) 1996 G. Williams, gw at objectpascal dot org
}
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;
Gary:
May I put a copy our your procedure on my Delphi Graphics Algorithms page?
[I always ask when there is an explicit copyright statement.]
TIA.
--
efg ef...@efg2.com Earl F. Glynn, Overland Park, KS USA
efg's Computer Lab: http://www.efg2.com/Lab
Mirror: http://homepages.borland.com/efg2lab/Default.htm
Certainly.
I left out the PointDist() function in my earlier posting but it's just a
trivial wrapper for Hypot().
-Gary