You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
1.6 KiB
73 lines
1.6 KiB
5 years ago
|
from typing import List
|
||
|
|
||
|
import numpy as np
|
||
|
|
||
|
from .geometry import dist
|
||
|
from .point import Point
|
||
|
|
||
|
|
||
|
class Cluster:
|
||
|
"""
|
||
|
Represents a cluster of points.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, mean: Point, points: List[Point], color: List[float]):
|
||
|
self._points = points
|
||
|
self._children = None
|
||
|
self._color = color
|
||
|
self._mean = mean
|
||
|
self._last_mean = None
|
||
|
|
||
|
@property
|
||
|
def points(self):
|
||
|
return self._points
|
||
|
|
||
|
@property
|
||
|
def color(self):
|
||
|
return self._color
|
||
|
|
||
|
@property
|
||
|
def mean(self):
|
||
|
return self._mean
|
||
|
|
||
|
@property
|
||
|
def last_mean(self):
|
||
|
return self._last_mean
|
||
|
|
||
|
def update_mean(self, mean: Point):
|
||
|
self._last_mean = self._mean
|
||
|
self._mean = mean
|
||
|
|
||
|
def mean_moved(self) -> float:
|
||
|
return dist(self._mean, self._last_mean)
|
||
|
|
||
|
@color.setter
|
||
|
def color(self, color: List[float]):
|
||
|
self._color = color
|
||
|
|
||
|
def add_point(self, point: Point):
|
||
|
self._points.append(point)
|
||
|
point.cluster = self
|
||
|
|
||
|
def remove_point(self, point: Point):
|
||
|
self._points.remove(point)
|
||
|
|
||
|
def __repr__(self):
|
||
|
point_pairs = [(p.x, p.y) for p in self._points]
|
||
|
string = f'POINTS: {point_pairs}\n'
|
||
|
|
||
|
return string
|
||
|
|
||
|
def __eq__(self, other):
|
||
|
if not isinstance(other, Cluster):
|
||
|
raise NotImplementedError('equality between clusters is only ' +
|
||
|
'defined for clusters ' +
|
||
|
f'(other={type(other)})')
|
||
|
|
||
|
point_eq = True
|
||
|
|
||
|
for point in self._points:
|
||
|
point_eq = point_eq and (point in other.points)
|
||
|
|
||
|
return point_eq
|