Associated Topics || Dr. Math Home || Search Dr. Math

### Drawing an Arrow

```
Date: 05/11/2000 at 03:38:13
From: Johan Sageryd
Subject: Drawing an Arrow

Hi.

I've come across a math problem while building my pascal program. I
need to draw an arrow relative to a user-drawn baseline. For example,
the user draws a line from point (X1,Y1) to point (X2,Y2). At point
(X2,Y2) I want an arrowhead to be drawn. The question I have is; what
are the coordinates of the edges of the arrow? I want the angle
between the baseline and arrow side to be 30 degrees, and the length
of the arrow side 15 pixels.

I would really appreciate it if you could give me a hand on this.
Thanks!

Sincerely,
- Johan Sageryd
```

```
Date: 05/11/2000 at 12:13:14
From: Doctor Peterson
Subject: Re: Drawing an Arrow

Hi, Johan.

I'll assume you understand a bit of trigonometry, in order to follow
this. If the line is at an angle A degrees to the x-axis, the two
sides of the arrowhead should be at angles A+30 and A-30 degrees. The
slope is the tangent of this angle, so the slope of the two sides will
be:

tan(A) + tan(30)
m1 = tan(A+30) = ------------------
1 - tan(A) tan(30)

tan(A) - tan(30)
m2 = tan(A-30) = ------------------
1 + tan(A) tan(30)

You can easily find tan(A), which is the slope of the original line;
tan(30) is 1/sqrt(3). Using these two slopes, you can draw the lines
you need. Let me know if you need more help.

- Doctor Peterson, The Math Forum
http://mathforum.org/dr.math/
```

```
Date: 05/11/2000 at 13:57:17
From: Johan Sageryd
Subject: Re: Drawing an Arrow

Thanks for the quick answer! Maybe I didn't express it clear enough to
be understandable, but what I really need is a formula for calculating
the coordinates of the two outer points of the arrowhead. We can call
them (X3,Y3) and (X4,Y4).

Thanks again!
- Johan Sageryd
```

```
Date: 05/11/2000 at 14:53:25
From: Doctor Peterson
Subject: Re: Drawing an Arrow

Hi, Johan.

I understand what you are asking for; but we like to give students a
chance to do as much of the work as they can, so we prefer to give
help rather than complete answers. You'll be able to use a formula
better if you understand where it comes from, so you can make
adjustments for yourself if you find a need to do so.

I did the first hard part, the trigonometry, for you. The next step is
either to use vectors, if you have learned about them, to find the
point a given distance in the direction of slope m1 from your end
point; or if you can't do that, to write the equation of the line with
that slope and solve an equation to find the point. One of us has to
do that work (I don't know of a standard off-the-shelf equation for
this), and it's best if you can do it.

If you still want more help, just write back and tell me what you have
done and where you have trouble, so I can help further.

- Doctor Peterson, The Math Forum
http://mathforum.org/dr.math/
```

```
Date: 05/12/2000 at 17:03:22
From: Doctor Peterson
Subject: Re: Drawing an Arrow

Hi, Johan.

Now that I've given you a chance to work this problem out, I want to
let you know what I came up with, because I recognize it may be
difficult for you to do on your own. It's an interesting problem.

We have a line segment from A(x0,y0) to B(x1,y1), and want to draw
segments BC and BD of length d, at a t degree angle on either side of
the segment at (x1,y1):

B
d   ---o
------ //
D o--   t /  /
/  t/ d
/    /
/      /
/       o
/         C
/
slope m /
/
/
/
/ s
o - - - - - - -
A

As before, we can pre-calculate a few numbers to make things easier:

m = (y1-y0)/(x1-x0) = tan(s)

n = tan(t)

The vector from B to C will have a slope that is the tangent of s+t.
(For the vector BD, we can replace t with -t everywhere.) This makes
its slope:

tan(s) + tan(t)    m + n
----------------- = ------
1 - tan(s) tan(t)   1 - mn

One possible vector in this direction will be (1 - mn, m + n). We can
make a unit vector by dividing this by its length, which is:

sqrt((1 - mn)^2 + (m + n)^2)

= sqrt(1 + m^2n^2 + m^2 + n^2)

= sqrt((1 + m^2)(1 + n^2))

Adding d times this unit vector to the position vector of point B, we
find:

1 - mn                            m + n
C = (x1 + ------------------------ d, y1 + ------------------------ d)
sqrt((1 + m^2)(1 + n^2))         sqrt((1 + m^2)(1 + n^2))

I've left out one detail, which is that there are actually TWO points
that are d units away from B on the line with the correct slope; how
can we ensure that this segment is drawn toward A rather than away
from it? If we go back to vector (1 - mn, m + n), we can tell whether
it points the right way by taking the scalar (dot) product with the
vector (x1 - x0, y1 - y0), which we want to be negative, so that it
will be pointing backward:

(1 - mn, m + n) dot (x1-x0, y1-y0)
= (1 - mn)(x1 - x0) + (m + n)(y1 - y0)
= (1 - mn)(x1 - x0) + (m + n)m(x1 - x0)
= [(1 - mn) + (m + n)m] (x1 - x0)
= (1 + m^2)(x1 - x0)

Since 1 + m^2 is always positive, this will have the same sign as
x1 - x0; so if x1 > x0, we want to replace d with -d to make it
negative.

(1 - mn)
x = x1 + ------------------------ d
sqrt((1 + m^2)(1 + n^2))

(m + n)
y = y1 + ------------------------ d
sqrt((1 + m^2)(1 + n^2))

Again, if x1 > x0, replace d with -d, and for point D, replace n with
-n. In your case, t = 30 degrees and n = 1/sqrt(3).

Please let me know if there are any parts of this you don't follow; I
don't know whether you know anything about vectors, but they are very
useful for any kind of graphic programming.

- Doctor Peterson, The Math Forum
http://mathforum.org/dr.math/
```

