# How to make a parallel lines in html canvas

450
November 22, 2016, at 1:32 PM

I have these conditions:

1. Point A, B and C are created.
2. Point A to Point B will create a line.
3. Parallel lines are created depending on the position of Point A, B and C (refer to the figure below).
4. If you move Point A, the lines will also move but Points B and C remain on their respective positions.
5. They can be moved at any position.

What I want is to create this:

Consider the figure 1 below (I'm sure you already know this basic 2D geometry but without this my answer would be incomplete):

Coordinates for points A and B are known and we want to find function that can be used to calculate y-coordinate whenever x-coordinate is known, in such a way that point (x,y) lies on the line. From the figure 1:

k = tan(alpha) = (y2 - y1) / (x2 - x1) - the slope of line

Putting coordinates of either A or B into well known line equation `y = kx + m` we can calculate `m` to make the equation complete. Having this equation, for any coordinate x we can calculate coordinate y using this equation. The good thing about it is that it doesn't depend on the position of point A and B or slop (angle) of the line - you will have to take care of the special case of vertical/horizontal lines where y/x will be infinite according to this equation.

Back to your question. Take a look at figure 2 below:

We have very similar situation here, there is a line between points A and C, and line between points B and D. I assumed that point A is at the center of the coordinate system! This generally won't be the case but this is really not a restriction as you can perform translation that will put A in the center, then make your calculations and then translate everything back.

Using the technique described at the beginning, you can find the line equation for the line that connects A and C points and for the line that connects B and D points (D coordinates can be easily calculated). Let's assume you did just that:

A-C: y = k1*x (m is zero as line goes through the center A)

B-D: y = k2*x + m2 (m2 is not zero as line doesn't go through the center A)

Finally the algorithm you could use to draw these parallel lines:

1. Choose a space with which you want to take x-coordinates between x1 and x3. For example, if you want 4 lines this space will be `s = (x3 - x1) / 4` and so on.
2. Set value `x_start = x1 + s (and later x_start += s)`, and calculate y-coordinate using the equation for A-C line `y_end = k1*x_start`. This will give you point that lies on the line A-C and this is the start of your line.
3. Similarly, calculate the end point that will lie on the line that connects B and D:

x_end = x2 + s (later x_end += s)

y_end = k2*x_end + m2

1. Using these equations calculate points (x_start,y_start) and (x_end,y_end) for all lines that you want to draw (there is `|x3 - x1| / desired_num_of_lines` of them).

You'll have to form new equations each time point A moves out of the current A-C line, as every time this happens the slop of the A-C (and B-D) line changes invalidating the current equations.

I'm not going to write any JS code, but having the logic behind the possible solution should give you more then enough information to move forward with you own implementation.

Always think, when using the `Context2D`, that using the transforms (`translate`, `rotate`, `scale`), can spare you some math.
With those transforms you can think of your drawing like you would do with a pen : where do you put the pen ? where do you move next (`translate`) ? do you `rotate` the page ? do you get closer or further from the page (`scale`) ?

Here you want to start at A, then move along AC.
Each step on the way, you want to draw the AB vector.

Here's how you could code it, as you see, just simple vector math here, so if you remember that AB vector has (B.x-A.x, B.y-A.y) coordinates, you know most of the math you'll need.

``````// boilerPlate
var ctx = document.getElementById('cv').getContext('2d');
ctx.strokeStyle = '#000';

// params :  Points : {x,y}
var A, B, C;
A = { x: 20,  y: 170  };
B = { x: 80,  y: 60   };
C = { x: 140, y: 120 };
// param : number of lines to draw.
var stepCount = 5;

//  ----------

// compute AB vector = B - A
var AB = { x: B.x - A.x,  y: B.y - A.y };
// compute step : ( C - A ) / stepCount
var step = { x: (C.x - A.x) / stepCount,  y: (C.y - A.y) / stepCount };

// -- start draw
ctx.save();
// Move pen to A
ctx.translate(A.x, A.y);
for (var i = 0; i <= stepCount; i++) {
// draw AB vector at current position
ctx.lineWidth= ( i==0 || i==stepCount ) ? 2 : 1 ;
drawVector(AB);
// move pen one step further
ctx.translate(step.x, step.y);
}
ctx.restore();
// --

// draws vector V at the current origin ((0,0)) of the context.
function drawVector(V) {
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(V.x, V.y);
ctx.stroke();
}

//  ----------
//   legend

drawPoint(A, 'A');
drawPoint(B, 'B');
drawPoint(C, 'C');

function drawPoint(P, name) {
ctx.beginPath();
ctx.arc(P.x, P.y, 3, 0, 6.28);
ctx.fill();
ctx.strokeText(name, P.x + 6, P.y + 6);
}``````
``<canvas id='cv' width=300 height=200></canvas>``

Džanan has it right, and in simple terms, you need the X and Y offsets between the starting points of the two lines, i'e' point A and point C. When drawing the line that starts at C, and assuming that it ends at D, you will need to add the same X and Y offsets, e.g., if you draw AB with starting coordinates (100, 150) as follows:

``````context.beginPath();
context.moveTo(100, 150);
context.lineTo(450, 50);
context.stroke();
``````

And if C has to start at (150, 200), the offset here would be X: 50, Y:50

so CD would be drawn as

``````context.beginPath();
context.moveTo(150, 200);
context.lineTo((450+50), (50+50));
context.stroke();
``````

Now this assumes that the length of both the lines are going to be same. If they are to differ, the equation will be slightly more complex.

POPULAR ONLINE

#### Call Ajax for next page of pagination in SwiperJS ### Submit button doesn't work in a form containing table with foreach

I have a form which contains a table. In the table, I used a foreach to fetch multiple data.

284 I'm trying to load a widget in javascript which creates a HTML table once it has been loaded. Inside the table are links where I'd like to remove the href attribute.

425 ### Print content of scroll x and y direction div

My problem is that,.

331 ### loop through array to find matches and return every possible solution

I have a small input field where this code gets activated everytime a key is pressed inside it. But it now only prints "found something" when the name exacly matches what you type in the input field.

357