From 3cdab9049d676940fa2140d707e4a14c777b59c3 Mon Sep 17 00:00:00 2001 From: Martin Skorupski Date: Sun, 22 Oct 2023 11:58:15 +0200 Subject: [PATCH] python 3.10 type definitions - split Point into extra module, avoiding circular definitions - deprecated typings - formatting - spelling Issue-ID: OAM-370 Change-Id: Ie869b97e19633afe0e8a74aaa2fe355ab9eb550e Signed-off-by: Martin Skorupski --- code/network-generator/model/python/hexagon.py | 79 +++++++++++++------------- code/network-generator/model/python/point.py | 29 ++++++++++ 2 files changed, 70 insertions(+), 38 deletions(-) create mode 100644 code/network-generator/model/python/point.py diff --git a/code/network-generator/model/python/hexagon.py b/code/network-generator/model/python/hexagon.py index 5a577e6..e268187 100644 --- a/code/network-generator/model/python/hexagon.py +++ b/code/network-generator/model/python/hexagon.py @@ -22,47 +22,43 @@ import collections import math from typing import NamedTuple +from model.python.point import Point +from model.python.geo_location import GeoLocation -class Point(NamedTuple): - x: float - y: float - - def __str__(self): - return f"{self.x},{self.y}" class Hex: - def __init__(self, q:int, r:int, s:int): + def __init__(self, q: int, r: int, s: int): if round(q + r + s) != 0: raise ValueError("The sum of q, r, and s must be 0.") self.q = q self.r = r self.s = s - def __str__(self): + def __str__(self) -> str: return f"q: {self.q}, r: {self.r}, s: {self.s}" -def hex_add(a: Hex, b: Hex): +def hex_add(a: Hex, b: Hex) -> Hex: return Hex(a.q + b.q, a.r + b.r, a.s + b.s) -def hex_subtract(a: Hex, b: Hex): +def hex_subtract(a: Hex, b: Hex) -> Hex: return Hex(a.q - b.q, a.r - b.r, a.s - b.s) -def hex_scale(a: Hex, k: int): +def hex_scale(a: Hex, k: int) -> Hex: return Hex(a.q * k, a.r * k, a.s * k) -def hex_rotate_left(a): +def hex_rotate_left(a) -> Hex: return Hex(-a.s, -a.q, -a.r) -def hex_rotate_right(a): +def hex_rotate_right(a) -> Hex: return Hex(-a.r, -a.s, -a.q) -hex_directions = [ +hex_directions: list[Hex] = [ Hex(1, 0, -1), Hex(1, -1, 0), Hex(0, -1, 1), @@ -72,15 +68,15 @@ hex_directions = [ ] -def hex_direction(direction): +def hex_direction(direction: int) -> Hex: return hex_directions[direction] -def hex_neighbor(hex: Hex, direction): +def hex_neighbor(hex: Hex, direction: int) -> Hex: return hex_add(hex, hex_direction(direction)) -hex_diagonals = [ +hex_diagonals: list[Hex] = [ Hex(2, -1, -1), Hex(1, -2, 1), Hex(-1, -1, 2), @@ -90,19 +86,19 @@ hex_diagonals = [ ] -def hex_diagonal_neighbor(hex: Hex, direction): +def hex_diagonal_neighbor(hex: Hex, direction: int) -> Hex: return hex_add(hex, hex_diagonals[direction]) -def hex_length(hex: Hex): +def hex_length(hex: Hex) -> int: return (abs(hex.q) + abs(hex.r) + abs(hex.s)) // 2 -def hex_distance(a: Hex, b: Hex): +def hex_distance(a: Hex, b: Hex) -> int: return hex_length(hex_subtract(a, b)) -def hex_round(hex: Hex): +def hex_round(hex: Hex) -> Hex: qi = int(round(hex.q)) ri = int(round(hex.r)) si = int(round(hex.s)) @@ -119,17 +115,17 @@ def hex_round(hex: Hex): return Hex(qi, ri, si) -def hex_lerp(a: Hex, b: Hex, t: int): # linearly interpolation +def hex_lerp(a: Hex, b: Hex, t: int) -> Hex: # linearly interpolation return Hex( a.q * (1.0 - t) + b.q * t, a.r * (1.0 - t) + b.r * t, a.s * (1.0 - t) + b.s * t ) -def hex_linedraw(a: Hex, b: Hex): +def hex_linedraw(a: Hex, b: Hex) -> list[hex]: N = hex_distance(a, b) a_nudge = Hex(a.q + 1e-06, a.r + 1e-06, a.s - 2e-06) b_nudge = Hex(b.q + 1e-06, b.r + 1e-06, b.s - 2e-06) - results = [] + results: list[hex] = [] step = 1.0 / max(N, 1) for i in range(0, N + 1): results.append(hex_round(hex_lerp(a_nudge, b_nudge, step * i))) @@ -138,11 +134,11 @@ def hex_linedraw(a: Hex, b: Hex): OffsetCoord = collections.namedtuple("OffsetCoord", ["col", "row"]) -EVEN = 1 -ODD = -1 +EVEN: int = 1 +ODD: int = -1 -def qoffset_from_cube(offset: int, hex: Hex): +def qoffset_from_cube(offset: int, hex: Hex) -> OffsetCoord: col = hex.q row = hex.r + (hex.q + offset * (hex.q & 1)) // 2 if offset != EVEN and offset != ODD: @@ -150,7 +146,7 @@ def qoffset_from_cube(offset: int, hex: Hex): return OffsetCoord(col, row) -def qoffset_to_cube(offset: int, hex: Hex): +def qoffset_to_cube(offset: int, hex: Hex) -> Hex: q = hex.col r = hex.row - (hex.col + offset * (hex.col & 1)) // 2 s = -q - r @@ -159,7 +155,7 @@ def qoffset_to_cube(offset: int, hex: Hex): return Hex(q, r, s) -def roffset_from_cube(offset: int, hex: Hex): +def roffset_from_cube(offset: int, hex: Hex) -> OffsetCoord: col = hex.q + (hex.r + offset * (hex.r & 1)) // 2 row = hex.r if offset != EVEN and offset != ODD: @@ -167,7 +163,7 @@ def roffset_from_cube(offset: int, hex: Hex): return OffsetCoord(col, row) -def roffset_to_cube(offset: int, hex: Hex): +def roffset_to_cube(offset: int, hex: Hex) -> Hex: q = hex.col - (hex.row + offset * (hex.row & 1)) // 2 r = hex.row s = -q - r @@ -185,14 +181,14 @@ def qdoubled_from_cube(hex: Hex): return DoubledCoord(col, row) -def qdoubled_to_cube(hex: Hex): +def qdoubled_to_cube(hex: Hex) -> Hex: q = hex.col r = (hex.row - hex.col) // 2 s = -q - r return Hex(q, r, s) -def rdoubled_from_cube(hex: Hex): +def rdoubled_from_cube(hex: Hex) -> DoubledCoord: col = 2 * hex.q + hex.r row = hex.r return DoubledCoord(col, row) @@ -217,7 +213,7 @@ class Layout(NamedTuple): origin: Point -layout_pointy = Orientation( +layout_pointy: Orientation = Orientation( math.sqrt(3.0), math.sqrt(3.0) / 2.0, 0.0, @@ -228,7 +224,7 @@ layout_pointy = Orientation( 2.0 / 3.0, 0.5, ) -layout_flat = Orientation( +layout_flat: Orientation = Orientation( 3.0 / 2.0, 0.0, math.sqrt(3.0) / 2.0, @@ -241,7 +237,7 @@ layout_flat = Orientation( ) -def hex_to_pixel(layout: Layout, hex: Hex): +def hex_to_pixel(layout: Layout, hex: Hex) -> Point: M = layout.orientation size = layout.size origin = layout.origin @@ -250,7 +246,7 @@ def hex_to_pixel(layout: Layout, hex: Hex): return Point(x + origin.x, y + origin.y) -def pixel_to_hex(layout: Layout, p: Point): +def pixel_to_hex(layout: Layout, p: Point) -> Hex: M = layout.orientation size = layout.size origin = layout.origin @@ -260,14 +256,14 @@ def pixel_to_hex(layout: Layout, p: Point): return Hex(q, r, -q - r) -def hex_corner_offset(layout: Layout, corner: int): +def hex_corner_offset(layout: Layout, corner: int) -> Point: M = layout.orientation size = layout.size angle = 2.0 * math.pi * (M.start_angle - corner) / 6.0 return Point(size.x * math.cos(angle), size.y * math.sin(angle)) -def polygon_corners(layout: Layout, hex: Hex): +def polygon_corners(layout: Layout, hex: Hex) -> list[Point]: corners: list[Point] = [] center = hex_to_pixel(layout, hex) for i in range(0, 6): @@ -276,6 +272,13 @@ def polygon_corners(layout: Layout, hex: Hex): return corners +def hex_to_geo_location( + layout: Layout, hex: Hex, reference: GeoLocation +) -> GeoLocation: + hexPoint: Point = hex_to_pixel(layout, hex) + return GeoLocation(reference).point_to_geo_location(hexPoint) + + # Tests diff --git a/code/network-generator/model/python/point.py b/code/network-generator/model/python/point.py new file mode 100644 index 0000000..a4e5283 --- /dev/null +++ b/code/network-generator/model/python/point.py @@ -0,0 +1,29 @@ +# Copyright 2023 highstreet technologies GmbH +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# inspired by http://www.redblobgames.com/grids/hexagons/ + +#!/usr/bin/python + +from __future__ import division +from __future__ import print_function +from typing import NamedTuple + + +class Point(NamedTuple): + x: float + y: float + + def __str__(self) -> str: + return f"{self.x},{self.y}" -- 2.16.6