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