restore flowsnake.py
This commit is contained in:
parent
f1cb3ec468
commit
1489e9bc52
1 changed files with 124 additions and 0 deletions
124
flowsnake.py
Normal file
124
flowsnake.py
Normal file
|
@ -0,0 +1,124 @@
|
|||
from typing import List
|
||||
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
from vector import *
|
||||
|
||||
FS_VECTOR = Vector(1, 0) + Vector(1, -60) + Vector(1, -180) + Vector(1, -120) + Vector(2, 0) + Vector(1, 60)
|
||||
|
||||
|
||||
class Line:
|
||||
def __init__(self, vector: Vector, variant: bool):
|
||||
self.vector = vector
|
||||
self.variant = variant
|
||||
|
||||
def flowsnake(self) -> list:
|
||||
out = []
|
||||
d = self.vector.distance / FS_VECTOR.distance
|
||||
a = (self.vector.angle - FS_VECTOR.angle) % 360
|
||||
if self.variant:
|
||||
out.append(Line(Vector(d, a), True))
|
||||
a -= 60
|
||||
out.append(Line(Vector(d, a), False))
|
||||
a -= 120
|
||||
out.append(Line(Vector(d, a), False))
|
||||
a += 60
|
||||
out.append(Line(Vector(d, a), self.variant))
|
||||
a += 120
|
||||
out.append(Line(Vector(d, a), True))
|
||||
out.append(Line(Vector(d, a), True))
|
||||
a += 60
|
||||
out.append(Line(Vector(d, a), False))
|
||||
else:
|
||||
a += 60
|
||||
out.append(Line(Vector(d, a), True))
|
||||
a -= 60
|
||||
out.append(Line(Vector(d, a), False))
|
||||
out.append(Line(Vector(d, a), False))
|
||||
a -= 120
|
||||
out.append(Line(Vector(d, a), self.variant))
|
||||
a -= 60
|
||||
out.append(Line(Vector(d, a), True))
|
||||
a += 120
|
||||
out.append(Line(Vector(d, a), True))
|
||||
a += 60
|
||||
out.append(Line(Vector(d, a), False))
|
||||
return out
|
||||
|
||||
|
||||
class FlowSnake(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.setWindowTitle("Flow Snake - Iteration 0")
|
||||
self.setFixedSize(600, 600)
|
||||
|
||||
self.iterations = [[Line(Vector(480, FS_VECTOR.angle + 90), True)]]
|
||||
self.current_iteration = 0
|
||||
|
||||
self.points = []
|
||||
self.prepare_drawing()
|
||||
|
||||
self.show()
|
||||
|
||||
def keyPressEvent(self, e: QKeyEvent):
|
||||
if e.key() == Qt.Key_Q:
|
||||
self.close()
|
||||
elif e.key() == Qt.Key_Right:
|
||||
if self.current_iteration < 7:
|
||||
self.current_iteration += 1
|
||||
if len(self.iterations) <= self.current_iteration:
|
||||
self.iterations.append(self.flowsnake(self.iterations[-1]))
|
||||
self.prepare_drawing()
|
||||
self.setWindowTitle(f"Flow Snake - Iteration {self.current_iteration}")
|
||||
self.repaint()
|
||||
elif e.key() == Qt.Key_Left:
|
||||
if self.current_iteration > 0:
|
||||
self.current_iteration -= 1
|
||||
self.setWindowTitle(f"Flow Snake - Iteration {self.current_iteration}")
|
||||
self.repaint()
|
||||
|
||||
@staticmethod
|
||||
def flowsnake(fs: List[Line]) -> List[Line]:
|
||||
out = []
|
||||
for line in fs:
|
||||
out += line.flowsnake()
|
||||
return out
|
||||
|
||||
def prepare_drawing(self):
|
||||
lines = self.iterations[self.current_iteration]
|
||||
p = Point(0, 0)
|
||||
minx, miny = maxx, maxy = p
|
||||
points = [p]
|
||||
for line in lines:
|
||||
p += line.vector.to_point()
|
||||
minx = min(p.x, minx)
|
||||
miny = min(p.y, miny)
|
||||
maxx = max(p.x, maxx)
|
||||
maxy = max(p.y, maxy)
|
||||
points.append(p)
|
||||
|
||||
midpoint = Point((maxx + minx) / 2, (maxy + miny) / 2)
|
||||
midpoint = Point(self.width() / 2, self.height() / 2) - midpoint
|
||||
self.points.append([p + midpoint for p in points])
|
||||
|
||||
def paintEvent(self, e: QPaintEvent):
|
||||
qp = QPainter(self)
|
||||
qp.setPen(Qt.white)
|
||||
qp.setBrush(Qt.white)
|
||||
qp.drawRect(self.rect())
|
||||
|
||||
qp.setPen(QPen(Qt.black, 1))
|
||||
|
||||
points = self.points[self.current_iteration]
|
||||
for p1, p2 in zip(points[:-1], points[1:]):
|
||||
qp.drawLine(*p1, *p2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QApplication([])
|
||||
flowsnake = FlowSnake()
|
||||
app.exec_()
|
||||
|
Reference in a new issue