0

I have to generate a block arrow using HTML5 canvas. I found few very good answers for this here.

But my requirement is different. I have to calculate the 6 points shown in the below picture.

I have to write a function which accepts 4 parameters:

  • arrow-tail point
  • arrow-head point (indicated by circle on the picture)
  • thickness of the arrow
  • arrow head size

and it will return the 6 points (shown on the picture) which helps to generate the block arrow.

Thank you.

Block Arrow

Abhishek Raj
  • 480
  • 4
  • 14
  • it can't calculate the width of the whole arrow, and height of the arrow head. You have to give these as parameters to function – sundowatch May 07 '20 at 05:52
  • @sundowatch You are correct. function will get the arrow tail thickness and size of arrow head. But my question is how to find the find the exact point (x,y) – Abhishek Raj May 08 '20 at 14:23

1 Answers1

0

This was not a simple solution. I used trigonometry to find the coordinates of the points.

function calculateArrow(tp, hp, thickness, headSize) {
    // basic info
    // angle between 0,0 and the head
    const a = Math.atan2(hp[0] - tp[0], hp[1] - tp[1]);
    // half the width
    const halfW = thickness / 2;
    // half the head size
    const halfH = headSize / 2;
    
    const halfPi = Math.PI / 2;
    // output :)
    const arrow = [
        [0,0], [0,0], [0,0], [0,0], [0,0], [0,0]
    ];
    
    // here comes the trig!
    // point 1
    arrow[0][0] = Math.cos(a + halfPi) * halfW + tp[0]; // x
    arrow[0][1] = Math.sin(a + halfPi) * halfW + tp[1]; // y
    // point 2
    arrow[1][0] = Math.cos(a - halfPi) * halfW + tp[0];
    arrow[1][1] = Math.sin(a - halfPi) * halfW + tp[1];
    // point 3
    arrow[2][0] = (hp[0] - Math.cos(a) * halfH) + Math.cos(a + halfPi) * halfH;
    arrow[2][1] = (hp[1] - Math.sin(a) * halfH) + Math.sin(a + halfPi) * halfH;
    // point 4
    arrow[3][0] = (hp[0] - Math.cos(a) * halfH) + Math.cos(a + halfPi) * halfW;
    arrow[3][1] = (hp[1] - Math.sin(a) * halfH) + Math.sin(a + halfPi) * halfW;
    // point 5
    arrow[4][0] = (hp[0] - Math.cos(a) * halfH) + Math.cos(a - halfPi) * halfW;
    arrow[4][1] = (hp[1] - Math.sin(a) * halfH) + Math.sin(a - halfPi) * halfW;
    // point 6
    arrow[5][0] = (hp[0] - Math.cos(a) * halfH) + Math.cos(a - halfPi) * halfH;
    arrow[5][1] = (hp[1] - Math.sin(a) * halfH) + Math.sin(a - halfPi) * halfH;
    return arrow;
}
VeryGoodDog
  • 335
  • 2
  • 11