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
22 import model.python.hexagon as Hexagon
25 class SpiralRadiusProfile:
26 def __init__(self, data: [dict[str, Any] | None] = None):
27 self._oRanSmoSpiralRadiusOfNearRtRics = (
28 data.get("oRanSmoSpiralRadiusOfNearRtRics", 1) if data else 1
30 self._oRanNearRtRicSpiralRadiusOfOCus = (
31 data.get("oRanNearRtRicSpiralRadiusOfOCus", 1) if data else 1
33 self._oRanCuSpiralRadiusOfODus = (
34 data.get("oRanCuSpiralRadiusOfODus", 1) if data else 1
36 self._oRanDuSpiralRadiusOfTowers = (
37 data.get("oRanDuSpiralRadiusOfTowers", 1) if data else 1
42 return f"{self._oRanDuSpiralRadiusOfTowers}{self._oRanCuSpiralRadiusOfODus}{self._oRanNearRtRicSpiralRadiusOfOCus}{self._oRanSmoSpiralRadiusOfNearRtRics}"
45 def count(self) -> int:
51 for ru in range(self._oRanDuSpiralRadiusOfTowers + 1):
52 towers = towers + 6 * ru
54 for du in range(self._oRanCuSpiralRadiusOfODus + 1):
57 for cu in range(self._oRanNearRtRicSpiralRadiusOfOCus + 1):
60 for ric in range(self._oRanSmoSpiralRadiusOfNearRtRics + 1):
63 return towers * dus * cus * rics
66 def oRanSmoSpiralRadiusOfNearRtRics(self) -> int:
67 return self._oRanSmoSpiralRadiusOfNearRtRics
69 @oRanSmoSpiralRadiusOfNearRtRics.setter
70 def oRanSmoSpiralRadiusOfNearRtRics(self, value: int):
71 self._oRanSmoSpiralRadiusOfNearRtRics = value
74 def oRanNearRtRicSpiralRadiusOfOCus(self) -> int:
75 return self._oRanNearRtRicSpiralRadiusOfOCus
77 @oRanNearRtRicSpiralRadiusOfOCus.setter
78 def oRanNearRtRicSpiralRadiusOfOCus(self, value: int):
79 self._oRanNearRtRicSpiralRadiusOfOCus = value
82 def oRanCuSpiralRadiusOfODus(self) -> int:
83 return self._oRanCuSpiralRadiusOfODus
85 @oRanCuSpiralRadiusOfODus.setter
86 def oRanCuSpiralRadiusOfODus(self, value: int):
87 self._oRanCuSpiralRadiusOfODus = value
90 def oRanDuSpiralRadiusOfTowers(self) -> int:
91 return self._oRanDuSpiralRadiusOfTowers
93 @oRanDuSpiralRadiusOfTowers.setter
94 def oRanDuSpiralRadiusOfTowers(self, value: int):
95 self._oRanDuSpiralRadiusOfTowers = value
98 def sectors(self) -> int:
102 def sectors(self, value: int):
103 self._sectors = value
106 def nrDuCellsPerSector(self) -> int:
107 return self._nrDuCellsPerSector
109 @nrDuCellsPerSector.setter
110 def nrDuCellsPerSector(self, value: int):
111 self._nrDuCellsPerSector: int = value
113 def oRanDuDirections(self) -> list[Hex]:
114 q: int = 2 * self._oRanDuSpiralRadiusOfTowers + 1
115 r: int = -self._oRanDuSpiralRadiusOfTowers - 1
126 def oRanDuNeighbor(self, cube: Cube, direction: int):
127 return Hexagon.hex_add(cube, self.oRanDuDirections()[direction])
129 def oRanDuRing(self, center: Hex, radius: int) -> list[Hex]:
132 "Invalid radius. The radius around the hex center must be greater than 0 rings."
134 results: list[Hex] = []
135 hex: Hex = Hexagon.hex_add(
136 center, Hexagon.hex_scale(self.oRanDuDirections()[4], radius)
139 for j in range(radius):
141 hex = self.oRanDuNeighbor(hex, i)
144 def oRanDuSpiral(self, o_ran_du_center: Hex, radius: int) -> list[Hex]:
145 result: list[Hex] = [o_ran_du_center]
146 for k in range(1, radius + 1):
147 result.extend(self.oRanDuRing(o_ran_du_center, k))
150 def oRanCuDirections(self) -> list[Hex]:
152 2 * self.oRanCuSpiralRadiusOfODus
153 + 3 * self.oRanCuSpiralRadiusOfODus * self.oRanDuSpiralRadiusOfTowers
154 + self.oRanDuSpiralRadiusOfTowers
157 r: int = self.oRanDuSpiralRadiusOfTowers - self.oRanCuSpiralRadiusOfODus
168 def oRanCuNeighbor(self, cube: Hex, direction: int) -> list[Hex]:
169 return Hexagon.hex_add(cube, self.oRanCuDirections()[direction])
171 def oRanCuRing(self, center: Hex, radius: int):
174 "Invalid radius. The radius around the hex center must be greater than 0 rings."
177 results: list[Hex] = []
178 hex: Hex = Hexagon.hex_add(
179 center, Hexagon.hex_scale(self.oRanCuDirections()[4], radius)
182 for j in range(radius):
184 hex = self.oRanCuNeighbor(hex, i)
187 def oRanCuSpiral(self, center: Hex, radius: int) -> list[Hex]:
188 result: list[Hex] = [center]
189 for k in range(1, radius + 1):
190 result += self.oRanCuRing(center, k)
193 def oRanNearRtRicDirections(self) -> list[Hex]:
195 2 * self.oRanCuSpiralRadiusOfODus
196 + 3 * self.oRanCuSpiralRadiusOfODus * self.oRanDuSpiralRadiusOfTowers
197 + self.oRanDuSpiralRadiusOfTowers
200 r0: int = self.oRanDuSpiralRadiusOfTowers - self.oRanCuSpiralRadiusOfODus
202 q: int = 3 * q0 - self.oRanNearRtRicSpiralRadiusOfOCus
203 r: int = -r0 - self.oRanNearRtRicSpiralRadiusOfOCus
205 profile_id: str = self.id[0 : len(self.id)-1]
206 if profile_id in {"111", "112", "113", "114"}:
207 q: int = 21 + 14 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
208 r: int = -7 * self.oRanNearRtRicSpiralRadiusOfOCus
209 elif profile_id in {"121", "122", "123", "124"}:
210 q: int = 25 + 13 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
211 r: int = 9 + 10 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
212 elif profile_id in {"131", "132"}:
213 q: int = 49 + 30 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
214 r: int = -21 - 34 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
215 elif profile_id == "133":
218 elif profile_id == "134":
221 elif profile_id in {"211", "212", "213", "214"}:
222 q: int = 34 + 23 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
223 r: int = -10 * self.oRanNearRtRicSpiralRadiusOfOCus - 1
224 elif profile_id in {"221", "222", "223", "224"}:
225 q: int = 57 + 38 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
226 r: int = -19 * self.oRanNearRtRicSpiralRadiusOfOCus
227 elif profile_id in {"231", "232", "233", "234"}:
228 q: int = 80 + 53 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
229 r: int = -28 * self.oRanNearRtRicSpiralRadiusOfOCus - 1
230 elif profile_id in {"241", "242", "243", "244"}:
231 q: int = 103 + 68 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
232 r: int = -39 * self.oRanNearRtRicSpiralRadiusOfOCus + 2 * (
233 self.oRanNearRtRicSpiralRadiusOfOCus - 1
235 elif profile_id in {"311", "312", "313", "314"}:
236 q: int = 47 + 32 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
237 r: int = -11 - 13 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
238 elif profile_id in {"321", "322", "323", "324"}:
239 q: int = 79 + 53 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
240 r: int = -24 - 25 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
241 elif profile_id in {"331", "332", "333", "334"}:
242 q: int = 111 + 75 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
243 r: int = -37 - 37 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
245 # Handle the default case or raise a warning
258 def oRanNearRtRicNeighbor(self, cube: Hex, direction: int):
259 return Hexagon.hex_add(cube, self.oRanNearRtRicDirections()[direction])
261 def oRanNearRtRicRing(self, center: Hex, radius: int) -> list[Hex]:
264 "Invalid radius. The radius around the hex center must be greater than 0 rings."
267 results: list[Hex] = []
268 hex: Hex = Hexagon.hex_add(
269 center, Hexagon.hex_scale(self.oRanNearRtRicDirections()[4], radius)
272 for j in range(radius):
274 hex = self.oRanNearRtRicNeighbor(hex, i)
277 def oRanNearRtRicSpiral(self, center: Hex, radius: int) -> list[Hex]:
278 result: list[Hex] = [center]
279 for k in range(1, radius + 1):
280 result += self.oRanNearRtRicRing(center, k)