Identifying if list of points exists in rectangle

77 views Asked by At

I'm new to Python and trying to determine if a list of points is inside a rectangle. I think my issue might have to do with iterating on integers but I'm not sure how to resolve it.

However, I tried the following solution for a list of points and was unsuccessful:


def allIn(firstCorner=(0,0), secondCorner=(0,0), pointList=[]):


  fx = firstCorner[0] 
  fy = firstCorner[1] 
  sx = secondCorner[0] 
  sy = secondCorner[1]

  import numpy as np

  for i in np.array(pointList):

    if i[0] >= fx and i[0] <= sx and i[1] >= fy and i[1] <= sy: 
        return True
    if i[0] <= fx and i[0] >= sx and i[1] <= fy and i[1] >= sy:
        return True
    if i[0] >= fx and i[0] <= sx and i[1] <= fy and i[1] >= sy: 
        return True
    if i[0] <= fx and i[0] >= sx and i[1] >= fy and i[1] <= sy:
        return True
    if pointList == []: 
        return False
    else:
        return False

The code seems to go through without error but it's not providing the correct answers. For example, it says allIn((0,0), (5,5), [(1,1), (0,0), (5,6)]) is True when it should return False. I think it's only referencing the first point in pointList. i.e.

allIn((0,0),(5,5),[(0,-1), (0,0), (5,6)]) returns False, but allIn((0,0), (5,5), [(1,1), (0,0), (5,6)]) returns True.

It also doesn't give any answer at all for allIn((0,0), (5,5), []).

It's important to note that firstCorner and secondCorner are not necessarily the left and right corners. We assume that the first parameter does not always represent the left corner of the rectangle and the second parameter is not always the right corner. The function should work correctly either way.

I was trying to avoid using libraries for this question (the assignment mentioned not to), but even with a proposed shapely.geometry solution, I still can't figure out how to iterate over the pointList rather than just a single point. Thank you in advance for any assistance you might be able to provide - I really appreciate it!

1

There are 1 answers

4
Tim Roberts On

So, you only return within the loop if you find an outsider. Otherwise, you have to run through the ENTIRE list before you can return True. This works. The final "not not" thing just converts the present or absence of the list to True or False.

def allIn(firstCorner=(0,0), secondCorner=(0,0), pointList=[]):

    left,right = sorted((firstCorner[0],secondCorner[0]))
    top,bottom = sorted((firstCorner[1],secondCorner[1]))

    for point in pointList:
        if not (left <= point[0] <= right and top <= point[1] <= bottom):
            return False

    return not not pointList

print(allIn((0,0), (5,5), [(0,-1), (0,0), (5,6)]))
print(allIn((0,0), (5,5), [(1,1), (0,0)]))
print(allIn((0,0), (5,5), [(1,1), (0,0), (5,6)]))
print(allIn((0,0), (5,5), []))

Output:

False
True
False
False

Another alternative is to write a function to check a single point, and then use the all or any function to handle the list part.

def inside(upperleft, lowerright,  point):
    return upperleft[0] <= point[0] <= lowerright[0] and upperleft[1] <= point[1] <= lowerright[1]

def allIn(firstCorner=(0,0), secondCorner=(0,0), pointList=[]):
    if not pointList:
        return False
    left,right = sorted((firstCorner[0],secondCorner[0]))
    top,bottom = sorted((firstCorner[1],secondCorner[1]))
    return all(inside((left,top),(right,bottom),pt) for pt in pointList)


print(allIn((0,0), (5,5), [(0,-1), (0,0), (5,6)])) 
print(allIn((0,0), (5,5), [(1,1), (0,0)]))
print(allIn((0,0), (5,5), [(1,1), (0,0), (5,6)]))
print(allIn((0,0), (5,5), []))