Create an arrow shape based on a vector

330 Views Asked by At

I've been trying to generate an arrow shape with javascript, which would have following characteristics:

  • random direction
  • random length (in bounds which doesn't matter in this question)
  • the length of the arrow head would be specific (10% of the arrows length)
  • the angle of the arrow head would be specific (30 degrees from the vector)

What I've managed to do so far is generating the line which always starts in point (0,0), has random angle α and random length l both of which I know. I also have the coordinates of the ending point of the line (x,y).

Now what is the most troubling part for me is creating the head arrow shape. I know one side of it would have to start in (x,y) point and be at 30 degree from the line, and the opposite would be the same just the but at -30 degree. So I guess what I would need is the ending point of each arrowhead side (n,m) (n',m') derived from the provided data?

I've never been good at maths, I've seen some helpfull equations but I'm afraid my brain doesn't have enough computing power to create a general case for this. If anyone could help that'd be great :)

enter image description here my data:

  • (x,y)
  • L
  • α
1

There are 1 best solutions below

0
On BEST ANSWER

You need to give me one more piece of data, which I'll call $f$:

  • $f$: a number between $0$ and $1$ indicating the length of the arrow "edges" as a fraction of $L$. If $f = 0.1$, then the edges of the arrowhead are each $10%$ of the length $L$ of the main body of the arrow.

I'll be writing "$+$" and "$-$" for points, and when I write those, I mean this: add or subtract term-by-term. So $$ (3, 5) + (-2, 4) = (3+ (-2), 5 + 4) = (1, 9), $$ for instance. I'll also multiply ordered pairs by a number (in a process called "scalar multiplication"), again termwise, so that $$ 3(1, -4) = (3, -12). $$

Finally, since you've expressed angles in degrees, I'll express them in degrees as well, and when I write $\cos (30)$, I'll assume that this means the cosine of 30 degrees (which may be computed in your programming language using something like cosd(330), or may have to computed by something like u = cos (30. * PI/180.), where PI is a constant that you've defined to be approximately 3.14159265. I'm not willing to read the Javascript manual to figure out how that particular language does it, because that's not math -- it's programming.

Finally, I'm going to assume that I can write draw(P, Q), where P and Q are points of the plane, to draw a line segment from one to the other.

There's one last thing: you've called the two new points $(n, m)$ and $(n', m')$, which I dislike. I'm going to call them $(a, b)$ and $(u, v)$.

Let's do it, in pseudo-code:

E = L * (cos(alpha), sin(alpha)) // the arrow-end
S = (0.0, 0.0)  // the arrow-start
draw(S, E)      // the arrow shaft

beta = -alpha + 30 // the direction from the arrowhead to 
                // the tip-end that's clockwise from it
v = f*L*(cos(beta), sin(beta)) // the vector from the shaft-end
                         // towards the first tip
P = E + v       // the first tip
draw(E, P)

// Now repeat for the other tip
beta = -alpha - 30 // the direction from the arrowhead to 
                // the tip-end that's COUNTERclockwise from it
                // (note the minus sign)
v = f*L*(cos(beta), sin(beta)) // the vector from the shaft-end
                         // towards the second tip
Q = E + v       // the second tip
draw(E, Q)

And that's it.