```
Date: 05/14/2000 at 09:57:09
From: Johan Sageryd
Subject: Re: Drawing an Arrow

Hi! Thanks VERY much for the explanation! I have implemented your
formula into a program and I have found an error, or what seems like
an error to me anyway: the angle, t, doesn't seem to be an angle,
rather some sort of... um... well something else.

Thanks!
- Johan Sageryd
```

```
Date: 05/14/2000 at 22:51:35
From: Doctor Peterson
Subject: Re: Drawing an Arrow

Hi, Johan.

Before I sent you the formula, I implemented it (not as a program, but
using Geometer's Sketchpad, which let me plot the point and see how it
worked for different lines), and it worked for me in that form. I was
playing with the formula yesterday and made an improved version. My
concern was that what I gave you did not work if m is undefined (or
too large to compute); so I wrote m as (y1-y0)/(x1-x0) and simplified
the expression. It turns out that since I multiplied by x1-x0, I also
eliminated the problem with the direction of the arrowhead if x1 < x0.
Here's the improved formula:

(x1-x0) - n(y1-y0)    d
x = x1 - ------------------ * ---
sqrt(1 + n^2)      l

(y1-y0) + n(x1-x0)    d
y = y1 - ------------------ * ---
sqrt(1 + n^2)      l

where d is the length of the arrowhead line, n is the tangent of t,
and l is the length of the line AB = sqrt((x1-x0)^2 + (y1-y0)^2). For
the other side of the arrowhead, the sign of n is reversed, so the
+ and - are swapped. This form is much more symmetrical, isn't it?

Perhaps you can show me the source of your program (or at least the
relevant section) so I can see how you are using t. It should work,
but there may be a subtlety to its use in your program that I didn't
anticipate. I assume you are taking the tangent of the angle expressed

- Doctor Peterson, The Math Forum
http://mathforum.org/dr.math/
```

```
Date: 05/15/2000 at 01:55:52
From: Johan Sageryd
Subject: Re: Drawing an Arrow

Hi! I think what you're saying might be the problem, the program uses
these two? Anyway, thanks for the new formula, I will try it A.S.A.P.

- Johan Sageyrd
```

```
Date: 05/15/2000 at 09:06:51
From: Doctor Peterson
Subject: Re: Drawing an Arrow

Hi, Johan.

Yes, if t is in degrees you will want to use

n = tan(t*pi/180)

to convert it to radians first. If you don't do this, large angles in
degrees will probably seem to give random results.

It occurred to me last night that, in trying to guide you to a simple
solution initially, without knowing whether you've had any
trigonometry or vectors, I blinded myself to the standard way to solve
this, which uses matrices. You can simply rotate the vector BA by t
degrees and scale it to the right length, and you will get exactly the
final formula I gave you, as long as t is less than 90 degrees. Here's
a version that should be completely general:

x = x1 - [(x1-x0)cos(t) - (y1-y0)sin(t)]*d/l

y = y1 - [(y1-y0)cos(t) + (x1-x0)sin(t)]*d/l

It's definitely worth learning about matrices if you are going to do
much with graphics; I've taught my 15-year-old son the basics.

- Doctor Peterson, The Math Forum
http://mathforum.org/dr.math/
```

```
Date: 05/15/2000 at 12:46:12
From: Johan Sageryd
Subject: Re: Drawing an Arrow

Okay, thanks. I've written a new version now with the degrees problem
fixed.

- Johan
```
Associated Topics:
High School Trigonometry

Search the Dr. Math Library:

 Find items containing (put spaces between keywords):   Click only once for faster results: [ Choose "whole words" when searching for a word like age.] all keywords, in any order at least one, that exact phrase parts of words whole words

Submit your own question to Dr. Math
Math Forum Home || Math Library || Quick Reference || Math Forum Search