Skip to content

Commit 46ac461

Browse files
committed
#187 New drawing of track sector dividers and waypoint labels
1 parent 1d9d4a2 commit 46ac461

File tree

3 files changed

+80
-28
lines changed

3 files changed

+80
-28
lines changed

src/graphics/track_analysis_canvas.py

+41-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55

66
from graphics.canvas import Canvas
77
from PyQt6.QtWidgets import QAbstractGraphicsShapeItem
8-
from PyQt6.QtGui import QPen, QPainter, QBrush
8+
from PyQt6.QtGui import QPen, QPainter, QBrush, QColor, QFont
99
from PyQt6.QtCore import Qt
1010

11+
from utils import geometry
12+
1113
Point = (float | int, float | int) # Typedef which we will use a lot for graphics
1214

1315

@@ -111,7 +113,7 @@ def add_fixed_shape(self, item: FixedShape):
111113
# plot_dot() in v3
112114

113115
class FilledCircle(FixedShape):
114-
def __init__(self, point: Point, diameter: int, colour: Qt.GlobalColor):
116+
def __init__(self, point: Point, diameter: int, colour: QColor):
115117
self._point = point
116118
self._pen = QPen(colour)
117119
self._diameter = diameter
@@ -133,11 +135,13 @@ def paint(self, painter: QPainter, scale: Scale):
133135
# def plot_line(self, point1, point2, width, fill_colour, dash_pattern=None) in v3
134136

135137
class Line(FixedShape):
136-
def __init__(self, start: Point, finish: Point, width: int, colour: Qt.GlobalColor, dash_pattern="??????"):
138+
def __init__(self, start: Point, finish: Point, width: int, colour: QColor, dash_pattern: (int, int) = None):
137139
self._start = start
138140
self._finish = finish
139141
self._pen = QPen(colour)
140142
self._pen.setWidth(width)
143+
if dash_pattern:
144+
self._pen.setDashPattern(dash_pattern)
141145

142146
def paint(self, painter: QPainter, scale: Scale):
143147
x1, y1 = scale.apply(self._start)
@@ -146,4 +150,38 @@ def paint(self, painter: QPainter, scale: Scale):
146150
painter.drawLine(x1, y1, x2, y2)
147151

148152

153+
# The point given is the approximate CENTRE of the text
154+
155+
class Text(FixedShape):
156+
last_non_overlapping_text_position = None
157+
158+
def __init__(self, position: Point, text: str, font_size: int, colour: QColor, offset_x: int = 0, offset_y: int = 0):
159+
self._position = position
160+
self._text = text
161+
self._offset_x = offset_x
162+
self._offset_y = offset_y
163+
self._centering_x_offset = 0.4 * font_size * len(text)
164+
self._centering_y_offset = 0.5 * font_size
165+
self._spacing = 2.3 * font_size
166+
167+
self._pen = QPen(colour)
168+
self._font = QFont()
169+
self._font.setPointSize(font_size)
170+
# self._font.setStyleStrategy(QFont.StyleStrategy.NoAntialias)
171+
172+
def paint(self, painter: QPainter, scale: Scale):
173+
x, y = scale.apply(self._position)
174+
175+
x = round(x + self._offset_x - self._centering_x_offset)
176+
y = round(y + self._offset_y + self._centering_y_offset)
177+
178+
if Text.last_non_overlapping_text_position:
179+
dist = geometry.get_distance_between_points(self.last_non_overlapping_text_position, (x, y))
180+
if dist < self._spacing:
181+
return
182+
183+
painter.setPen(self._pen)
184+
painter.setFont(self._font)
185+
painter.drawText(x, y, self._text)
149186

187+
Text.last_non_overlapping_text_position = (x, y)

src/prototype_ui/main.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import sys
22

33
from PyQt6.QtCore import Qt
4+
from PyQt6.QtGui import QColor
45
from PyQt6.QtWidgets import QMainWindow, QApplication, QProgressBar, QFileDialog
56

