Browse Source

Draw cluster means, support default 4 clusters.

master
Taylor Bockman 5 years ago
parent
commit
a9e163b3f7
  1. 3
      clusterview2/ui/mode_handlers.py
  2. 54
      clusterview2/ui/opengl_widget.py
  3. 7
      main_window.py

3
clusterview2/ui/mode_handlers.py

@ -11,7 +11,8 @@ from clusterview2.exceptions import ExceededWindowBoundsError
from clusterview2.mode import Mode
from clusterview2.ui.opengl_widget import (set_drawing_event, set_move_bb_top_left,
set_move_bb_bottom_right, reset_move_bbs,
viewport_height, viewport_width)
viewport_height, viewport_width,
draw_mean_circles)
from clusterview2.point_manager import PointManager

54
clusterview2/ui/opengl_widget.py

@ -13,9 +13,12 @@ It should be split up into a few more separate files eventually...
Probably even into it's own module folder.
"""
from OpenGL.GL import (glBegin, glClearColor, glColor3f,
glEnd, GL_LINE_LOOP, GL_POINTS,
glPointSize, glVertex3f, glViewport)
import math
from OpenGL.GL import (glBegin, glClearColor, glColor3f, glColor4f,
glEnable, glEnd, GL_LINE_LOOP, GL_LINE_SMOOTH,
GL_POINTS, glPointSize, glVertex3f,
glViewport)
from clusterview2.colors import Color, COLOR_TO_RGBA
from clusterview2.exceptions import (handle_exceptions,
@ -188,6 +191,11 @@ def paint_gl():
draw_points(PointManager.point_set)
if (__current_context.mode is Mode.CLUSTERING and
__current_context.clustering_solved):
draw_mean_circles(PointManager.clusters)
elif __current_context.mode is Mode.MOVE:
# We have to repeatedly draw the points while we are showing the
# move box.
@ -388,3 +396,43 @@ def draw_points(point_set):
__clamp_y(point.y),
0.0) # Z is currently fixed to 0
glEnd()
def draw_mean_circles(clusters: list):
"""
Draws a red circle for each mean.
@param clusters The list of clusters created by k-means.
"""
global __current_context
if __current_context is None:
raise InvalidStateError('Drawing context must be set before setting ' +
'drawing mode.')
if len(clusters) == 0:
raise InvalidStateError('Run clustering before drawing means.')
radius = 0.02
segments = 100
glViewport(0, 0, __WIDTH, __HEIGHT)
glEnable(GL_LINE_SMOOTH)
for cluster in clusters:
glBegin(GL_LINE_LOOP)
blue = COLOR_TO_RGBA[Color.BLUE]
glColor4f(blue[0], blue[1], blue[2], 0.5)
mean = cluster.mean
x = __clamp_x(cluster.mean.x)
y = __clamp_y(cluster.mean.y)
for i in range(0, segments):
glVertex3f(x + (radius * math.cos(i * ((2 * math.pi)/segments))),
y + (radius * math.sin(i * ((2 * math.pi)/segments))),
0.0)
glEnd()

7
main_window.py

@ -57,6 +57,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.number_of_clusters.setMinimum(0)
self.number_of_clusters.setMaximum(Color.count() - 2)
self.clustering_button.setEnabled(False)
# We only need to set the context in our OpenGL state machine
# wrapper once here since the window is fixed size.
# If we allow resizing of the window, the context must be updated
@ -84,7 +86,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self))
self.clustering_button.clicked.connect(self._clustering)
self.number_of_clusters.valueChanged.connect(self._clustering_enabled)
self.reset_button.clicked.connect(self._reset)
@ -209,7 +210,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
refresh_point_list(self)
def _clustering_enabled(self):
self.clustering_button.setEnabled(self.number_of_clusters.value() > 0)
point_count = len(list(PointManager.point_set.points))
self.clustering_button.setEnabled(point_count > 0)
@property
def mode(self):
@ -260,4 +262,5 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# OpenGL event. The context passed to these functions allows
# them to modify on screen widgets such as the QOpenGLWidget and
# QListWidget.
self._clustering_enabled()
MODE_HANDLER_MAP[self._mode](self, event)

Loading…
Cancel
Save