I am trying to create a function that will return the 3 points coordinates of arrow head (isoscele triangle) that I want to draw at the end of a line.
The challenge is in the orientation (angle) of the line that can vary between 0 and 360 degree in the quadrant.
I have the following values:
//start coordinates of the line
var x0 = 100;
var y0 = 100;
//end coordinates of the line
var x1 = 200;
var y1 = 200;
//height of the triangle
var h = 10;
//width of the base of the triangle
var w = 30 ;
This is my function until now that returns the two point coordinates of the base of the triangle:
var drawHead = function(x0, y0, x1, y1, h, w){
var L = Math.sqrt(Math.pow((x0 - x1),2)+Math.pow((y0 - y1),2));
//first base point coordinates
var base_x0 = x1 + (w/2) * (y1 - y0) / L;
var base_y0 = y1 + (w/2) * (x0 - x1) / L;
//second base point coordinates
var base_x1 = x1 - (w/2) * (y1 - y0) / L;
var base_y1 = y1 - (w/2) * (x0 - x1) / L;
//now I have to find the last point coordinates ie the top of the arrow head
}
How can I determine the coordinates of the top of the triangle considering the angle of the line?
The head of the arrow will lie along the same line as the body of the arrow. Therefore, the slope of the line segment between (x1, y1) and (head_x, head_y) will be the same as the slope of the line segment between(x0, y0) and (x1, y1). Let's say that dx = head_x - x1 and dy = head_y - y1 and slope = (y1 - y0) / (x1 - x0). Therefore, dy / dx = slope. We also know that dx^2 + dy^2 = h^2. We can solve for dx in terms of slope and h. Then, dy = dx * slope. Once you have dx and dy, you can just add those to x1 and y1 to get the head point. Some pseudocode:
if x1 == x0: #avoid division by 0
dx = 0
dy = h
if y1 < y0:
dy = -h #make sure arrow head points the right way
else:
dy = h
else:
if x1 < x0: #make sure arrow head points the right way
h = -h
slope = (y1 - y0) / (x1 - x0)
dx = h / sqrt(1 + slope^2)
dy = dx * slope
head_x = x1 + dx
head_y = y1 + dy
I see it like this:
A=(x0,y0) , B=(x1,y1)
are the known line endpoints
dir=B-A; dir/=|dir|;
is unit vector of direction of line (||
is vector size)
dir.x=B.x-A.x;'
dir.y=B.y-A.y;
dir/=sqrt((dir.x*dir.x)+(dir.y*dir.y));
so you can use it and its 90 degree rotation as as a basis vectors. Let q
be the 90 degrees rotated vector, in 2D it is easy to obtain:
q.x=+dir.y
q.y=-dir.x
so now you can compute your wanted points:
C=B-(h*dir)+(w*q/2.0);
D=B-(h*dir)-(w*q/2.0);
it is just translation by h
and w/2
along basis vectors