/ Fractals / hilbert_curve.py
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_()