Link to home
Start Free TrialLog in
Avatar of carpbyte
carpbyte

asked on

Drawing an Arrow

This should be easy for someone with good Trig skills, but I give it 500 points anyway.

I'm trying to draw an "arrow" on picture, and need to be able to make the arrow "head" proportionally. The arrow head will change depending on the angle that the original line was drawn.

Since everything is in terms of "rects" it's a little tricky to get the arrow head lines in the proper coordinates.

I'm sure it can be done with Cosines, etc. which will be a suitable solution, but if anyone has a brilliant trick I'm open to that too.

For an example of what the arrow would look like, draw a square and then draw a line bisecting it.  Erase erased the bottom and right sides, and the erase about 90% of the right and left sides to create the pointing arrow "head".  It's easy for a square, but not so easy for a rectangle.

Thanks.

Avatar of sdland1
sdland1

Type atom

    X As Double
    Y As Double
    xV As Double
    yV As Double
   
End Type


Private Function step(which As atom)

    which.X = which.X - which.xV
    which.Y = which.Y - which.yV

End Function

Private Function invert(ByRef X As Double) As Double

    invert = X * -1

End Function

drawSquare a.X, a.Y, b.X, b.Y, c.X, c.Y, d.X, d.Y


Private Sub drawSquare(x1 As Double, y1 As Double, x2 As Double, y2 As Double, x3 As Double, y3 As Double, x4 As Double, y4 As Double)
On Error Resume Next
   
    l = (Abs(x1 - x2) / 50) Mod 256
        Me.Line (x1, y1)-(x2, y2), RGB(256 - l, l, l)
    end sub
   
Just taging along...


Cheers!
Avatar of carpbyte

ASKER

I'm not quite clear on where the other functions get called and the additional parameters with in the drawSquare function.  What do the x3,y3,x4,y4 do?

Where do the Which & Invert functions come into play?

I'm basically using MouseDown & Up to send the current x,y values.

So far,
drawSquare downX#, downY#, upX#, upY#, 0, 0, 0, 0

draws a nice line, but how do I get the arrow head on it?  I'm missing the key step.

Thanks.

I just need a little more info per the comments to accept the response.

x1 and y1 botom left point of line
x2 and y2 top right end of line
x3 and y3 and x4 and y4 ends of head lines

pi=3.1415926535897932384626433832795
x=x2-x1
y=y2-y1
angle=atn(y/x)
angleoftopline=angle+(pi/4)
angleofbotom=angle-(pi/4)
x3=sqr((x2-x1)^2+(y2-y1)^2)*cos(angleoftop)
y3=sqr((x2-x1)^2+(y2-y1)^2)*sin(angleoftop)
x4=sqr((x2-x1)^2+(y2-y1)^2)*cos(angleofbotom)
y4=sqr((x2-x1)^2+(y2-y1)^2)*sin(angleofbotom)

I found a very simple solution, but I would like to leave the question open with regard to drawing an arrow using the Imaging For Windows OCX.  I.E. I need to draw the arrow on whatever is loaded in the imgedit.ocx control.

The following code works fine for a Picture Box, but I can't seem to "port" it to work with the ImgEdit.draw command.

Dim changex As Single
Dim changey As Single
Dim baselen As Single
   
    Picture1.DrawWidth = 5
    Picture1.ForeColor = QBColor(3)
   
    Picture1.Line (x1, y1)-(x2, y2) 'draw intital line
   
    changex = x2 - x1
    changey = y2 - y1
    baselen = Sqr(changex * changex + changey * changey)
    changex = CLng(changex / baselen * hat)
    changey = CLng(changey / baselen * hat)

    Picture1.Line (x1, y1)-(x1 + changex + changey, y1 + changey - changex)
    Picture1.Line (x1, y1)-(x1 + changex - changey, y1 + changey + changex)

Thanks for the attempts so far.
Hi carbyte
ImgEdit.draw command doesn't work to draw graphics - only for annotation.
Please read carefully ImgEdit OCX control help file. Instead you can create arrow image, save it in the Clipboard and then use ImgEdit.ClipBoardPaste command. But I'm not sure this is best solution.
Regards
George
Thanks, but that's exactly the issue - no arrow tool in the Imaging arsenal.

