Given two diagonally opposite points on the rectangle, how to calculate the other two points

I am trying to resize a div element while dragging from the top right or bottom left corners.

To calculate the new width and height, I need to know the other two points on the rectangle

How can I get these values, given only two points and the degree of rotation?

look at the image I added to fully understand this problem plus, the div can also rotate (centered start)

  • to clarify my question: the goal is to resize the div by dragging the mouse from the upper right corner to the lower left. and then resize the image so the width will be the distance between mouseX to the left side. and the height will be from mouseY to the bottom. for this, I should not calculate both the upper left corner and the lower right corner when the mouse cursor moves. thanks.

enter image description here

+5
source share
4 answers

Knowing two opposite corner points as absolute coordinates and angle. (X1, y1) - (x3, y3) is essentially a rotating line representing the diagonal of the rectangle, so we can do:

  • Find your middle and segment length (middle to corner)
  • Disable two dots around the middle.
  • Use abs () with differences to get width and height

Main code

// find center point (origin) using linear interpolation var mx = x1 + (x3 - x1) * 0.5, my = y1 + (y3 - y1) * 0.5, cos = Math.cos(-angle), sin = Math.sin(-angle); // unrotate known points (using negative of known angle) var x1u = cos * (x1-mx) - sin * (y1-my) + mx, y1u = sin * (x1-mx) + cos * (y1-my) + my, x3u = cos * (x3-mx) - sin * (y3-my) + mx, y3u = sin * (x3-mx) + cos * (y3-my) + my; // Get width and height: var width = Math.abs(x3u - x1u), height = Math.abs(y3u - y1u); 

To get points for missing angles, simply rotate the new points made from a combination of broken points:

 cos = Math.cos(angle); sin = Math.sin(angle); // Use known coordinates for the new points: var x2u = x1u, y2u = y3u, x4u = x3u, y4u = y1u; // rotate new points using angle var x2 = cos * (x2u-mx) - sin * (y2u-my) + mx, y2 = sin * (x2u-mx) + cos * (y2u-my) + my, x4 = cos * (x4u-mx) - sin * (y4u-my) + mx, y4 = sin * (x4u-mx) + cos * (y4u-my) + my; 

Graphing demo

