|
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:

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:
- Start with two Points, having an X-value and an Y-value.
- Calculate the differences in X- and Y-values, dX and dY
- Now you can calculate the diagonal (the length of the line connecting these points) using the Pythagorean theorem.
- 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.
- Now you define a GraphicsPath, and rotate the GraphicsPath with the angle in degrees.
- 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.
|