67
from src.log.log import Log
@@ -68,9 +69,12 @@ def __init__(self):
6869
self._current_track = self._tracks["arctic_pro_cw"]
6970
self._current_track.configure_track_canvas(self.canvas)
7071

71-
self._current_track.draw_track_edges(self.canvas, Qt.GlobalColor.darkGray)
72-
self._current_track.draw_waypoints(self.canvas, Qt.GlobalColor.blue, 3, 4)
73-
self._current_track.draw_section_highlight(self.canvas, Qt.GlobalColor.green, 0, 20)
72+
self._current_track.draw_track_edges(self.canvas, QColor("dimGray"))
73+
self._current_track.draw_waypoints(self.canvas, QColor("dimGray"), 2, 8)
74+
self._current_track.draw_section_highlight(self.canvas, QColor("dimGray"), 0, 20)
75+
self._current_track.draw_starting_line(self.canvas, QColor("dimGray"))
76+
self._current_track.draw_sector_dividers(self.canvas, QColor("dimGray"))
77+
self._current_track.draw_waypoint_labels(self.canvas, QColor("dimGray"), 9)
7478

7579
def set_busy_cursor(self):
7680
self.setCursor(Qt.CursorShape.WaitCursor)

src/tracks/track.py

+32-22
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
# Copyright (c) 2021 dmh23
1010
#
1111
from PyQt6.QtCore import Qt
12+
from PyQt6.QtGui import QColor
1213

1314
import src.utils.geometry as geometry
14-
from graphics.track_analysis_canvas import TrackAnalysisCanvas, TrackArea, Line, FilledCircle
15+
from graphics.track_analysis_canvas import TrackAnalysisCanvas, TrackArea, Line, FilledCircle, Text
1516
from src.analyze.util.heatmap import HeatMap
1617
from src.analyze.util.visitor import VisitorMap
1718
from src.configuration.real_world import VEHICLE_LENGTH, VEHICLE_WIDTH, BOX_OBSTACLE_WIDTH, BOX_OBSTACLE_LENGTH
@@ -116,7 +117,7 @@ def configure_track_canvas(self, canvas: TrackAnalysisCanvas):
116117
self._max_x + DISPLAY_BORDER, self._max_y + DISPLAY_BORDER)
117118
canvas.set_track_area(area)
118119

119-
def draw_track_edges(self, track_canvas: TrackAnalysisCanvas, colour: Qt.GlobalColor):
120+
def draw_track_edges(self, track_canvas: TrackAnalysisCanvas, colour: QColor):
120121
previous_left = self._drawing_points[-1].left
121122
previous_right = self._drawing_points[-1].right
122123

