Knowing two points of a rectangle, how can I figure out the other two?

If this quadrilateral is a rectangle (all four angles are 90 degrees), then it can be solved. (if it could be any quadrilateral, then it is not solvable)

if the points are (x1,y1), and (x2, y2), and if the two points are not perfectly vertical (x1 = x2) or horizontal (y1 = y2), then the slope of one edge of the rectangle is

m1 = (y2-y1) / (x2-x1) 

and the slope of the other edge is:

m2 = - 1 / m1

If you know the lengths of the sides, and the midpoints of two opposite sides, then the corrner points are easily determined by adding dx, dy to the midpoints: (if L is length of the sides that the midpoints are on)

dx = Sqrt( L^2 / (1 + m2^2) ) / 2

and

dy = m2 * dx

NOTE: if the points are vertically or horizontally aligned, this technique will not work, although the obvious solution for those degenerative cases is much simpler.


If you know your quadrilateral is a rectangle, then you can use some simple vector maths to find the coordinates of the corners. The knowns are:

  • (x1,y1) - the coordinate of the midpoint on the top line
  • (x2,y2) - the coordinate of the midpoint on the bottom line
  • l1 - the length of the top and bottom lines
  • l2 - the length of the other two lines

First, we find the vector between the two known points. This vector is parallel to the side lines:

(vx, vy) = (x2 - x1, y2 - y1)

We need to normalize this vector (i.e. make it length 1) so we can use it later as a basis to find our coordinates.

vlen = sqrt(vx*vx + vy*vy)

(v1x, v1y) = (vx / vlen, vy / vlen)

Next, we rotate this vector anticlockwise by 90 degrees. The rotated vector will be parallel to the top and bottom lines. 90 degree rotation turns out to just be swapping the coordinates and negating one of them. You can see this just by trying it out on paper. Or take at look at the equations for 2D rotations and substitute in 90 degrees.

(u1x, u1y) = (-v1y, v1x)

Now we have enough information to find the 'top-left' corner. We simply start at our point (x1, y1) and move back along that side by half the side length:

(p1x, p1y) = (x1 - u1x * l1 / 2, y1 - u1y * l1 / 2)

From here we can find the remaining points just by adding the appropriate multiples of our basis vectors. When implementing this you can obviously speed it up by only calculating each unique multiplication a single time:

(p2x, p2y) = (p1x + u1x * l1, p1y + u1y * l1)

(p3x, p3y) = (p1x + v1x * l2, p1y + v1y * l2)

(p4x, p4y) = (p3x + u1x * l1, p3y + u1y * l1)


  function getFirstPoint(x1,y1,x2,y2,l1,l2)
    distanceV = {x2 - x1, y2 - y1}
    vlen = math.sqrt(distanceV[1]^2 + distanceV[2]^2)
    normalized = {distanceV[1] / vlen, distanceV[2] / vlen}
    rotated = {-normalized[2], normalized[1]}
    p1 = {x1 - rotated[1] * l1 / 2, y1 - rotated[2] * l1 / 2}
    p2 = {p1[1] + rotated[1] * l1, p1[2] + rotated[2] * l1}
    p3 = {p1[1] + normalized[1] * l2, p1[2] + normalized[2] * l2}
    p4 = {p3[1] + rotated[1] * l1, p3[2] + rotated[2] * l1}
    points = { p1 , p2 , p3 , p4}
    return p1
end