192 lines
6.2 KiB
Python
192 lines
6.2 KiB
Python
import math
|
|
|
|
from typing import List, Tuple
|
|
|
|
from PySide6.QtCore import Qt
|
|
|
|
from PySide6.QtGui import QBrush, QPainter
|
|
|
|
from PySide6.QtWidgets import QGraphicsItemGroup
|
|
from PySide6.QtWidgets import (
|
|
QStyleOptionGraphicsItem,
|
|
QWidget,
|
|
)
|
|
|
|
from grid.ui.items import (
|
|
HPSphereGraphicsItem,
|
|
ArcGraphicsItem,
|
|
LineGraphicsItem,
|
|
random_sphere_factory,
|
|
)
|
|
|
|
|
|
class Pattern(QGraphicsItemGroup):
|
|
PATTERN_WIDTH = 0
|
|
SPACE_BETWEEN_SPHERE = 60
|
|
|
|
def __init__(self, top_left_corner_x: int, top_left_corner_y: int) -> None:
|
|
super().__init__()
|
|
self.top_left_corner_x = top_left_corner_x
|
|
self.top_left_corner_y = top_left_corner_y
|
|
# center coordinates of the pattern
|
|
self.center_x = top_left_corner_x + int(self.PATTERN_WIDTH / 2)
|
|
self.center_y = top_left_corner_y + int(self.PATTERN_WIDTH / 2)
|
|
|
|
def paint(
|
|
self,
|
|
painter: QPainter,
|
|
option: QStyleOptionGraphicsItem,
|
|
widget: QWidget | None = ...,
|
|
):
|
|
super().paint(painter, option, widget)
|
|
brush = QBrush(Qt.GlobalColor.gray)
|
|
painter.setBrush(brush)
|
|
painter.drawRect(
|
|
self.top_left_corner_x,
|
|
self.top_left_corner_y,
|
|
self.PATTERN_WIDTH,
|
|
self.PATTERN_WIDTH,
|
|
)
|
|
|
|
@staticmethod
|
|
def generate_circle_points(
|
|
center_x: int, center_y: int, radius: int, n_points: int
|
|
) -> List[Tuple[int, int]]:
|
|
"""generate coordinates of points on a circle equally spaced
|
|
|
|
Args:
|
|
self.center_x (int): center x coordinate
|
|
self.center_y (int): center y coordinate
|
|
radius (int): circle radius
|
|
n_points (int): number of points on the circle to generate
|
|
|
|
Returns:
|
|
List[Tuple[int, int]]: list of points coordinates, (x,y)
|
|
"""
|
|
points = []
|
|
angle_step = 2 * math.pi / n_points
|
|
|
|
for i in range(n_points):
|
|
theta = i * angle_step
|
|
x = int(center_x + radius * math.cos(theta))
|
|
y = int(center_y + radius * math.sin(theta))
|
|
points.append((x, y))
|
|
|
|
return points
|
|
|
|
|
|
class LargeUltimaPattern(Pattern):
|
|
"""Common pattern on the sphere grid"""
|
|
|
|
PATTERN_WIDTH = 350
|
|
|
|
def __init__(self, top_left_corner_x: int, top_left_corner_y: int) -> None:
|
|
super().__init__(top_left_corner_x, top_left_corner_y)
|
|
|
|
# center
|
|
|
|
line_start_x = self.center_x
|
|
line_start_y = self.center_y
|
|
line_end_x = self.center_x
|
|
line_end_y = int(self.center_y + self.SPACE_BETWEEN_SPHERE)
|
|
self.addToGroup(
|
|
LineGraphicsItem(line_start_x, line_start_y, line_end_x, line_end_y, self)
|
|
)
|
|
|
|
line_start_x = self.center_x
|
|
line_start_y = top_left_corner_y + self.SPACE_BETWEEN_SPHERE
|
|
line_end_x = self.center_x
|
|
line_end_y = line_start_y + self.SPACE_BETWEEN_SPHERE
|
|
self.addToGroup(
|
|
LineGraphicsItem(line_start_x, line_start_y, line_end_x, line_end_y, self)
|
|
)
|
|
|
|
self.addToGroup(HPSphereGraphicsItem(self.center_x, self.center_y))
|
|
|
|
# first cercle
|
|
sphere_on_circle = 4
|
|
for i in range(sphere_on_circle):
|
|
self.addToGroup(
|
|
ArcGraphicsItem(
|
|
x_pos=self.center_x,
|
|
y_pos=self.center_y,
|
|
width=self.SPACE_BETWEEN_SPHERE * 2,
|
|
angle_start=(i * 360 / sphere_on_circle) % 360,
|
|
# angle_end=((i + 1) * 360 / sphere_on_circle) % 360,
|
|
angle_end=(360 / sphere_on_circle),
|
|
parent=self,
|
|
)
|
|
)
|
|
points = self.generate_circle_points(
|
|
self.center_x, self.center_y, self.SPACE_BETWEEN_SPHERE, sphere_on_circle
|
|
)
|
|
for x, y in points:
|
|
self.addToGroup(random_sphere_factory(x, y))
|
|
|
|
# second cercle
|
|
sphere_on_circle = 8
|
|
points = self.generate_circle_points(
|
|
self.center_x,
|
|
self.center_y,
|
|
self.SPACE_BETWEEN_SPHERE * 2,
|
|
sphere_on_circle,
|
|
)
|
|
for i in range(sphere_on_circle):
|
|
self.addToGroup(
|
|
ArcGraphicsItem(
|
|
x_pos=self.center_x,
|
|
y_pos=self.center_y,
|
|
width=self.SPACE_BETWEEN_SPHERE * 4,
|
|
angle_start=int(i * 360 / sphere_on_circle) % 360,
|
|
angle_end=int((i + 1) * 360 / sphere_on_circle) % 360,
|
|
parent=self,
|
|
)
|
|
)
|
|
for x, y in points:
|
|
self.addToGroup(random_sphere_factory(x, y))
|
|
# self.addToGroup(
|
|
# ArcGraphicsItem(
|
|
# self.center_x, self.center_y, self.SPACE_BETWEEN_SPHERE * 2, 0, 90, self
|
|
# )
|
|
# )
|
|
|
|
|
|
class SmallZPattern(Pattern):
|
|
"""Small pattern used in the sphere grid"""
|
|
|
|
PATTERN_WIDTH = 200
|
|
|
|
def __init__(self, top_left_corner_x: int, top_left_corner_y: int) -> None:
|
|
super().__init__(top_left_corner_x, top_left_corner_y)
|
|
|
|
sphere_on_circle = 6
|
|
for i in range(sphere_on_circle):
|
|
if i == 2 or i == 3 or i == 5 or i == 0:
|
|
continue
|
|
else:
|
|
self.addToGroup(
|
|
ArcGraphicsItem(
|
|
x_pos=self.center_x,
|
|
y_pos=self.center_y,
|
|
width=self.SPACE_BETWEEN_SPHERE * 2,
|
|
angle_start=(i * 360 / sphere_on_circle) % 360,
|
|
angle_end=int((i + 1) * 360 / sphere_on_circle) % 360,
|
|
parent=self,
|
|
)
|
|
)
|
|
points = self.generate_circle_points(
|
|
self.center_x, self.center_y, self.SPACE_BETWEEN_SPHERE, sphere_on_circle
|
|
)
|
|
self.addToGroup(
|
|
LineGraphicsItem(self.center_x, self.center_y, points[1][0], points[1][1], self)
|
|
)
|
|
self.addToGroup(
|
|
LineGraphicsItem(self.center_x, self.center_y, points[4][0], points[4][1], self)
|
|
)
|
|
# Remove left and right sphere
|
|
del points[0]
|
|
del points[2]
|
|
for x, y in points:
|
|
self.addToGroup(random_sphere_factory(x, y))
|
|
|
|
self.addToGroup(HPSphereGraphicsItem(self.center_x, self.center_y)) |