@@ -126,7 +127,7 @@ def draw_track_edges(self, track_canvas: TrackAnalysisCanvas, colour: Qt.GlobalC
126127
track_canvas.add_fixed_shape(Line(previous_right, p.right, 2, colour))
127128
previous_right = p.right
128129

129-
def draw_section_highlight(self, track_canvas: TrackAnalysisCanvas, colour: Qt.GlobalColor, start: int, finish: int):
130+
def draw_section_highlight(self, track_canvas: TrackAnalysisCanvas, colour: QColor, start: int, finish: int):
130131
previous_left = self._drawing_points[start].left_outer
131132
previous_right = self._drawing_points[start].right_outer
132133

@@ -136,42 +137,51 @@ def draw_section_highlight(self, track_canvas: TrackAnalysisCanvas, colour: Qt.G
136137
highlight_points = self._drawing_points[start:] + self._drawing_points[:finish + 1]
137138

138139
for p in highlight_points:
139-
track_canvas.add_fixed_shape(Line(previous_left, p.left_outer, 3, colour))
140+
track_canvas.add_fixed_shape(Line(previous_left, p.left_outer, 4, colour))
140141
previous_left = p.left_outer
141-
track_canvas.add_fixed_shape(Line(previous_right, p.right_outer, 3, colour))
142+
track_canvas.add_fixed_shape(Line(previous_right, p.right_outer, 4, colour))
142143
previous_right = p.right_outer
143144

144-
def draw_starting_line(self, track_graphics: TrackGraphics, colour: str):
145-
track_graphics.plot_line(self._drawing_points[0].left, self._drawing_points[0].right, 3, colour)
145+
def draw_starting_line(self, track_canvas: TrackAnalysisCanvas, colour: QColor):
146+
track_canvas.add_fixed_shape(Line(self._drawing_points[0].left, self._drawing_points[0].right, 3, colour))
146147

147-
def draw_sector_dividers(self, track_graphics: TrackGraphics, colour: str):
148+
def draw_sector_dividers(self, track_canvas: TrackAnalysisCanvas, colour: QColor):
148149
for p in self._drawing_points:
149150
if p.is_divider:
150-
track_graphics.plot_line(p.left, p.right, 3, colour, (4, 2))
151+
track_canvas.add_fixed_shape(Line(p.left, p.right, 2, colour, (2, 3)))
151152

152-
def draw_waypoints(self, track_canvas: TrackAnalysisCanvas, colour: Qt.GlobalColor, minor_size: int, major_size: int):
153+
def draw_waypoints(self, track_canvas: TrackAnalysisCanvas, colour: QColor, minor_size: int, major_size: int):
153154
assert major_size >= minor_size
154155
for (i, p) in enumerate(self._drawing_points):
155156
if i % 10 == 0:
156157
track_canvas.add_fixed_shape(FilledCircle(p.middle, major_size, colour))
157158
else:
158159
track_canvas.add_fixed_shape(FilledCircle(p.middle, minor_size, colour))
159160

160-
def draw_waypoint_labels(self, track_graphics: TrackGraphics, colour: str, font_size: int):
161+
def draw_waypoint_labels(self, track_canvas: TrackAnalysisCanvas, colour: QColor, font_size: int):
161162
last_label_position = None
162-
for (i, p) in enumerate(self._drawing_points[:-2]):
163+
for (i, p) in enumerate(self._drawing_points[1:-2]):
163164
if self._is_vertical_at_waypoint(i):
164-
label = track_graphics.plot_text(p.middle, str(i), font_size, colour, -1.5 * font_size, 0.0)
165-
else:
166-
label = track_graphics.plot_text(p.middle, str(i), font_size, colour, 0.0, 1.5 * font_size)
167-
168-
label_position = track_graphics.get_widget_position(label)
169-
if last_label_position is None:
170-
last_label_position = label_position
171-
elif geometry.get_distance_between_points(last_label_position, label_position) < 2.5 * font_size:
172-
track_graphics.delete_widget(label)
165+
y_offset = 0
166+
if i >= 99:
167+
x_offset = -round(1.5 * font_size)
168+
else:
169+
x_offset = -font_size
173170
else:
174-
last_label_position = label_position
171+
x_offset = 0
172+
y_offset = font_size + 2
173+
174+
track_canvas.add_fixed_shape(Text(p.middle, str(i+1), font_size, colour, x_offset, y_offset))
175+
# track_canvas.add_fixed_shape(Text(p.middle, str(i+1), font_size, colour))
176+
177+
# TODO Clever stuff to skip labels which would be too close together!
178+
# label_position = track_canvas.get_widget_position(label)
179+
# if last_label_position is None:
180+
# last_label_position = label_position
181+
# elif geometry.get_distance_between_points(last_label_position, label_position) < 2.5 * font_size:
182+
# track_graphics.delete_widget(label)
183+
# else:
184+
# last_label_position = label_position
175185

176186
def draw_annotations(self, track_graphics: TrackGraphics):
177187
for a in self._annotations:

0 commit comments

Comments
 (0)