简体   繁体   中英

C points forming rectangle

I have this piece of code for finding out whether 4 x,y coordinates make a rectangle which works perfectly well, but, I need to make it so that it only works if the points are entered in the correct order, ie: Point #1: 0 0 Point #2: 20 0 Point #3: 20 50 Point #4: 0 50 would say "Is a rectangle" but : Point #1: 0 0 Point #2: 20 0 Point #3: 0 50 Point #4: 20 50 Would say "Is not a rectangle" (because the points arent in the right order)

This is what i have:

 static bool IsRectangle(float x1, float y1, float x2, float y2,
                       float x3, float y3, float x4, float 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);
    }

Im totally unsure as to how to limit it to only work in the correct order... :( Thank you

Note: This method only works for rectangles aligned with the axes.

Think about the delta X/Y between adjacent points. In the first case you have:

  • ( 20, 0)
  • ( 0, 50)
  • (-20, 0)

and in the second case you have:

  • ( 20, 0)
  • (-20, 50) <===
  • ( 20, 0)

The highlighted line shows you what to look for if the points are out of order...check for delta X/Y between adjacent points where both are non-zero.

In terms of code something like the following should work (not tested):

static bool IsRectangle(float x1, float y1, float x2, float y2,
                   float x3, float y3, float x4, float y4)
{
    int dx1 = x2 - x1;
    int dx2 = x3 - x2;
    int dx3 = x4 - x3;
    int dy1 = y2 - y1;
    int dy2 = y3 - y2;
    int dy3 = y4 - y3;

    x2 -= x1; x3 -= x1; x4 -= x1; y2 -= y1; y3 -= y1; y4 -= y1;

    return
        (dx1 == 0 || dy1 == 0) && (dx2 == 0 || dy2 == 0) && (dx3 == 0 || dy3 == 0) &&
        ((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));
}

Check each pair of consecutive segments to ensure they're perpendicular: (x1,y1) --> (x2,y2) perpendicular to (x2,y2) --> (x3,y3), (x2,y2) --> (x3,y3) perpendicular to (x3,y3) --> (x4,y4), etc., ending with (x4,y4) --> (x1,y1). If so, you have a rectangle.

So for each segment, you need to subtract the endpoints to get a vector for the segment... then for each (consecutive) pair of these vectors check that the sum of product of the X components and the product of the Y components is zero, indicating that they're orthogonal.

For example:

static bool IsRectangle(float x1, float y1, float x2, float y2, 
                        float x3, float y3, float x4, float y4)
{
  return !( ((x2-x1)*(x3-x2) + (y2-y1)*(y3-y2)) ||
            ((x3-x2)*(x4-x3) + (y3-y2)*(y4-y3)) ||
            ((x4-x3)*(x1-x4) + (y4-y3)*(y1-y4)) ||
            ((x1-x4)*(x2-x1) + (y1-y4)*(y2-y1)) );
}

The example above may need to be adjusted to allow for rounding errors if very large or non-integer coordinates are used, though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM