Find number of rectangles from a given set of coordinates
Asked Answered
W

7

12

I have to find max number of rectangles from a given set of coordinates.

Consider the following coordinates are given in an X Y coordinate system 3 10, 3 8, 3 6, 3 4, 3 0, 6 0, 6 4, 6 8, 6 10,

How can I find if the following coordinates form a rectangle (3,0) (3,4) (6,4) (6,0)

Running time constraint: 0.1 sec

Thank you

Welldressed answered 5/10, 2013 at 22:7 Comment(9)
Decide what is the question. 4 point form a rectangle or how many rectangles can be formed in given points?Staphylorrhaphy
Both of them actually, how can I verify 4 points form a rectangle and how can I find max number of possible rectanglesWelldressed
Is this an ACM question?Staphylorrhaphy
Not an ACM one, from a book with practice questionsWelldressed
what is the maximum number of given points?Staphylorrhaphy
are all given points are integers?Staphylorrhaphy
What are the maximum values of x and yStaphylorrhaphy
answer to all of these questions will give different solutionStaphylorrhaphy
please try to answer my questions so I can give you the most appropriate solution for the situation.Staphylorrhaphy
U
9

For every pair of points, say (x1, y1) and (x2, y2) consider it to be the diagonal of some rectangle. If there exist points (x1, y2) and (x2, y1) in the initial set then we have found our rectangle. It should be noted that there will exist 2 diagonals which will represent the same rectangle so we divide the final answer by 2.

This will work only for rectangles parallel to x-axis or y-axis.

PseudoCode C++:

answer = 0;
set<pair<int, int>> points;

for(auto i=points.begin(); i!=std::prev(points.end()); i++)
{
    for(auto j=i+1; j!=points.end(); j++)
    {
        pair<int, int> p1 = *i;
        pair<int, int> p2 = *j;

        if(p1.first == p2.first || p1.second == p2.second)
            continue;

        pair<int, int> p3 = make_pair(p1.first, p2.second);
        pair<int, int> p4 = make_pair(p2.first, p1.second);

        if(points.find(p3) != points.end() && points.find(p4) != points.end())
            ++answer;
    }
}

return answer/2;
Unsnarl answered 30/9, 2019 at 17:40 Comment(2)
help me here. is (1,1) (2,2) (3,1) (2,0) a rectangle?Staphylorrhaphy
@Staphylorrhaphy - It is a rectangle but its sides are not parallel to the coordinate axesUnsnarl
P
10

Separate your points in lists of 'y' coordinate, grouped by 'x' coordinate. In your case you would have two sorted lists:

3: [0,4,6,8,10]
6: [0,4,8,10]

Doing the intersection of both lists you get: [0,4,8,10]

Any two of those would form a rectangle:

[0,4] => (3,0), (3,4), (6,0), (6,4)
[0,8] => (3,0), (3,8), (6,0), (6,8)
[4,8] => (3,4), (3,8), (6,4), (6,8)
...

This solution only works for orthogonal rectangles, this is, with sides parallel to x,y axis.

Prepay answered 28/10, 2013 at 21:38 Comment(3)
Amazing, I've been struggling my head to find a way to achieve thisAntimicrobial
I just saw your note regarding the orthogonal. sryStaphylorrhaphy
There should be a way to rotate after the orthogonal case though. Just changing the coordinate calculation.Fy
U
9

For every pair of points, say (x1, y1) and (x2, y2) consider it to be the diagonal of some rectangle. If there exist points (x1, y2) and (x2, y1) in the initial set then we have found our rectangle. It should be noted that there will exist 2 diagonals which will represent the same rectangle so we divide the final answer by 2.

This will work only for rectangles parallel to x-axis or y-axis.

PseudoCode C++:

answer = 0;
set<pair<int, int>> points;

for(auto i=points.begin(); i!=std::prev(points.end()); i++)
{
    for(auto j=i+1; j!=points.end(); j++)
    {
        pair<int, int> p1 = *i;
        pair<int, int> p2 = *j;

        if(p1.first == p2.first || p1.second == p2.second)
            continue;

        pair<int, int> p3 = make_pair(p1.first, p2.second);
        pair<int, int> p4 = make_pair(p2.first, p1.second);

        if(points.find(p3) != points.end() && points.find(p4) != points.end())
            ++answer;
    }
}

return answer/2;
Unsnarl answered 30/9, 2019 at 17:40 Comment(2)
help me here. is (1,1) (2,2) (3,1) (2,0) a rectangle?Staphylorrhaphy
@Staphylorrhaphy - It is a rectangle but its sides are not parallel to the coordinate axesUnsnarl
S
4

To check if 4 points form a rectangle:

  1. for every two points calculate the distance. store all in array of floats.
  2. sort the array.

you will have a[0] = a[1], a[2] = a[3], a[4] = a[5]

Staphylorrhaphy answered 5/10, 2013 at 22:22 Comment(8)
Your condition is neccessary but not sufficient: a parallelorgram will satisfy it as well. And comparing floating point numbers for exact equality is a bad idea due to rounding errors.Felspar
I'm a bit puzzled about this solution. What about this set of points (a,b,c,d) = (1,2),(2,1),(3,1),(4,2) The distance between a and b is the same as the distance between c and d, but they do not form a rectangle.Prepay
you must have six values. a-b = c-d, a-d = b-c, a-c = b-d. last one is the diagonals.Staphylorrhaphy
But, if you had a much longer list of points, say 100, how could you find the 3 pairs of distances needed for a rectangle between the 10k pair of distances?Prepay
I commented on the above question with alot of questions. I need alot of information to provide an appropriate solution for each situation. answer them and I will tell you.Staphylorrhaphy
Ok, so your answer only checks if a set of 4 points is a rectangle or not, but does not solve the problem of how to find the number of rectangles on a finite set of points. I blame the author of the question, for asking two separate questions :PPrepay
I was going to continue with editing to answer full question. but, he didn't edit his question and answer my questions. therefore, he didn't really know what input specification he have. so, he was satisfied with the answer. are you going to answer those questions?Staphylorrhaphy
@Mvg no parallelorgram does not satisfy it. I thought I responded to that! a[4] != a[5] in parallelorgramsStaphylorrhaphy
F
1

How can I find if the following coordinates form a rectangle

Check whether the difference vectors are orthogonal, i.e. have dot product zero.

This does not check whether these coordinates are included in your list. It also does not check whether the rectangle is aligned with the coordinate axes, which would be a far simpler problem.

If you want to find all rectangles in your input, you could do the above check for all quadruples. If that is inacceptable for performance reasons, then you should update your question, indicating what kind of problem size and performance constrainst you are facing.

Felspar answered 5/10, 2013 at 22:20 Comment(1)
If I understood it right, your suggestion is to iterate over all quadruples of points (O(n^4)) and check if v . w = 0 for each quadruple, where v = p1-p2 and w = p3-p4 , right? What exactly do you mean with "this does not check whether these coordinates are included in your list" ? You are iterating over the given points, so why would you need that check?Strongarm
R
0

My humble submission

enter image description here

I assume number of optimizations is possible.

Rogerson answered 28/1, 2020 at 10:38 Comment(0)
A
0

My approach is to

  • Traverse over every point
  • Check which all points are there just above this point and then store Y coordinates of that points which form a line
  • Next time when I find again the same Y coordinate that means we have found 1 rectangle
  • Keep traversing all other points again doing the same thing.

My solution runs in O(n^2) but this will only be rectangle which are parallel to X or Y axis.

Here is my code for above approach:

def getRectangleCount(coordinate):
    n = len(coordinate)
    y_count = dict()
    ans = 0
    for i in range(n):
        x, y = coordinate[i]
        for j in range(n):
            dx = coordinate[j][0]
            dy = coordinate[j][1]
            if y < dy and x == dx:
                ans += y_count.get((y, dy), 0)
                y_count[(y, dy)] = y_count.get((y, dy), 0) + 1
    return ans


coordinate = [[3, 10], [3, 8], [3, 6], [3, 4], [3, 0], [6, 0], [6, 4], [6, 8], [6, 10]]
print(getRectangleCount(coordinate))
Acred answered 14/3, 2021 at 11:30 Comment(0)
C
0

Here's a solution that finds all unique rectangles (not only those parallel to the x or y-axis) in a given list of coordinate points in O(n^4) time.

Pseudocode:

// checks if two floating point numbers are equal within a given 
// error to avoid rounding issues
bool is_equal(double a, double b, double e) {
    return abs(a - b) < e;
}

// computes the dot product of the vectors ab and ac
double dot_product(Point a, Point b, Point c) {
    return (b.x - a.x) * (c.x - a.x) + (b.y - a.y) * (c.y - a.y);
}

// find all rectangles in a given set of coordinate points
List<Rectangle> find_rectangles(List<Point> points) {
    List<Rectangle> rectangles;

    // sort points in ascending order by first comparing x than y value
    sort(points);

    for (int a = 0; a < points.size(); ++a)
        for (int b = a + 1; a < points.size(); ++b)
            for (int c = b + 1; c < points.size(); ++c)
                for (int d = c + 1; d < points.size(); ++d)
                    // check all angles
                    if (is_equal(dot_product(points[a], points[b], points[c]), 0.0, 1e-7) &&
                        is_equal(dot_product(points[b], points[a], points[d]), 0.0, 1e-7) &&
                        is_equal(dot_product(points[d], points[b], points[c]), 0.0, 1e-7) &&
                        is_equal(dot_product(points[c], points[a], points[d]), 0.0, 1e-7))
                        // found rectangle
                        rectangles.add(new Rectangle(points[a], points[c], points[d], points[b]));

    return rectangles;
}

Explanation:

For a given set of points A, B, C, D to define a rectangle we can check if all angles are 90° meaning all non-parallel sides are orthogonal.

Since we can check this property just by the dot product being 0 this is the most efficient way (instead of having to do square-root calculations for computing side lengths).

Sorting the points first avoids checking the same set of points multiple times due to permutations.

Cremate answered 13/1, 2022 at 16:9 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.