"""Der Graph, aus dem die Straßen entstehen. Gegenstück zum Entwurf, Abschnitt "Das Netz".""" from __future__ import annotations import numpy as np from leonida.coords import SLICE from leonida.roads import JUNCTION_RADIUS, graph_from_skeleton def skeleton(pixels: list[tuple[int, int]], shape=(120, 120)) -> np.ndarray: skel = np.zeros(shape, dtype=bool) for r, c in pixels: skel[r, c] = True return skel def kreuz(arm: int = 40) -> np.ndarray: """Ein Pluszeichen: vier Arme von 40 px an einem Mittelpunkt.""" pixels = [(60, c) for c in range(60 - arm, 60 + arm + 1)] pixels += [(r, 60) for r in range(60 - arm, 60 + arm + 1)] return skeleton(pixels) def test_ein_kreuz_gibt_einen_knoten_und_vier_kanten(): graph = graph_from_skeleton(kreuz()) junctions = [i for i in range(len(graph.nodes)) if graph.degree(i) >= 3] assert len(junctions) == 1 assert graph.degree(junctions[0]) == 4 assert len(graph.edges) == 4 def test_kanten_beginnen_und_enden_am_knotenpunkt(): graph = graph_from_skeleton(kreuz()) mitte = graph.nodes[next(i for i in range(len(graph.nodes)) if graph.degree(i) >= 3)].point for edge in graph.edges: enden = {edge.points[0], edge.points[-1]} assert mitte in enden, "jede Kante des Kreuzes hängt am Mittelknoten" def test_zwei_kreuzungen_naeher_als_der_radius_werden_ein_knoten(): # Zwei Abzweige im Abstand von 4 m — unter JUNCTION_RADIUS, also ein Knoten. pixels = [(60, c) for c in range(20, 100)] pixels += [(r, 58) for r in range(40, 60)] pixels += [(r, 62) for r in range(60, 80)] graph = graph_from_skeleton(skeleton(pixels)) assert 4 < JUNCTION_RADIUS assert len([i for i in range(len(graph.nodes)) if graph.degree(i) >= 3]) == 1 def test_gerade_strecke_ohne_abzweig_gibt_eine_kante_mit_zwei_enden(): graph = graph_from_skeleton(skeleton([(60, c) for c in range(20, 100)])) assert len(graph.edges) == 1 assert [graph.degree(i) for i in range(len(graph.nodes))] == [1, 1] def test_punkte_liegen_in_weltkoordinaten(): graph = graph_from_skeleton(skeleton([(60, c) for c in range(20, 100)])) xs = [x for x, _ in graph.edges[0].points] assert min(xs) == SLICE["x0"] + 20 assert max(xs) == SLICE["x0"] + 99