|
|
Title | Draw a dashed polyline |
Keywords | polyline, dashed, draw |
Categories | Graphics |
|
|
When you draw a series of small dashed or dotted lines using the Line statement, you don't always get a very good result.
If the lines are too small, they blend together making a solid line with gaps. This code draws a series of line segments
with dashes.
Note also that the DrawStyle property only works when DrawWidth = 1. If DrawWidth > 1, the line is solid. This code
also handles this case and can draw thick dashed polylines.
Subroutine DrawDashedPolyline starts it all. The variable skipping tells the program whether it is drawing
a dash or a skip between dashes. Variable dist_to_draw is the distance left to draw in the current dash/skip.
DrawDashedPolyline loops through the segments defined for the polyline and calls DrawDashedSegment to
draw them. It passes the skipping and dist_to_draw variables to DrawDashedSegment ByRef so that routine
can update them as it draws.
|
|
' Draw the polyline with dashed segments.
Private Sub DrawDashedPolyline(ByVal pic As Object, ptx() _
As Single, pty() As Single, Optional ByVal dash_length _
As Single = 60, Optional ByVal skip_length As Single = _
60)
Dim skipping As Boolean
Dim dist_to_draw As Single
Dim pt As Integer
Dim x1 As Single
Dim y1 As Single
Dim x2 As Single
Dim y2 As Single
' Start drawing.
skipping = False
dist_to_draw = dash_length
' Start at (x1, y1).
pt = LBound(ptx)
x2 = ptx(pt)
y2 = pty(pt)
' Draw the line segments.
For pt = pt + 1 To UBound(ptx)
' Get the next point.
x1 = x2
y1 = y2
x2 = ptx(pt)
y2 = pty(pt)
' Draw between these points.
DrawDashedSegment pic, _
dash_length, skip_length, _
x1, y1, x2, y2, _
skipping, dist_to_draw
Next pt
End Sub
|
|
Subroutine DrawDashedSegment begins by calculating the segment's unit vector (vector of length 1 pointing in the
direction of the segment). It then loops until it uses up the segment.
In the loop, the routine determines how far it can draw for the current dash/skip. This is the smaller of:
- The remaining length of the segment (stored in variable dist)
- The amount left to draw for the current dash/skip (stored in variable dist_to_draw)
The routine uses the unit vector to draw/skip this distance and it subtracts this distance from dist and dist_to_draw.
Now if dist_to_draw > 0, the routine did not draw the entire dash/skip. In that case, it must have run out of segment
so it exits the Do loop so it can start on the next segment.
If dist_to_draw = 0, the routine finished the current dash/skip and probably still has some segment to use.
In that case, the routine switches the value of skipping and repeats the loop to draw the next dash/skip using
the rest of this segment.
|
|
' Draw a dashed segment from (x1, y1) to (x2, y2).
Private Sub DrawDashedSegment(ByVal pic As Object, ByVal _
dash_length As Single, ByVal skip_length As Single, _
ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As _
Single, ByVal y2 As Single, ByRef skipping As Boolean, _
ByRef dist_to_draw As Single)
Dim ux As Single
Dim uy As Single
Dim dist As Single
Dim dist_this_piece As Single
' See how long the segment is.
ux = x2 - x1
uy = y2 - y1
dist = Sqr(ux * ux + uy * uy)
' Do nothing if the segment has zero length.
If dist < 0.00001 Then Exit Sub
' Get the segment's unit vector.
ux = ux / dist
uy = uy / dist
' Repeat until we use up the segment.
Do
' See how far we should go.
dist_this_piece = dist
' Make sure we don't exceed the total distance.
If dist_this_piece > dist_to_draw Then _
dist_this_piece = dist_to_draw
' Go.
If skipping Then
If dist_this_piece > skip_length Then _
dist_this_piece = skip_length
x1 = x1 + ux * dist_this_piece
y1 = y1 + uy * dist_this_piece
Else
If dist_this_piece > dash_length Then _
dist_this_piece = dash_length
x2 = x1 + ux * dist_this_piece
y2 = y1 + uy * dist_this_piece
pic.Line (x1, y1)-(x2, y2)
x1 = x2
y1 = y2
End If
' Subtract the distance drawn.
dist_to_draw = dist_to_draw - dist_this_piece
dist = dist - dist_this_piece
' See if we finished this dash/skip.
If dist_to_draw > 0 Then
' We did not finish. We ran out of segment.
' Exit to start the next segment.
Exit Do
Else
' We did finish. Start the next dash/skip
' on this segment.
skipping = Not skipping
If skipping Then
dist_to_draw = skip_length
Else
dist_to_draw = dash_length
End If
End If
Loop
End Sub
|
|
For more information on graphics including drawing routines (splines and other curves), graphing, fractals,
three-dimensonal graphics, ray tracing, and lots more, see the book
Visual Basic Graphics Programming.
|
|
|
|
|
|