This commit is contained in:
Horldsence
2026-09-13 08:54:06 +08:00
parent 27f4d6e0d8
commit 0a2d30702d
2 changed files with 15 additions and 16 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 93 KiB

+15 -16
View File
@@ -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