12
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 93 KiB |
+15
-16
@@ -23,7 +23,7 @@ import math
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, Iterable, Sequence
|
||||
from typing import Any, Callable, Sequence
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
FONT_DIR = ROOT / "docs" / "paper" / "fonts"
|
||||
@@ -130,7 +130,7 @@ def new_axes(width_mm: float, height_mm: float, *, ncols: int = 1,
|
||||
|
||||
def axes_for_panels(panel_mm: float, aspects: Sequence[float], *, scale: float = 1.0,
|
||||
width_ratios: Sequence[float] | None = None,
|
||||
extra_mm: float = 30.0, **kw: Any) -> tuple[Any, Any]:
|
||||
**kw: Any) -> tuple[Any, Any]:
|
||||
"""按"每个面板高 panel_mm、宽 = 高 × 宽高比"手工排版。
|
||||
|
||||
等比例坐标轴(``set_aspect('equal')``)在自动布局(constrained/tight)下会被
|
||||
@@ -310,7 +310,8 @@ def decompose(run: dict[str, Any]) -> dict[str, Any]:
|
||||
y=req.get("position", {}).get("y")))
|
||||
wall = [r for r in run["actions"] if r.get("wall_ts_ms")]
|
||||
real_s = (wall[-1]["wall_ts_ms"] - wall[0]["wall_ts_ms"]) / 1000.0 if len(wall) > 1 else 0.0
|
||||
return dict(rows=rows, virtual_s=float(run["actions"][-1]["response"].get("virtual_time_s") or 0),
|
||||
last = run["actions"][-1]["response"]
|
||||
return dict(rows=rows, virtual_s=float(last.get("virtual_time_s") or 0.0),
|
||||
real_s=real_s,
|
||||
move_s=sum(r["move_s"] for r in rows),
|
||||
switch_s=sum(r["switch_s"] for r in rows),
|
||||
@@ -386,12 +387,12 @@ def clip_wedge(region: np.ndarray, station: Sequence[float], bearing: float,
|
||||
region = candidates[0]
|
||||
continue
|
||||
region = min(candidates, key=lambda cand: _direction_error(cand, station,
|
||||
bearing, half_deg))
|
||||
bearing))
|
||||
return region
|
||||
|
||||
|
||||
def _direction_error(poly: np.ndarray, station: Sequence[float], bearing: float,
|
||||
half_deg: float) -> float:
|
||||
def _direction_error(poly: np.ndarray, station: Sequence[float],
|
||||
bearing: float) -> float:
|
||||
"""多边形中心方向与示向度的偏差;用于挑正确的半平面一侧。"""
|
||||
centre = poly.mean(axis=0)
|
||||
dx, dy = centre[0] - station[0], centre[1] - station[1]
|
||||
@@ -691,7 +692,6 @@ def fig_q1_meetup(font: dict[str, Any]) -> Any:
|
||||
stations = data["stations"]
|
||||
xs = [s[0] for s in stations]
|
||||
ys = [s[1] for s in stations]
|
||||
cx, cy = (min(xs) + max(xs)) / 2, (min(ys) + max(ys)) / 2
|
||||
half = max(max(xs) - min(xs), max(ys) - min(ys)) / 2 * 1.35 + 60
|
||||
reach = 2.4 * half
|
||||
mec_c = data["mec"]["center"]
|
||||
@@ -703,7 +703,7 @@ def fig_q1_meetup(font: dict[str, Any]) -> Any:
|
||||
span = float(np.abs(verts - np.array(zoom_c)).max())
|
||||
zoom = max(1.8 * span, 0.8 * mec_r + span, 12.0)
|
||||
|
||||
fig, axes = axes_for_panels(62.0, [1.0, 1.0], width_ratios=[1.0, 1.0])
|
||||
fig, axes = axes_for_panels(62.0, [1.0, 1.0])
|
||||
ax, axz = axes
|
||||
polar_axes(ax, half, grid=half / 2)
|
||||
for sx, sy, bearing, hd in stations:
|
||||
@@ -846,13 +846,13 @@ def fig_q2_safe_disk(font: dict[str, Any]) -> Any:
|
||||
edgecolor=C["success"], lw=1.2))
|
||||
ax.annotate("", xy=c, xytext=(0, 0),
|
||||
arrowprops=dict(arrowstyle="-|>", color=C["violet"], lw=1.0))
|
||||
ax.annotate(f"a = {a:.1f} m", ((c[0] + 0) / 2, (c[1] + 0) / 2),
|
||||
textcoords="offset points", xytext=(-6, 26), ha="right",
|
||||
fontproperties=font["song"], fontsize=7.6, color=C["violet"],
|
||||
ax.annotate(f"a = {a:.1f} m", (c[0] / 2, c[1] / 2), textcoords="offset points",
|
||||
xytext=(-10, 30), ha="center", fontproperties=font["song"],
|
||||
fontsize=7.6, color=C["violet"],
|
||||
arrowprops=dict(arrowstyle="-", color=C["violet"], lw=0.8))
|
||||
ax.annotate(f"安全盘半径 {safe:.1f} m", (c[0], c[1] - safe * 0.7),
|
||||
textcoords="offset points", xytext=(14, -20), ha="left",
|
||||
fontproperties=font["song"], fontsize=7.6, color=C["success"],
|
||||
ax.annotate(f"安全盘半径 {safe:.1f} m", (c[0], c[1]), textcoords="offset points",
|
||||
xytext=(30, -34), ha="left", fontproperties=font["song"],
|
||||
fontsize=7.6, color=C["success"],
|
||||
arrowprops=dict(arrowstyle="-", color=C["success"], lw=0.8))
|
||||
ax.text(0, OMEGA_R * 0.98, "Ω:R = 1800 m", fontproperties=font["song"],
|
||||
fontsize=7.6, color=C["primary"], ha="center", va="top")
|
||||
@@ -860,7 +860,7 @@ def fig_q2_safe_disk(font: dict[str, Any]) -> Any:
|
||||
ax.set_ylabel("y / m", fontproperties=font["song"])
|
||||
|
||||
# 右:安全性依据(两半径相加 = 1000 m)
|
||||
axz.set_aspect("auto")
|
||||
axz.set_aspect("equal", adjustable="box")
|
||||
axz.axis("off")
|
||||
axz.set_xlim(-1.15, 1.25)
|
||||
axz.set_ylim(-0.35, 1.05)
|
||||
@@ -945,7 +945,6 @@ def fig_q3_seven_coverage(font: dict[str, Any]) -> Any:
|
||||
def fig_q4_mincover(font: dict[str, Any]) -> Any:
|
||||
plan = load_plan("q4_mincover_v2")
|
||||
pts = np.array(plan["points"], dtype=float)
|
||||
cert = plan["certificate"]
|
||||
|
||||
fig, axes = axes_for_panels(64.0, [1.0, 1.0], width_ratios=[1.0, 1.0])
|
||||
ax, axr = axes
|
||||
|
||||
Reference in New Issue
Block a user