|
|
|
@ -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) |
|
|
|
|