|
2 | 2 |
|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
| 5 | +import math |
| 6 | + |
5 | 7 | import numpy as np |
6 | 8 |
|
7 | 9 | from ..axis_directions import _AXIS_DIR_2D, _AXIS_DIR_3D |
|
22 | 24 | np.array([-1.0, -1.0], dtype=float) / np.sqrt(2.0), |
23 | 25 | np.array([1.0, -1.0], dtype=float) / np.sqrt(2.0), |
24 | 26 | ) |
| 27 | +_SEMIDIAGONAL_DIRECTIONS_2D: tuple[np.ndarray, ...] = tuple( |
| 28 | + np.array( |
| 29 | + [math.cos(math.radians(angle_degrees)), math.sin(math.radians(angle_degrees))], |
| 30 | + dtype=float, |
| 31 | + ) |
| 32 | + for angle_degrees in (67.5, 112.5, 157.5, 202.5, 247.5, 292.5, 337.5, 22.5) |
| 33 | +) |
| 34 | +_NORTH_BEHAVIOR_ORDER_2D: tuple[np.ndarray, ...] = ( |
| 35 | + np.array([0.0, 1.0], dtype=float), |
| 36 | + np.array([0.0, -1.0], dtype=float), |
| 37 | + np.array([1.0, 0.0], dtype=float), |
| 38 | + np.array([-1.0, 0.0], dtype=float), |
| 39 | + *_DIAGONAL_DIRECTIONS_2D, |
| 40 | + *_SEMIDIAGONAL_DIRECTIONS_2D, |
| 41 | +) |
| 42 | + |
| 43 | + |
| 44 | +def _rotate_direction_2d( |
| 45 | + direction: np.ndarray, |
| 46 | + *, |
| 47 | + quarter_turns_clockwise: int, |
| 48 | +) -> np.ndarray: |
| 49 | + x_coord, y_coord = np.asarray(direction, dtype=float).reshape(-1)[:2] |
| 50 | + turns = int(quarter_turns_clockwise) % 4 |
| 51 | + if turns == 0: |
| 52 | + return np.array([x_coord, y_coord], dtype=float) |
| 53 | + if turns == 1: |
| 54 | + return np.array([y_coord, -x_coord], dtype=float) |
| 55 | + if turns == 2: |
| 56 | + return np.array([-x_coord, -y_coord], dtype=float) |
| 57 | + return np.array([-y_coord, x_coord], dtype=float) |
| 58 | + |
| 59 | + |
| 60 | +def _behavior_direction_order_2d(behavior: str) -> tuple[np.ndarray, ...]: |
| 61 | + turns_by_behavior = { |
| 62 | + "north": 0, |
| 63 | + "east": 1, |
| 64 | + "south": 2, |
| 65 | + "west": 3, |
| 66 | + } |
| 67 | + turns = turns_by_behavior.get(behavior.lower().strip(), 0) |
| 68 | + return tuple( |
| 69 | + _normalize_direction( |
| 70 | + _rotate_direction_2d(direction, quarter_turns_clockwise=turns), |
| 71 | + dimensions=2, |
| 72 | + ) |
| 73 | + for direction in _NORTH_BEHAVIOR_ORDER_2D |
| 74 | + ) |
25 | 75 |
|
26 | 76 |
|
27 | 77 | def _is_dangling_leg_axis(graph: _GraphData, node_id: int, axis_index: int) -> bool: |
@@ -465,6 +515,7 @@ def _preferred_component_directions_3d( |
465 | 515 |
|
466 | 516 |
|
467 | 517 | __all__ = [ |
| 518 | + "_behavior_direction_order_2d", |
468 | 519 | "_dedupe_candidate_directions", |
469 | 520 | "_direction_from_axis_name", |
470 | 521 | "_direction_has_space", |
|
0 commit comments