find if 4 points on a plane form a rectangle?
- find the center of mass of corner points: cx=(x1+x2+x3+x4)/4, cy=(y1+y2+y3+y4)/4
- test if square of distances from center of mass to all 4 corners are equal
bool isRectangle(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4){ double cx,cy; double dd1,dd2,dd3,dd4; cx=(x1+x2+x3+x4)/4; cy=(y1+y2+y3+y4)/4; dd1=sqr(cx-x1)+sqr(cy-y1); dd2=sqr(cx-x2)+sqr(cy-y2); dd3=sqr(cx-x3)+sqr(cy-y3); dd4=sqr(cx-x4)+sqr(cy-y4); return dd1==dd2 && dd1==dd3 && dd1==dd4;}
(Of course in practice testing for equality of two floating point numbers a and b should be done with finite accuracy: e.g. abs(a-b) < 1E-6)
struct point{ int x, y;}// tests if angle abc is a right angleint IsOrthogonal(point a, point b, point c){ return (b.x - a.x) * (b.x - c.x) + (b.y - a.y) * (b.y - c.y) == 0;}int IsRectangle(point a, point b, point c, point d){ return IsOrthogonal(a, b, c) && IsOrthogonal(b, c, d) && IsOrthogonal(c, d, a);}
If the order is not known in advance, we need a slightly more complicated check:
int IsRectangleAnyOrder(point a, point b, point c, point d){ return IsRectangle(a, b, c, d) || IsRectangle(b, c, a, d) || IsRectangle(c, a, b, d);}
- translate the quadrilateral so that one of its vertices now lies at the origin
- the three remaining points form three vectors from the origin
- one of them must represent the diagonal
- the other two must represent the sides
- by the parallelogram rule if the sides form the diagonal, we have a parallelogram
- if the sides form a right angle, it is a parallelogram with a right angle
- opposite angles of a parallelogram are equal
- consecutive angles of a parallelogram are supplementary
- therefore all angles are right angles
- it is a rectangle
it is much more concise in code, though :-)
static bool IsRectangle( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4){ x2 -= x1; x3 -= x1; x4 -= x1; y2 -= y1; y3 -= y1; y4 -= y1; return (x2 + x3 == x4 && y2 + y3 == y4 && x2 * x3 == -y2 * y3) || (x2 + x4 == x3 && y2 + y4 == y3 && x2 * x4 == -y2 * y4) || (x3 + x4 == x2 && y3 + y4 == y2 && x3 * x4 == -y3 * y4);}
(If you want to make it work with floating point values, please, do not just blindly replace the int declarations in the headers. It is bad practice. They are there for a reason. One should always work with some upper bound on the error when comparing floating point results.)