Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleDraw a dashed polyline
Keywordspolyline, dashed, draw
CategoriesGraphics
 
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.
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated