1 # Copyright 2023 highstreet technologies GmbH
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
17 from dataclasses import dataclass
18 from typing import Any
20 from model.python.cube import Cube
21 from model.python.hexagon import Hex
24 class SpiralRadiusProfile:
25 def __init__(self, data: [dict[str, Any] | None] = None):
26 self._oRanSmoSpiralRadiusOfNearRtRics = (
27 data.get("oRanSmoSpiralRadiusOfNearRtRics", 1) if data else 1
29 self._oRanNearRtRicSpiralRadiusOfOCus = (
30 data.get("oRanNearRtRicSpiralRadiusOfOCus", 1) if data else 1
32 self._oRanCuSpiralRadiusOfODus = (
33 data.get("oRanCuSpiralRadiusOfODus", 1) if data else 1
35 self._oRanDuSpiralRadiusOfTowers = (
36 data.get("oRanDuSpiralRadiusOfTowers", 1) if data else 1
41 return f"{self._oRanDuSpiralRadiusOfTowers}{self._oRanCuSpiralRadiusOfODus}{self._oRanNearRtRicSpiralRadiusOfOCus}{self._oRanSmoSpiralRadiusOfNearRtRics}"
44 def count(self) -> int:
50 for ru in range(self._oRanDuSpiralRadiusOfTowers + 1):
51 towers = towers + 6 * ru
53 for du in range(self._oRanCuSpiralRadiusOfODus + 1):
56 for cu in range(self._oRanNearRtRicSpiralRadiusOfOCus + 1):
59 for ric in range(self._oRanSmoSpiralRadiusOfNearRtRics + 1):
62 return towers * dus * cus * rics
65 def oRanSmoSpiralRadiusOfNearRtRics(self) -> int:
66 return self._oRanSmoSpiralRadiusOfNearRtRics
68 @oRanSmoSpiralRadiusOfNearRtRics.setter
69 def oRanSmoSpiralRadiusOfNearRtRics(self, value: int):
70 self._oRanSmoSpiralRadiusOfNearRtRics = value
73 def oRanNearRtRicSpiralRadiusOfOCus(self) -> int:
74 return self._oRanNearRtRicSpiralRadiusOfOCus
76 @oRanNearRtRicSpiralRadiusOfOCus.setter
77 def oRanNearRtRicSpiralRadiusOfOCus(self, value: int):
78 self._oRanNearRtRicSpiralRadiusOfOCus = value
81 def oRanCuSpiralRadiusOfODus(self) -> int:
82 return self._oRanCuSpiralRadiusOfODus
84 @oRanCuSpiralRadiusOfODus.setter
85 def oRanCuSpiralRadiusOfODus(self, value: int):
86 self._oRanCuSpiralRadiusOfODus = value
89 def oRanDuSpiralRadiusOfTowers(self) -> int:
90 return self._oRanDuSpiralRadiusOfTowers
92 @oRanDuSpiralRadiusOfTowers.setter
93 def oRanDuSpiralRadiusOfTowers(self, value: int):
94 self._oRanDuSpiralRadiusOfTowers = value
97 def sectors(self) -> int:
101 def sectors(self, value: int):
102 self._sectors = value
105 def nrDuCellsPerSector(self) -> int:
106 return self._nrDuCellsPerSector
108 @nrDuCellsPerSector.setter
109 def nrDuCellsPerSector(self, value: int):
110 self._nrDuCellsPerSector = value
112 def oRanDuDirections(self) -> list[Hex]:
113 q = 2 * self._oRanDuSpiralRadiusOfTowers + 1
114 r = -self._oRanDuSpiralRadiusOfTowers - 1
125 def oRanDuNeighbor(self, cube: Cube, direction: int):
126 return Hex.add(cube, self.oRanDuDirections[direction])
128 def oRanDuRing(self, center: Hex, radius: int) -> list[Hex]:
131 "Invalid radius. The radius around the hex center must be greater than 0 rings."
133 results: list[Hex] = []
134 hex = Hex.add(center, Hex.scale(self.oRanDuDirections[4], radius))
136 for j in range(radius):
138 hex = self.oRanDuNeighbor(hex, i)
141 def oRanDuSpiral(self, center: Hex, radius: int) -> list[Hex]:
142 result: list[Hex] = [center]
143 for k in range(1, radius + 1):
144 result.extend(self.oRanDuRing(center, k))
147 def oRanNearRtRicDirections(self) -> list[Hex]:
149 2 * self.oRanCuSpiralRadiusOfODus
150 + 3 * self.oRanCuSpiralRadiusOfODus * self.oRanDuSpiralRadiusOfORus
151 + self.oRanDuSpiralRadiusOfORus
154 r0 = self.oRanDuSpiralRadiusOfORus - self.oRanCuSpiralRadiusOfODus
156 q = 3 * q0 - self.oRanNearRtRicSpiralRadiusOfOCus
157 r = -r0 - self.oRanNearRtRicSpiralRadiusOfOCus
159 profile_id = self.id[2:-1]
161 if profile_id in {"111", "112", "113", "114"}:
162 q = 21 + 14 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
163 r = -7 * self.oRanNearRtRicSpiralRadiusOfOCus
164 elif profile_id in {"121", "122", "123", "124"}:
165 q = 25 + 13 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
166 r = 9 + 10 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
167 elif profile_id in {"131", "132"}:
168 q = 49 + 30 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
169 r = -21 - 34 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
170 elif profile_id == "133":
173 elif profile_id == "134":
176 elif profile_id in {"211", "212", "213", "214"}:
177 q = 34 + 23 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
178 r = -10 * self.oRanNearRtRicSpiralRadiusOfOCus - 1
179 elif profile_id in {"221", "222", "223", "224"}:
180 q = 57 + 38 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
181 r = -19 * self.oRanNearRtRicSpiralRadiusOfOCus
182 elif profile_id in {"231", "232", "233", "234"}:
183 q = 80 + 53 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
184 r = -28 * self.oRanNearRtRicSpiralRadiusOfOCus - 1
185 elif profile_id in {"241", "242", "243", "244"}:
186 q = 103 + 68 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
187 r = -39 * self.oRanNearRtRicSpiralRadiusOfOCus + 2 * (
188 self.oRanNearRtRicSpiralRadiusOfOCus - 1
190 elif profile_id in {"311", "312", "313", "314"}:
191 q = 47 + 32 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
192 r = -11 - 13 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
193 elif profile_id in {"321", "322", "323", "324"}:
194 q = 79 + 53 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
195 r = -24 - 25 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
196 elif profile_id in {"331", "332", "333", "334"}:
197 q = 111 + 75 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
198 r = -37 - 37 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
200 # Handle the default case or raise a warning