A stamp won't do it, as the "arrow" need to be varying length, angle, etc.
This is sample code how to draw line in ImgEdit OCX control box. It works as Line command in Visual Basic.
I hope this will be useful for you.
That's up to you to organise moving arrow across ImgEdit box use MouseMove event. I just investigate how to draw Line with any size/angle/location.
Good luck
------------
Just create new Form with ImgEdit1, Command1, Command2 and download from here source code for appropriate object

Option Explicit
'--------------
Dim lTop, lLeft, lWidth, lHeight As Long 'Line coords
Dim iLineWidth, iLineColor, iLineStyle As Long 'Line params
Dim sArrowGroupName As String 'Group name to save/manipulate Annotation object

Private Sub Command1_Click()
'
 sArrowGroupName = "MyArrow"
 iLineStyle = 0
 iLineWidth = 1
 iLineColor = &HFF&
'
 lTop = 0
 lLeft = 0
 lWidth = 100
 lHeight = 100
'
 Call fDrawLine(sArrowGroupName, iLineStyle, iLineWidth, iLineColor, _
      lTop, lLeft, lWidth, lHeight)
'
End Sub


Private Sub Command2_Click()
'
'Delete Line as Annotation object
'
 ImgEdit1.DeleteAnnotationGroup sArrowGroupName
'
End Sub

Private Sub Form_Load()
'
'Load image to ImgEdit Control
'
 ImgEdit1.ClearDisplay
 ImgEdit1.Image = App.Path & "\test.bmp"
 ImgEdit1.Display
'
End Sub



Public Sub fDrawLine(ByVal sArrowGroupName As String, iLineStyle, iLineWidth, iLineColor, _
      ByVal lTop As Long, ByVal lLeft As Long, ByVal lWidth As Long, ByVal lHeight As Long)
'
'Draw line as Annotation object
'
 ImgEdit1.AddAnnotationGroup sArrowGroupName
'
 ImgEdit1.AnnotationType = wiStraightLine
'
 ImgEdit1.AnnotationLineStyle = iLineStyle
 ImgEdit1.AnnotationLineWidth = iLineWidth
 ImgEdit1.AnnotationLineColor = iLineColor
'
 ImgEdit1.Draw lTop, lLeft, lWidth, lHeight
'
 ImgEdit1.AnnotationType = wiNone
'
End Sub
Thanks for the post.

Unfortunately, drawing the line isn't the hard part, it's the "arrow" hat.

All of Imaging for Windows drawing commands are based on rectangles (as opposed to Rectangles, Points, etc. for a normal Picture control).

So, the problem is calculating the two rectangles required to draw the actual arrow "hat" after you have completed the line.

The known elements are the start x,y point and the rect width and height upon completion of the arrow.

Seems pretty straight forward, but it's actually pretty complicated even with Trig functions.

Thanks.

 
carbyte
Maybe you didn't understand what source code I sent you. With this code if you can draw line (and point) - you can draw everything not only such simple think as arrow. Please have a look your previous code which you use to draw arrow in picture box with Line function.
I guess you can use instead the Picture.Line1 function code to draw line in ImgEdit source code (I mean fDrawLine sub).
Nobody can prepares everything what we want for us. So we should find solution how to solve this problem with that what we have. For your case fDrawLine sub is the best solution.
Regards
Thanks, but it isn't that easy.

The whole issue is maintaining the aspect of the "arrow" head.

It's easy to draw the initial line with Imaging for windows, it's the arrow head that is difficult, since there is no correlation between the rectangles drawn.

The problem is converting x,y corrdinates into a usable rectangle to pass to the ImgEdit.Draw command.

If you can show me a piece of code that draws the full arrow, in any direction, I'll be more than happy to award the
points.

Thanks.
ASKER CERTIFIED SOLUTION
Avatar of georgeman
georgeman

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you Georgeman!

This is what I was looking for and solves the problem the way I intended.

Thanks again!