def snap(self) -> Quadrilateral: """Snaps the sides of the square such that each corner (x,y) is modified to be a corner (x',y') where x' is the integer value closest to x and y' is the integer value closest to y. This, of course, may change the shape to a general quadrilateral, hence the return type. The only exception is when the square is positioned in a way where this approximation will lead it to vanish into a single point. In that case, a call to snap() will not modify this square in any way.""" tempVert = self.vertices v1 = (math.floor(tempVert[0].x + 0.5), math.floor(tempVert[0].y + 0.5)) v2 = (math.floor(tempVert[1].x + 0.5), math.floor(tempVert[1].y + 0.5)) v3 = (math.floor(tempVert[2].x + 0.5), math.floor(tempVert[2].y + 0.5)) v4 = (math.floor(tempVert[3].x + 0.5), math.floor(tempVert[3].y + 0.5)) if (v1 == v2) and (v2 == v3) and (v3 == v4) and (v4 == v1): return Quadrilateral(tempVert[0].x, tempVert[0].y, tempVert[1].x, tempVert[1].y, tempVert[2].x, tempVert[2].y, tempVert[3].x, tempVert[3].y) else: return Quadrilateral(math.floor(tempVert[0].x + 0.5), math.floor(tempVert[0].y + 0.5), math.floor(tempVert[1].x + 0.5), math.floor(tempVert[1].y + 0.5), math.floor(tempVert[2].x + 0.5), math.floor(tempVert[2].y + 0.5), math.floor(tempVert[3].x + 0.5), math.floor(tempVert[3].y + 0.5))
def create_quadrilateral_1_2_3(connected=False): """Create 1, 2 or 3 quadrilaterals per image. Args: connected: contain connected masks or not. Returns: quadrilateral_list: List of Quadrilateral instances. """ threshold_1 = 0.33 threshold_2 = 0.66 random_number = random.random() if random_number < threshold_1: # three quadrilaterals quadrilateral_list = create_quadrilateral_3(connected) elif random_number > threshold_2: # two quadrilaterals quadrilateral_list = create_quadrilateral_2(connected) quadrilateral_list.append(Quadrilateral([])) else: # one quadrilateral quadrilateral_list = [ Quadrilateral(), Quadrilateral([]), Quadrilateral([]) ] return quadrilateral_list
class TestQuadrilateral(TestCase): def setUp(self) -> None: self.q1 = Quadrilateral(5, 5, 2, 5, 1, 0, 4, 0) self.q2 = Quadrilateral(5, 5, 2, 5, 1, 0, 4, 0) self.q3 = Quadrilateral(5, 5, 2, 5, 1, 0, 4, 1) def test_side_lengths(self): self.assertEqual(self.q1.side_lengths(), (3.0, math.sqrt(26), 3.0, math.sqrt(26))) # TODO def test_smallest_x(self): self.assertEqual(self.q1.smallest_x(), 1) # TODO def test_eq(self): self.assertTrue(self.q1.__eq__(self.q2)) self.assertFalse(self.q1.__eq__(self.q3)) self.assertFalse(self.q3.__eq__(self.q2)) def test_ne(self): self.assertTrue(self.q1.__ne__(self.q3)) self.assertTrue(self.q2.__ne__(self.q3)) self.assertFalse(self.q1.__ne__(self.q2)) def test_str(self): self.assertEqual(self.q1.__str__(), "(5, 5), (2, 5), (1, 0), (4, 0)")
def test_smallest_x(self): q1 = Quadrilateral(2, 1, 0, 1, 0, 0, 2, 0) q2 = Quadrilateral(2, 4, -2, 4, -5, 0, 5, 0) # Trapezoid q3 = Quadrilateral(1, 1, 0, 1, 0, 0, 1, 0) self.assertEqual(q1.smallest_x(), 0) self.assertEqual(q2.smallest_x(), -5) self.assertEqual(q3.smallest_x(), 0)
def test__str__(self): print("Testing __str__ method") A = Quadrilateral(0, 0, -3.5, 0.0, -3.5, -7.8, 0, -7.8) B = Quadrilateral(0.0, 0.0, -3.0, 1, -3.0, -2, 0.0, -1.0) aStr = "I am a Quadrilateral with TwoDpoint (0, 0) , TwoDpoint (-3.5, 0) , TwoDpoint (-3.5, -7.8) , TwoDpoint (0, -7.8)" bStr = "I am a Quadrilateral with TwoDpoint (0, 0) , TwoDpoint (-3, 1) , TwoDpoint (-3, -2) , TwoDpoint (0, -1)" randStr = "I am a Quadrilateral with TwoDpoint (0, 0) , TwoDpoint (0, 1) , TwoDpoint (0, 0) , TwoDpoint (0, 0)" self.assertEqual(str(A), aStr) self.assertEqual(str(B), bStr) self.assertNotEqual(str(B), randStr) print("Done testing __str__ method successfully")
def create_rectangle_1(): """Create 1 rectangle per image. Returns: quadrilateral_list: List of Quadrilateral instances. """ quadrilateral_1 = Quadrilateral([]) quadrilateral_1.quadrilateral = quadrilateral_1.create_rectangle() quadrilateral_list = [quadrilateral_1] return quadrilateral_list
def test_smallest_x(self): #TODO self.assertEqual( 0.0, Quadrilateral(1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0).smallest_x()) self.assertEqual( -2.0, Quadrilateral(2.0, 2.0, -2.0, 2.0, -2.0, -2.0, 2.0, -2.0).smallest_x()) self.assertFalse(0.0 == Quadrilateral(2.0, 2.0, -2.0, 2.0, -2.0, -2.0, 2.0, -2.0).smallest_x())
def test_snap(self): print("Testing snap method") A = Square(0, 0.0, -0.4, 0.0, -0.4, -0.4, 0, -0.4) B = Square(0, 0.0, -5, 0.0, -5, -5, 0, -5) C = Square(3.8, 3.7, 1.7, 3.7, 1.7, 1.6, 3.8, 1.6) D = Square(0, 0, -10.5, 0, -10.5, -10.5, 0, -10.5) self.assertEqual(A.snap(), A) self.assertNotEqual(A.snap(), B) self.assertEqual(B.snap(), Quadrilateral(0, 0, -5, 0, -5, -5, 0, -5)) self.assertEqual(C.snap(), Quadrilateral(4, 4, 2, 4, 2, 2, 4, 2)) self.assertNotEqual(D.snap(), Square(0, 0, -11, 0, -11, -11, 0, -11)) print("Done testing snap method successfully")
def test_side_lengths(self): a = Quadrilateral(6, 1.5, 1, 1.5, 0, 0, 5, 0) v = list(a.vertices) l = list(a.side_lengths()) self.assertEqual((v[0].x - v[1].x), l[0].x) self.assertEqual((v[0].y - v[1].y), l[0].y) self.assertEqual((v[0].x - v[3].x), l[1].x) self.assertEqual((v[0].y - v[3].y), l[1].y) self.assertEqual((v[3].x - v[2].x), l[2].x) self.assertEqual((v[3].y - v[2].y), l[2].y) self.assertEqual((v[1].x - v[2].x), l[3].x) self.assertEqual((v[1].y - v[2].y), l[3].y)
def test_side_lengths(self): # coordinates = [2, 1, 0, 1, 0, 0, 2, 0] # coordinates2 = [-3, -2, -5, -2, -5, -3, -3, -3] # coordinates3 = [1, 1, 0, 1, 0, 0, 1, 0] q1 = Quadrilateral(2, 1, 0, 1, 0, 0, 2, 0) q2 = Quadrilateral(2, 4, -2, 4, -5, 0, 5, 0) # Trapezoid q3 = Quadrilateral(1, 1, 0, 1, 0, 0, 1, 0) # Square with self.assertRaises(TypeError) as error: q4 = Quadrilateral(1, 1, 0, 1, 0, 0, 1, 0, 5, 6) # Too many arguments self.assertEqual(q1.side_lengths(), (2, 1, 2, 1)) self.assertNotEqual(q2.side_lengths(), (4, 5, 10, 5)) self.assertEqual(q3.side_lengths(), (1, 1, 1, 1))
def test_side_lengths(self): #TODO self.assertEqual( (1.0, 1.0, 1.0, 1.0), Quadrilateral( 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0).side_lengths()) # Checks if they are equal to each other self.assertEqual((4.0, 4.0, 4.0, 4.0), Quadrilateral(2.0, 2.0, -2.0, 2.0, -2.0, -2.0, 2.0, -2.0).side_lengths()) self.assertFalse((4.0, 4.0, 4.0, 3.0) == Quadrilateral( 2.0, 2.0, -2.0, 2.0, -2.0, -2.0, 2.0, -2.0)) # Checks to makes sure that the value is false
def snap(self): """Snaps the sides of the square such that each corner (x,y) is modified to be a corner (x',y') where x' is the integer value closest to x and y' is the integer value closest to y. This, of course, may change the shape to a general quadrilateral, hence the return type. The only exception is when the square is positioned in a way where this approximation will lead it to vanish into a single point. In that case, a call to snap() will not modify this square in any way.""" vertex = self.vertices # Gets all the vertices of the quadraterial lst = [] # the list that is going to hold for i in range(0, 4): x = vertex[i].x - int( vertex[i].x) # deceimal value of x coordinate y = vertex[i].y - int(vertex[i].y) # Gets the decemial value of x if (x >= 0.5 or (x < 0 and x >= -0.5)): x = float(math.ceil(vertex[i].x)) else: x = float(math.floor(vertex[i].x)) if (y >= 0.5 or (y < 0 and y >= -0.5)): y = float(math.ceil(vertex[i].y)) else: y = float(math.floor(vertex[i].y)) lst.append(x) #adds the elements into the list lst.append(y) for i in range(0, 8, 2): if (lst[i % 8] == lst[(i + 2) % 8] and lst[(i + 1) % 8] == lst[(i + 3) % 8] or lst[i % 8] == lst[(i + 4) % 8] and lst[(i + 1) % 8] == lst[(i + 5) % 8]): return self # Checks if there are any points that are missing after being snapped return Quadrilateral( *lst) # Creates the new quadlaterial with the list
def snap(self): """Snaps the sides of the square such that each corner (x,y) is modified to be a corner (x',y') where x' is the integer value closest to x and y' is the integer value closest to y. This, of course, may change the shape to a general quadrilateral, hence the return type. The only exception is when the square is positioned in a way where this approximation will lead it to vanish into a single point. In that case, a call to snap() will not modify this square in any way.""" newPoint1 = TwoDPoint(Square.regular_round(self.vertices[0].x), Square.regular_round(self.vertices[0].y)) newPoint2 = TwoDPoint(Square.regular_round(self.vertices[1].x), Square.regular_round(self.vertices[1].y)) newPoint3 = TwoDPoint(Square.regular_round(self.vertices[2].x), Square.regular_round(self.vertices[2].y)) newPoint4 = TwoDPoint(Square.regular_round(self.vertices[3].x), Square.regular_round(self.vertices[3].y)) if (newPoint1 == newPoint2 or newPoint1 == newPoint3 or newPoint1 == newPoint4 or newPoint2 == newPoint3 or newPoint2 == newPoint4 or newPoint3 == newPoint4): return self return Quadrilateral(Square.regular_round(self.vertices[0].x), Square.regular_round(self.vertices[0].y), Square.regular_round(self.vertices[1].x), Square.regular_round(self.vertices[1].y), Square.regular_round(self.vertices[2].x), Square.regular_round(self.vertices[2].y), Square.regular_round(self.vertices[3].x), Square.regular_round(self.vertices[3].y)) # TODO
def test_snap(self): newSqu = Square(2.5, 2.5, 0.4, 2.5, 0.4, 0.4, 2.5, 0.4) # Positive Case snappedQuad = Quadrilateral(3.0, 3.0, 0.0, 3.0, 0.0, 0.0, 3.0, 0.0) self.assertEqual(snappedQuad, newSqu.snap()) newSqu = Square(1.7, 1.7, 1.5, 1.7, 1.5, 1.5, 1.7, 1.5) # Positive Cases self.assertEqual(newSqu, newSqu.snap()) newSqu = Square(-2.5, -2.5, -0.6, -2.5, -0.6, -0.6, -2.5, -0.6) # Negative Cases snappedQuad = Quadrilateral(-2.0, -2.0, -1.0, -2.0, -1.0, -1.0, -2.0, -1.0) self.assertEqual(snappedQuad, newSqu.snap()) newSqu = Square(-2.6, -2.6, -0.4, -2.6, -0.4, -0.4, -2.6, -0.4) # Negative Cases snappedQuad = Quadrilateral(-3.0, -3.0, 0.0, -3.0, 0.0, 0.0, -3.0, 0.0) self.assertEqual(snappedQuad, newSqu.snap())
def create_quadrilateral_1_2(connected=False): """Create 1 or 2 quadrilaterals per image. Args: connected: contain connected masks or not. Returns: quadrilateral_list: List of Quadrilateral instances. """ threshold = 0.5 if random.random() > threshold: # two quadrilaterals quadrilateral_list = create_quadrilateral_2(connected) else: # one quadrilateral quadrilateral_list = [Quadrilateral(), Quadrilateral([])] return quadrilateral_list
def test_sort(self): r1 = Rectangle(0, 4, 6, 4, 6, 0, 0, 0) r2 = Rectangle(1, 4, 6, 4, 6, 0, 1, 0) r3 = Rectangle(2, 4, 6, 4, 6, 0, 2, 0) q1 = Quadrilateral(-1, 4, 6, 4, 6, 0, -1, 0) self.assertEqual(ShapeSorter.sort(r1, r2, r3, q1), [q1, r1, r2, r3]) self.assertEqual(ShapeSorter.sort(r1), [r1]) self.assertEqual(ShapeSorter.sort(), []) self.assertNotEqual(ShapeSorter.sort(r2, r3, r1, q1), [r2, r3, r1, q1])
class TestQuadrilateral(unittest.TestCase): def setUp(self) -> None: self.q1 = Quadrilateral(1, 3, 0, 2, -1, 0, 0, 0) self.q2 = Quadrilateral(1, 1, 0, 1, 0, 0, 0, 1) def test_side_lengths(self): # (round(math.sqrt(2), 5), round(math.sqrt(10), 5), round(math.sqrt(1), 5), round(math.sqrt(5), 5)) self.assertEqual(self.q1.side_lengths(), (math.sqrt(2), math.sqrt(10), math.sqrt(1), math.sqrt(5))) self.assertEqual(self.q2.side_lengths(), (1, 1, 1, 1)) def test_smallest_x(self): self.assertEqual(self.q1.smallest_x(), -1) self.assertEqual(self.q2.smallest_x(), 0) def test___eq__(self): self.assertEqual(self.q1 == self.q1, True) self.assertEqual(self.q2 == self.q1, False)
def create_quadrilateral_1(): """Create 1 quadrilateral per image. Returns: quadrilateral_list: List of Quadrilateral instances. """ quadrilateral_1 = Quadrilateral() quadrilateral_list = [quadrilateral_1] return quadrilateral_list
def test_smallest_x(self): print("Testing smallest_x method") A = Quadrilateral(0, 0, -3.5, 0.0, -3.5, -7.8, 0, -7.8) B = Quadrilateral(0.0, 0.0, -3.0, 1, -3.0, -2, 0.0, -1.0) self.assertEqual(A.smallest_x(), -3.5) self.assertNotEqual(B.smallest_x(), -1.0) print("Done testing smallest_x method successfully")
def create_quadrilateral_2(connected=False): """Create 2 quadrilaterals per image. Args: connected: contain connected masks or not. Returns: quadrilateral_list: List of Quadrilateral instances. """ # first quadrilateral quadrilateral_1 = Quadrilateral([]) # second quadrilateral quadrilateral_2 = Quadrilateral([]) while True: quadrilateral_1.update() cur_iter_num = 0 max_iter_num = 5 flag = False while cur_iter_num < max_iter_num: quadrilateral_2.update() if connected: flag = quadrilateral_1.is_soft_overlap(quadrilateral_2) else: flag = quadrilateral_1.is_overlap(quadrilateral_2) cur_iter_num += 1 if flag: continue else: break if flag: continue else: break quadrilateral_list = [quadrilateral_1, quadrilateral_2] return quadrilateral_list
def test___ne__(self): print("Testing __ne__ method") A = Quadrilateral(0, 0, -3.5, 0.0, -3.5, -7.8, 0, -7.8) B = Quadrilateral(0.0, 0.0, -3.0, 1, -3.0, -2, 0.0, -1.0) C = Quadrilateral(0, 0, -1, 0, -1, -1, 0, -1) self.assertFalse(A != A) self.assertTrue(A != B) self.assertFalse(B.__ne__(B)) self.assertTrue(B.__ne__(C)) print("Done testing __ne__ method successfully")
def test_side_lengths(self): print("Testing side_lengths method") A = Quadrilateral(0, 0, -3.5, 0.0, -3.5, -7.8, 0, -7.8) B = Quadrilateral(0.0, 0.0, -3.0, 1, -3.0, -2, 0.0, -1.0) aSide = (3.5, 7.8, 3.5, 7.8) bSide = (3.16228, 1.0, 3.16228, 3.0) self.assertEqual(aSide, A.side_lengths()) self.assertEqual(bSide, B.side_lengths()) self.assertNotEqual(aSide, (0, 0, 0, 0)) print("Done testing side_lengths method successfully")
def snap(self): """Snaps the sides of the square such that each corner (x,y) is modified to be a corner (x',y') where x' is the integer value closest to x and y' is the integer value closest to y. This, of course, may change the shape to a general quadrilateral, hence the return type. The only exception is when the square is positioned in a way where this approximation will lead it to vanish into a single point. In that case, a call to snap() will not modify this square in any way.""" x0 = round(self.vertices[0].x) y0 = round(self.vertices[0].y) x1 = round(self.vertices[1].x) y1 = round(self.vertices[1].y) x2 = round(self.vertices[2].x) y2 = round(self.vertices[2].y) x3 = round(self.vertices[3].x) y3 = round(self.vertices[3].y) if x0 == x1 and x1 == x2 and x2 == x3 and y0 == y1 and y1 == y2 and y2 == y3: return self return Quadrilateral(x0, y0, x1, y1, x2, y2, x3, y3)
def snap(self): """Snaps the sides of the square such that each corner (x,y) is modified to be a corner (x',y') where x' is the integer value closest to x and y' is the integer value closest to y. This, of course, may change the shape to a general quadrilateral, hence the return type. The only exception is when the square is positioned in a way where this approximation will lead it to vanish into a single point. In that case, a call to snap() will not modify this square in any way.""" # Done: Check rounding on .5 flag = True index = 0 new = [] for i in self.vertices: # print(i) if (i.x < 0 and len(findall("\d.5[0]*[1-9]+", str(i.x))) == 0) or \ (i.y < 0 and len(findall("\d.5[0]*[1-9]+", str(i.y))) == 0): if i.x < 0: new.append(int(i.x)) if i.y < 0: new.append(int(i.y)) else: new.append(round(i.x)) new.append(round(i.y)) if index < len(new) - 1: if i.x != new[index] or i.y != new[index + 1]: # print("Original: {}, {}".format(str(i.x), str(i.y))) # print("New: {}, {}".format(str(new[index]), str(new[index + 1]))) # print("At index = {}\n".format(str(index))) flag = False index += 1 # print("{}, {}".format(i.x, i.y)) # print("New List: {}".format(new)) if flag or len(new) != 4: return self new_quad = Quadrilateral(new) # print(str(new_quad)) v = {(new_quad.vertices[0].x, new_quad.vertices[0].y)} for i in new_quad.vertices: v.add((i.x, i.y)) if len(new_quad.vertices) == len(v): return new_quad else: return self # Done
def snap(self) -> 'TwoDPoint': """Snaps the sides of the square such that each corner (x,y) is modified to be a corner (x',y') where x' is the integer value closest to x and y' is the integer value closest to y. This, of course, may change the shape to a general quadrilateral, hence the return type. The only exception is when the square is positioned in a way where this approximation will lead it to vanish into a single point. In that case, a call to snap() will not modify this square in any way.""" vertices = self.vertices point0 = TwoDPoint(int(round(vertices[0].x)), int(round(vertices[0].y))) point1 = TwoDPoint(int(round(vertices[1].x)), int(round(vertices[1].y))) if point0 == point1: return self return Quadrilateral(int(round(vertices[0].x)), int(round(vertices[0].y)), int(round(vertices[1].x)), int(round(vertices[1].y)), int(round(vertices[2].x)), int(round(vertices[2].y)), int(round(vertices[3].x)), int(round(vertices[3].y))) # TODO
def snap(self): """Snaps the sides of the square such that each corner (x,y) is modified to be a corner (x',y') where x' is the integer value closest to x and y' is the integer value closest to y. This, of course, may change the shape to a general quadrilateral, hence the return type. The only exception is when the square is positioned in a way where this approximation will lead it to vanish into a single point. In that case, a call to snap() will not modify this square in any way.""" x_values = [self.vertices[0].x, self.vertices[1].x, self.vertices[2].x, self.vertices[3].x] y_values = [self.vertices[0].y, self.vertices[1].y, self.vertices[2].y, self.vertices[3].y] for i in range(4): if x_values[i] == 0 or isinstance(x_values[i], int): pass elif x_values[i] - math.floor(x_values[i]) < 0.5: x_values[i] = math.floor(x_values[i]) else: x_values[i] = math.ceil(x_values[i]) for i in range(4): if y_values[i] == 0 or isinstance(y_values[i], int): pass elif y_values[i] - math.floor(y_values[i]) < 0.5: y_values[i] = math.floor(y_values[i]) else: y_values[i] = math.ceil(y_values[i]) if x_values[0] == x_values[1] == x_values[2] == x_values[3] and \ y_values[0] == y_values[1] == y_values[2] == y_values[3]: return self # for i in range(4): # print(x_values[i], y_values[i]) return Quadrilateral(x_values[0], y_values[0], x_values[1], y_values[1], x_values[2], y_values[2], x_values[3], y_values[3]) # TODO
def test_snap(self): self.assertEqual(self.s1.snap(), Quadrilateral(6, 3, 3, 3, 3, 0, 6, 0)) self.assertEqual(self.s4.snap(), Quadrilateral(-3, -3, -1, -3, -1, -1, -3, -1)) self.assertEqual(self.s5.snap(), Quadrilateral(4, 4, 2, 4, 2, 2, 4, 2))
2.0, 2.0, -2.0, 2.0, -2.0, -2.0, 2.0, -2.0)) # Checks to makes sure that the value is false def test_smallest_x(self): #TODO self.assertEqual( 0.0, Quadrilateral(1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0).smallest_x()) self.assertEqual( -2.0, Quadrilateral(2.0, 2.0, -2.0, 2.0, -2.0, -2.0, 2.0, -2.0).smallest_x()) self.assertFalse(0.0 == Quadrilateral(2.0, 2.0, -2.0, 2.0, -2.0, -2.0, 2.0, -2.0).smallest_x()) print( Quadrilateral(2.0, 2.0, -2.0, 2.0, -2.0, -2.0, 2.0, -2.0)) # Printing to make sure it gives the right str output print( Quadrilateral(1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0) == (Quadrilateral(2.0, 2.0, -2.0, 2.0, -2.0, -2.0, 2.0, -2.0))) # should print false print( Quadrilateral(1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0) == (Quadrilateral(1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0))) # Should print true if __name__ == "__main__": unittest.main() # Test eq method and more on the str
def setUp(self) -> None: self.q1 = Quadrilateral(5, 5, 2, 5, 1, 0, 4, 0) self.q2 = Quadrilateral(5, 5, 2, 5, 1, 0, 4, 0) self.q3 = Quadrilateral(5, 5, 2, 5, 1, 0, 4, 1)
def test_snap(self): s1 = Square(0, 2.7, 2.7, 2.7, 2.7, 0, 0, 0) s2 = Square(0, 0.1, 0.1, 0.1, 0.1, 0, 0, 0) self.assertEqual(s1.snap(), Quadrilateral(0, 3, 3, 3, 3, 0, 0, 0)) self.assertEqual(s2.snap(), s2)