How to make parallel lines in html canvas

I have the following conditions:

  • Points A, B, and C created.
  • Point A to point B will create a string.
  • Parallel lines are created depending on the position of points A, B and C (see the figure below).
  • If you move point A, the lines will also move, but points B and C remain at their respective positions.
  • They can be moved in any position.

I want to create this:

enter image description here

+6
source share
3 answers

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

Picture 1

The coordinates for points A and B are known, and we want to find a function that can be used to calculate the y-coordinate whenever the x-coordinate is known, so that the point (x, y) lies on a straight line. In figure 1:

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

Putting the coordinates A or B in the well-known linear equation y = kx + m , we can calculate m to make the equation complete. Having this equation, for any x coordinate, we can calculate the y coordinate using this equation. The good thing is that it does not depend on the position of points A and B or the deviations (angle) of the line - you have to take care of the special case of vertical / horizontal lines, where y / x will be infinite in accordance with this equation.

Let's get back to your question. Take a look at Figure 2 below:

Figure 2

Here we have a very similar situation, between points A and C there is a straight line, and between points B and D. I assume that point A is in the center of the coordinate system! This, as a rule, will not, but it really is not a limitation, since you can perform a translation that will put A in the center, then do your calculations, and then translate everything back.

Using the technique described at the beginning, you can find a linear equation for the line connecting points A and C, and for the line connecting points B and D (D coordinates can be easily calculated). Suppose you did just that:

AC: y = k1 * x (m is zero when the line passes through center A)

BD: y = k2 * x + m2 (m2 is not equal to zero, since the line does not pass through the center A)

Finally, an algorithm that you could use to draw these parallel lines:

  • Select the space in which you want to take the x-coordinates between x1 and x3. For example, if you want 4 lines, this space will be s = (x3 - x1) / 4 , etc.
  • Set the value x_start = x1 + s (and later x_start += s) and calculate the y-coordinate using the equation for the AC line y_end = k1*x_start . This will give you a point lying on the AC line, and this is the beginning of your line.
  • Similarly, calculate the endpoint that will lie on the line connecting B and D:

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

y_end = k2 * x_end + m2

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

You will need to generate new equations every time point A leaves the current AC line, since each time this happens, the slop of the AC line (and BD) changes the invalidity of the current equations.

I will not write any JS code, but the presence of the logic of a possible solution should give you more than enough information to move forward with your own implementation.

+6
source

Always think, using Context2D , that with the help of transformations ( translate , rotate , scale ) you can save you some math.
With these transformations, you can come up with your own drawing, as if you made a pen: where did you put the pen? where do you move on ( translate )? do you rotate page? Are you getting closer or further from the page ( scale )?

Here you want to start with A and then move on AC.
Every step of the way, you want to draw an AB vector.

Here's how you could encode it, as you can see, just simple vector math here, so if you remember that the AB vector has coordinates (Bx-Ax, By-Ay), 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: Bx - Ax, y: By - Ay }; // compute step : ( C - A ) / stepCount var step = { x: (Cx - Ax) / stepCount, y: (Cy - Ay) / stepCount }; // -- start draw ctx.save(); // Move pen to A ctx.translate(Ax, Ay); 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(Vx, Vy); ctx.stroke(); } // ---------- // legend drawPoint(A, 'A'); drawPoint(B, 'B'); drawPoint(C, 'C'); function drawPoint(P, name) { ctx.beginPath(); ctx.arc(Px, Py, 3, 0, 6.28); ctx.fill(); ctx.strokeText(name, Px + 6, Py + 6); } 
 <canvas id='cv' width=300 height=200></canvas> 
+2
source

Janan has it right, and in simple words, you need the X and Y offsets between the starting points of the two lines, i'e 'point A and point C. When you draw a line starting with C and assuming that it ends with D, you will need to add the same X and Y offsets, for example, if you draw AB with the origin coordinates (100, 150) as follows:

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

And if C should start with (150, 200), the offset here will be X: 50, Y: 50

therefore the CD will 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 lines will be the same. If they are different, the equation will be a little more complicated.

+1
source

All Articles