hilbert_curve.py
1 from typing import List 2 3 from PyQt5.QtCore import * 4 from PyQt5.QtGui import * 5 from PyQt5.QtWidgets import * 6 7 8 class Hilbert(QWidget): 9 def __init__(self): 10 super().__init__() 11 12 self.setWindowTitle("Hilbert Curve - Iteration 0") 13 self.setFixedSize(480, 480) 14 15 self.iterations = [self.hilbert([(.5, .5)])] 16 self.current_iteration = 0 17 18 self.show() 19 20 def keyPressEvent(self, e: QKeyEvent): 21 if e.key() == Qt.Key_Q: 22 self.close() 23 elif e.key() == Qt.Key_Right: 24 if self.current_iteration < 7: 25 self.current_iteration += 1 26 if len(self.iterations) <= self.current_iteration: 27 self.iterations.append(self.hilbert(self.iterations[-1])) 28 self.setWindowTitle(f"Hilbert Curve - Iteration {self.current_iteration}") 29 self.repaint() 30 elif e.key() == Qt.Key_Left: 31 if self.current_iteration > 0: 32 self.current_iteration -= 1 33 self.setWindowTitle(f"Hilbert Curve - Iteration {self.current_iteration}") 34 self.repaint() 35 36 def paintEvent(self, _: QPaintEvent): 37 qp = QPainter(self) 38 qp.setPen(Qt.white) 39 qp.setBrush(Qt.white) 40 qp.drawRect(self.rect()) 41 42 qp.setPen(QPen(Qt.black, 1)) 43 44 curve = self.iterations[self.current_iteration] 45 for (x1, y1), (x2, y2) in zip(curve[:-1], curve[1:]): 46 qp.drawLine(x1 * self.width(), y1 * self.height(), x2 * self.width(), y2 * self.height()) 47 48 @staticmethod 49 def hilbert(h: List[tuple]) -> List[tuple]: 50 return [((1 - y) / 2, 1 - x / 2) for x, y in h] + \ 51 [(x / 2, y / 2) for x, y in h] + \ 52 [(1 - (1 - x) / 2, y / 2) for x, y in h] + \ 53 [(1 - (1 - y) / 2, 1 - (1 - x) / 2) for x, y in h] 54 55 56 if __name__ == '__main__': 57 app = QApplication([]) 58 hilbert = Hilbert() 59 app.exec_()