How to draw an arrow using VB.net PDF Print E-mail
Written by Joris Bijvoets   
Monday, 14 December 2009 07:39

There comes a time in your life you have to draw an arrow using VB.net. First, you try the StartCap and EndCap feature of the predefined Pen-Object:

'Suppose you have to draw the arrow from Point Pnt1 to Point Pnt2:

Dim Graph As Graphics = Me.CreateGraphics()
Dim Pen1 As New Pen(Color.Blue, 5)

Pen1.StartCap = Drawing2D.LineCap.ArrowAnchor
Pen1.EndCap = Drawing2D.LineCap.DiamondAnchor

Graph.DrawLine(Pen1, Pnt1.X, Pnt1.Y, Pnt2.X, Pnt2.Y)

This code draws a nice arrow onto your form:

Drawing a simple arrow in Visual Basic

 

If you want to draw on an existing image instead of the Form, sometimes the arrow isn't visible if you use a linewidth of 1.You can thicken your line to solve your problem. If you want to use a thin line of width = 1 , you'll have to draw the arrow yourself.

Drawing an arrow the hard way

The problem you'll stumble onto in that case, is that the arrow must point in the direction of the line. Some highschool maths is needed if you want to do it the hard way:

  1. Start with two Points, having an X-value and an Y-value.
  2. Calculate the differences in X- and Y-values, dX and dY
  3. Now you can calculate the diagonal (the length of the line connecting these points) using the Pythagorean theorem.
  4. The angle of the line can be calculated now by calculating the cosine, using this cosine to calculate the arccosine, and converting the result of the arccosine from radions to degrees.
  5. Now you define a GraphicsPath, and rotate the GraphicsPath with the angle in degrees.
  6. At last, use the simple Graphics.DrawPath function to draw the arrow to the image.

 

The code for all this work is the following:

 

'Suppose you have a Graphics object to draw upon;

'Suppose you have to Points, Pnt1 and Pnt2 to draw the lines between.

Graph.FillPath(Brushes.Black, GetArrowPath(Pnt1, Pnt2))

 

Private Function GetArrowPath(ByVal Pnt1 As Point, ByVal Pnt2 As Point) As GraphicsPath

Dim dX As Decimal, dY As Decimal
Dim diagonal As Decimal
Dim cosa As Decimal, sina As Decimal
Dim degr As Decimal

dX = Pnt1.X - Pnt2.X
dY = Pnt1.Y - Pnt2.Y

diagonal = (dX ^ 2 + dY ^ 2) ^ (1 / 2) 'Pythagoras

cosa = (dX / diagonal)

degr = Math.Acos(cosa) * 180 / Math.PI - 90

Dim path As New GraphicsPath()
Dim pnts(4) As Point

pnts(0) = New Point(Pnt1.X, Pnt1.Y)
pnts(1) = New Point(Pnt1.X - 3, Pnt1.Y + 5)
pnts(2) = New Point(Pnt1.X, Pnt1.Y + 3)
pnts(3) = New Point(Pnt1.X + 3, Pnt1.Y + 5)
pnts(4) = New Point(Pnt1)

path.AddPolygon(pnts)

'rotate it degrees° clockwise using the center of the object
Dim rot As New Matrix()

rot.RotateAt(degr, Pnt1)
path.Transform(rot)

GetArrowPath = path

End Function

 

Do it more simple

The solution above is nice for the die hards. I prefer a more simple method: using the CustomLineCap.

Dim MyPath As New GraphicsPath()

' Create the outline for our custom end cap.
MyPath.AddLine(New Point(0, 0), New Point(-3, -2))
MyPath.AddLine(New Point(-3, -2), New Point(0, -1))
MyPath.AddLine(New Point(0, -1), New Point(3, -2))
MyPath.AddLine(New Point(3, -2), New Point(0, 0))

' Construct the hook-shaped end cap.
Dim MyCustLineCap As New CustomLineCap(Nothing, MyPath)

Dim Graph As Graphics = Me.CreateGraphics()
Dim MyPen As New Pen(Color.Blue, 5)
MyPen.CustomEndCap = MyCustLineCap

Using MyPen for drawing a line shows a nice arrow, rotating itself according to the direction of the line.

 

Last Updated on Friday, 26 November 2010 19:08