From 1483e9a25bfc68e38e2798aeb3d282eb18d1858e Mon Sep 17 00:00:00 2001 From: Taylor Bockman Date: Mon, 19 Aug 2019 18:13:26 -0700 Subject: [PATCH] Back PointSet by a list, add point constraint, now move-delete works --- clusterview/points.py | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/clusterview/points.py b/clusterview/points.py index 3d19d50..88b0de5 100644 --- a/clusterview/points.py +++ b/clusterview/points.py @@ -71,7 +71,7 @@ class Point: self.__y + half_point) self.__bottom_right_corner = (self.__x + half_point, - self.__y - half_point) + self.__y - half_point) def __check_window_bounds(self, x, y): """ @@ -122,13 +122,6 @@ class Point: self.__y == other.y and self.__point_size == other.point_size) - def __hash__(self): - """ - Overridden hashing function so it can be used as a dictionary key - for attributes. - """ - return hash((self.__x, self.__y, self.__point_size)) - def __repr__(self): # For some reason I had to split this instead of using one giant @@ -192,8 +185,10 @@ class Attribute: class PointSet: """ - Useful container for points backed by a set to insure point - uniqueness. + Useful container for points. Since points are not hashable (they are + modified in place by move) we are forced to back the PointSet with an + array. However, it is still a "set" in the "uniqueness among all points" + sense because `add_point` will reject a point with a duplicate center. """ def __init__(self, point_size, viewport_width, viewport_height): @@ -206,7 +201,7 @@ class PointSet: @param viewport_height The height of the viewport for bounds calculations. """ - self.__points = set() + self.__points = [] self.__point_size = point_size self.__viewport_width = viewport_width self.__viewport_height = viewport_height @@ -218,7 +213,7 @@ class PointSet: attributes_equal = True - other_points = set(other.points) + other_points = list(other.points) attributes_equal = (attributes_equal and (len(self.__points) == len(other_points))) @@ -316,12 +311,16 @@ class PointSet: for attr in attrs: point.add_attribute(attr) - self.__points.add(point) + if point in self.__points: + # Silently reject a duplicate point (same center). + return + + self.__points.append(point) def remove_point(self, x, y): """ - Removes a point and it's attributes from the point set based - on a bounding box calculation. + Removes a point from the point set based on a bounding + box calculation. Removing a point is an exercise is determining which points have been hit, and then pulling them out of the list. @@ -334,9 +333,6 @@ class PointSet: @param x The x-coordinate. @param y The y-coordinate. """ - - # Find points that match - matched = set(p for p in self.__points if p.hit(x, y)) - - # In place set difference - self.__points = self.__points - matched + for p in self.__points: + if p.hit(x, y): + self.__points.remove(p)