PDA

Click to See Complete Forum and Search --> : Plotting Arrows


ThomasJones
Jun 27th, 2003, 12:18 PM
I need to be pointed in the right direction. In a program that I'm writing I need to draw an arrow. I have a line that can be any random angle. What formula can I use to draw two other lines that begin at an X2,Y2 point and are slanted at a 45 degree angle for instance. The endpoints of the lines that make up the arrow does not matter.

For example:

X1=0
Y1=0
X2=10
Y2=10

How can I plot an arrow off of theese points using a formula?

Thanks for any help.

ThomasJones
Jun 27th, 2003, 04:07 PM
Well, I figured out in a round about way to do it. It's not a formula like I was looking for but for those who are interested, here it is.


x1=0:y1=0:x2=300:y2=400

xLineDelta = X2 - X1
yLineDelta = Y2 - Y1

xLineUnitDelta = xLineDelta / Sqr((xLineDelta * xLineDelta) + (yLineDelta * yLineDelta))
yLineUnitDelta = yLineDelta / Sqr((xLineDelta * xLineDelta) + (yLineDelta * yLineDelta))

'(xBase,yBase) is where arrow line is perpendicular to base of triangle.
HeadLength = 15 'The Length Of The Arrow Head
xBase = X2 - Round(HeadLength * xLineUnitDelta)
yBase = Y2 - Round(HeadLength * yLineUnitDelta)

xNormalDelta = yLineDelta
yNormalDelta = -xLineDelta
xNormalUnitDelta = xNormalDelta / Sqr((xNormalDelta * xNormalDelta) + (yNormalDelta * yNormalDelta))
yNormalUnitDelta = yNormalDelta / Sqr((xNormalDelta * xNormalDelta) + (yNormalDelta * yNormalDelta))


'// Draw the arrow tip
Me.Line (X1, Y1)-(X2, Y2)

'here is one side of the arrow
'x1=xBase+Round(HeadLength * xNormalUnitDelta)
'y1=yBase + Round(HeadLength * yNormalUnitDelta)
Me.Line (xBase + Round(HeadLength * xNormalUnitDelta), yBase + Round(HeadLength * yNormalUnitDelta))-(X2, Y2)

'here is the other side of the arrow
'x1=xBase+Round(HeadLength * xNormalUnitDelta)
'y1=yBase + Round(HeadLength * yNormalUnitDelta)
Me.Line (xBase - Round(HeadLength * xNormalUnitDelta), yBase - Round(HeadLength * yNormalUnitDelta))-(X2, Y2)





Thanks

sql_lall
Jun 28th, 2003, 05:28 AM
OK, when drawing lines it is always a good idea to look at the angle formed between the line and the x-axis.
this way, if you want a line at T degrees, length L from the x-axis starting at X1,Y1, the line is:
(X1,Y1)->(X1+R*cos(T), Y1+R*sin(T))

Then, as you are now wanting two lines 45 degrees off the endpoint, the new lines are at 45+T and 135+T degrees from the X-Axis (or pi/4 +T and 3Pi/4 +T radians)

You can use the same formula then to draw the new lines, with starting point X2=X1+R*cos(T) and Y2=Y1+R*sin(T)

Finally, i'm not too sure about what happens with angles with the same tan value (like, 30 and 210 degrees) whether this works fine, or whether some if-statements must be added to see if the angle is < or >=180 degrees.

krtxmrtz
Jul 2nd, 2003, 11:38 AM
I think this should be correct in all instances.

Referring to the drawing, (your arrow is blue):

http://www.vbforums.com/attachment.php?s=&postid=1473475

alpha is 45 deg. in your case, but I have written the general case.

theta is the angle between the (x1,y1) to (x2,y2) segment and the x axis. In the drawing it is > 180 deg. because the arrow is pointing downwards and to the left.

The coordinates you want to figure out are (x3,y3) and (x4,y4).

Then:

x3 = x2 + cos(Beta2)
y3 = y2 + sin(Beta2)
x4 = x2 + cos(Beta1)
y4 = y2 + sin(Beta1)

and cos & sin of Beta2 and Beta1 as a function of alpha and theta are calculated by means of elemental trig. formulas:

Beta2 = theta - (Pi - alpha)
Beta1 = theta + (Pi - alpha)

cos(Beta2) = sin(theta)sin(alpha) - cos(theta)cos(alpha)
sin(Beta2) = -sin(theta)cos(alpha) - cos(theta)sin(alpha)
cos(Beta1) = -sin(theta)sin(alpha) - cos(theta)cos(alpha)
sin (Beta1) = -sin(theta)cos(alpha) + cos(theta)sin(alpha)

krtxmrtz
Aug 8th, 2003, 08:55 AM
I have written a demo project where I have made a few changes to take user scales into account, otherwise if the vertical and horizontal scales are not the same your arrow could come out quite out of this world.

krtxmrtz
Aug 8th, 2003, 09:00 AM
Here's a new drawing I've used in relation to the code.

http://www.vbforums.com/attachment.php?s=&postid=1500193

Darkwraith
Aug 8th, 2003, 04:22 PM
Couldn't you have an X and Y range?

If you did then you could find the position by (this is for X):
(X - Xmin) / (Xmax - Xmin) = decimal percent. of placement inside pic
where Xmin <= X <= Xmax
then
Pic1.left + round( dec. percent * Pic1.Width) = X coordinate

This way, your graph is scalable. :)

NOTE: Please check to make sure I'm right. Also, sorry if I am reiterating anything here. I did not get a chance to look at the attachment.

krtxmrtz
Aug 11th, 2003, 03:03 AM
Originally posted by Darkwraith
Couldn't you have an X and Y range?

If you did then you could find the position by (this is for X):
(X - Xmin) / (Xmax - Xmin) = decimal percent. of placement inside pic
where Xmin <= X <= Xmax
then
Pic1.left + round( dec. percent * Pic1.Width) = X coordinate

This way, your graph is scalable. :)

NOTE: Please check to make sure I'm right. Also, sorry if I am reiterating anything here. I did not get a chance to look at the attachment.
At first glance I'd say this is more or less what I do. See the attachment and take a look at the code.