The demo will calculate the "missing" points, width and height and show the result for each step. Entrance angle - make sure it works independently.

 var ctx = document.querySelector("canvas").getContext("2d"); ctx.fillStyle = "#e00"; document.querySelector("input").addEventListener("change", update); function update() { // Test rect: 50,25 - 350, 175, center: 200,200, W: 300, H: 150 // generate x1,y1 - x3,y3 known points so we have something to work with: var value = typeof this.value !== "undefined" ? +this.value : 30, angle = value * Math.PI / 180, x1 = Math.cos(angle) * (50-200) - Math.sin(angle) * (275-200) + 200, y1 = Math.sin(angle) * (50-200) + Math.cos(angle) * (275-200) + 200, x3 = Math.cos(angle) * (350-200) - Math.sin(angle) * (125-200) + 200, y3 = Math.sin(angle) * (350-200) + Math.cos(angle) * (125-200) + 200; // Initial Visuals: rotated rect, known corner points ctx.clearRect(0,0,400,400); ctx.strokeStyle = "#000"; ctx.translate(200,200); ctx.rotate(angle); ctx.translate(-200,-200); ctx.strokeRect(50, 125, 300, 150); ctx.setTransform(1,0,0,1,0,0); ctx.fillStyle = "#e00"; ctx.fillRect(x1-2, y1-2, 4, 4); ctx.fillText("x1,y1", x1+5, y1); ctx.fillRect(x3-2, y3-2, 4, 4); ctx.fillText("x3,y3", x3+5, y3); // Step 1: find center point (origin) var mx = x1 + (x3 - x1) * 0.5, my = y1 + (y3 - y1) * 0.5; ctx.fillRect(mx-2, my-2, 4, 4); // draw center point // unrotate known points (negative angle) var x1u = Math.cos(-angle) * (x1-mx) - Math.sin(-angle) * (y1-my) + mx, y1u = Math.sin(-angle) * (x1-mx) + Math.cos(-angle) * (y1-my) + my, x3u = Math.cos(-angle) * (x3-mx) - Math.sin(-angle) * (y3-my) + mx, y3u = Math.sin(-angle) * (x3-mx) + Math.cos(-angle) * (y3-my) + my; ctx.fillStyle = "#00c"; ctx.fillRect(x1u-2, y1u-2, 4, 4); ctx.fillText("x1u,y1u", x1u+5, y1u-5); ctx.fillRect(x3u-2, y3u-2, 4, 4); ctx.fillText("x3u,y3u", x3u+5, y3u); // To get width and height: var width = Math.abs(x3u - x1u), height = Math.abs(y3u - y1u); ctx.fillText("Size: " + ((width+0.5)|0) + " x " + ((height+0.5)|0), 0, 10); // Mix known coordinates var x2u = x1u, y2u = y3u, x4u = x3u, y4u = y1u; // show unrotated points ctx.fillStyle = "#0c0"; ctx.fillRect(x2u-2, y2u-2, 4, 4); ctx.fillText("x2u,y2u", x2u+5, y2u-5); ctx.fillRect(x4u-2, y4u-2, 4, 4); ctx.fillText("x4u,y4u", x4u+5, y4u); // draw lines between unrotated points to show we have an actual rectangle ctx.strokeStyle = "#777"; ctx.beginPath(); ctx.moveTo(x1u, y1u); ctx.lineTo(x2u, y2u); ctx.lineTo(x3u, y3u); ctx.lineTo(x4u, y4u); ctx.closePath(); ctx.stroke(); // rotate new points using angle var x2 = Math.cos(angle) * (x2u-mx) - Math.sin(angle) * (y2u-my) + mx, y2 = Math.sin(angle) * (x2u-mx) + Math.cos(angle) * (y2u-my) + my, x4 = Math.cos(angle) * (x4u-mx) - Math.sin(angle) * (y4u-my) + mx, y4 = Math.sin(angle) * (x4u-mx) + Math.cos(angle) * (y4u-my) + my; // show new coordinates ctx.fillStyle = "#f0f"; ctx.fillRect(x2-2, y2-2, 4, 4); ctx.fillText("x2,y2", x2+5, y2); ctx.fillRect(x4-2, y4-2, 4, 4); ctx.fillText("x4,y4", x4+5, y4); } update(); 
 <script src="https://cdn.rawgit.com/epistemex/slider-feedback/master/sliderfeedback.min.js"></script> Angle: <input type=range min=0 max=360 value=30><br><canvas width=400 height=400></canvas> 
+7
source

I think you should use Trigo for this, but since I'm terrible with these, here is a stupid way without any Maths to get the absolute positioning of your points.

 var tl= document.querySelector('#tl').getBoundingClientRect(); var tr= document.querySelector('#tr').getBoundingClientRect(); var br= document.querySelector('#br').getBoundingClientRect(); var bl= document.querySelector('#bl').getBoundingClientRect(); var pointsList = { tl:[tl.left, tl.top], tr:[tr.left, tr.top], br:[br.left, br.top], bl:[bl.left, bl.top], }; for(var p in pointsList){ document.querySelector('#r').innerHTML+=p+' '+pointsList[p].join(' , ')+'<br>'; } 
 #main{background-color:#CCC;height: 120px; width: 70px; position: relative; transform: rotate(30deg)} .dot{ width: 1px; height: 1px; position: absolute; background-color:#000;} #tl{top:0; left:0;} #tr{top:0; right:0;} #br{bottom:0; right:0;} #bl{bottom:0; left:0;} 
 <div id="main"> <div id="tl" class="dot"></div> <div id="tr" class="dot"></div> <div id="br" class="dot"></div> <div id="bl" class="dot"></div> </div> <div id="r"> 
0
source

Ken's comments are a good starting point. You can take the tangent, the inverse of the diagonal of the diagonal, and add degrees rotated to find the angle between the diagonal and the side.

 m = (y3-y1)/(x3-x1) diag_angle = arctan(m) diag_angle_adjusted = diag_angle + rotation 

This will give you the angle between the diagonal and the lower left side. Then you can use the distance formula to get the length of the diagonal.

 diag_length = (y3 - y1)^2 + (x3-x1)^2 

To find the length of the lower left, you must use the cos formula, and for the lower right, you must use sin.

 bot_left = diag_length*cos(diag_angle_adjusted) 

This will allow you to get the lengths of the sides and go on to calculate the other x and y. For instance,

 sin(rotation) = (y2 - y4)/bot_left 

After solving for y4, its pretty easy to solve for x4 using cos.

I answer from my phone and have not officially tested this, but this approach should work. I hope tomorrow I will have time to draw an answer if this is not clear.

Good luck And make sure your signs are correct for rotation.

0
source

Naming point (x1, x2) p1, etc. denoting the rotation angle rot (minus 30deg in the example), denoting the distance frop p1 to p4 d14, etc.

Using the fact that the length of the projection of the vector on the axis is the absolute value of the point product of this vector on the ubit vector in this direction,

the length p1-p4 is the point product (cos (rot), sin (rot)) with (x3 - x1, y3 - y1).

 d14 = abs((x3 - x1)*cos(rot) + (y3 - y1)*sin(rot)) d12 = abs((x3 - x1)*cos(rot + 90) + (y3 - y1)sin(rot +90)) 

If you need p2 and p4 coordinates

 x4 = x1 + d14 * cos(rot) y4 = y1 + d14 * sin(rot) x2 = x1 + d12 * cos(rot + 90) y2 = y1 + d12 * sin(rot + 90) 

(created on my tablet to be reviewed when I work on my laptop)

0
source

All Articles