106 lines
2.9 KiB
Python
106 lines
2.9 KiB
Python
from PyQt5.QtCore import *
|
|
from PyQt5.QtGui import *
|
|
from PyQt5.QtWidgets import *
|
|
|
|
from vector import *
|
|
|
|
ANGLE = 30
|
|
|
|
|
|
class Square:
|
|
def __init__(self, p1: Point, p2: Point):
|
|
self.p1 = p1
|
|
self.p2 = p2
|
|
vector = (p2 - p1).to_vector()
|
|
vector.angle -= 90
|
|
self.p3 = p2 + vector.to_point()
|
|
self.p4 = p1 + vector.to_point()
|
|
|
|
self.triangle = None
|
|
|
|
def __iter__(self):
|
|
yield self.p1, self.p2, self.p3, self.p4
|
|
if self.triangle:
|
|
yield from self.triangle
|
|
|
|
def iterate(self):
|
|
if self.triangle is None:
|
|
self.triangle = Triangle(self.p4, self.p3)
|
|
else:
|
|
self.triangle.iterate()
|
|
|
|
|
|
class Triangle:
|
|
def __init__(self, p1: Point, p2: Point):
|
|
self.p1 = p1
|
|
self.p2 = p2
|
|
vector = (p2 - p1).to_vector()
|
|
vector.angle -= ANGLE
|
|
vector.distance *= math.cos(deg2rad(ANGLE))
|
|
self.p3 = p1 + vector.to_point()
|
|
|
|
self.square1 = self.square2 = None
|
|
|
|
def __iter__(self):
|
|
yield self.p1, self.p2, self.p3
|
|
if self.square1 is not None:
|
|
yield from self.square1
|
|
yield from self.square2
|
|
|
|
def iterate(self):
|
|
if self.square1 is None:
|
|
self.square1 = Square(self.p1, self.p3)
|
|
self.square2 = Square(self.p3, self.p2)
|
|
else:
|
|
self.square1.iterate()
|
|
self.square2.iterate()
|
|
|
|
|
|
class PyTree(QWidget):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
self.setWindowTitle("Pythagoras Tree - Iteration 0")
|
|
self.setFixedSize(900, 600)
|
|
|
|
self.tree = Square(
|
|
Point(self.width() / 2 - 50, self.height() - 20),
|
|
Point(self.width() / 2 + 50, self.height() - 20)
|
|
)
|
|
self.iterations = [list(self.tree)]
|
|
self.current_iteration = 0
|
|
|
|
self.show()
|
|
|
|
def keyPressEvent(self, e: QKeyEvent):
|
|
if e.key() == Qt.Key_Q:
|
|
self.close()
|
|
elif e.key() == Qt.Key_Right:
|
|
self.current_iteration += 1
|
|
if len(self.iterations) <= self.current_iteration:
|
|
self.tree.iterate()
|
|
self.iterations.append(list(self.tree))
|
|
self.setWindowTitle(f"Pythagoras Tree - Iteration {self.current_iteration}")
|
|
self.repaint()
|
|
elif e.key() == Qt.Key_Left:
|
|
if self.current_iteration > 0:
|
|
self.current_iteration -= 1
|
|
self.setWindowTitle(f"Pythagoras Tree - Iteration {self.current_iteration}")
|
|
self.repaint()
|
|
|
|
def paintEvent(self, _: QPaintEvent):
|
|
qp = QPainter(self)
|
|
qp.setPen(Qt.white)
|
|
qp.setBrush(Qt.white)
|
|
qp.drawRect(self.rect())
|
|
|
|
qp.setPen(Qt.black)
|
|
|
|
for polygon in self.iterations[self.current_iteration]:
|
|
qp.drawPolygon(*(QPoint(*p) for p in polygon))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
app = QApplication([])
|
|
tree = PyTree()
|
|
app.exec_()
|