# LOG456_07 ⑧ロボットの待機点の直し方(上から見た図)。fig_fix_options.py の形と中身はそのまま、色と字を STYLE.md にそろえた版(2026-11-08) # 使い方: python3 fig_fix_options_v2.py <出力.png> import sys sys.path.insert(0, sys.argv[1]) import style as st st.mpl_setup() import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt, matplotlib.patches as mp plt.rcParams['hatch.linewidth'] = 0.8 R = 0.25; SENS = 0.85; HALF = 35 COME = st.INK # 戻ってくる台と、その道(灰の地の上で目立つ黒) COME_FILL = st.BAND def robot(ax, x, y, col=st.ROBOT, ec=st.INK, lab=None, z=5, lw=1.2): ax.add_patch(mp.Circle((x, y), R, fc=col, ec=ec, lw=lw, zorder=z)) if lab: ax.text(x, y, lab, ha='center', va='center', fontsize=9, zorder=z + 1, color=st.INK) def fan(ax, x, y, deg, col): ax.add_patch(mp.Wedge((x, y), SENS, deg - HALF, deg + HALF, fc=col, ec='none', alpha=0.28, zorder=3)) def base(ax, title, verdict, vcol): ax.set_facecolor(st.SHEET) ax.add_patch(mp.Rectangle((13.0, 11.8), 11.6, 0.6, fc=st.MAP_WALL, ec='none')); ax.text(15.0, 12.1, 'パントリー(壁)', fontsize=10, color=st.MUTED, va='center') ax.add_patch(mp.Rectangle((15.5, 10.6), 3.0, 1.2, fc='none', ec=st.BAD, hatch='////', lw=0, alpha=0.55)) ax.plot(17.0, 11.45, '*', ms=15, color=st.INK, zorder=6); ax.text(17.0, 10.45, '受け渡し口の前\n(あけておく所)', ha='center', va='top', fontsize=9, color=st.BAD) ax.add_patch(mp.Rectangle((24.7, 10.2), 0.9, 1.6, fc=st.SHEET, ec=st.FAINT, lw=1)); ax.text(25.15, 11.0, 'T57', ha='center', va='center', fontsize=9, color=st.FAINT) ax.add_patch(mp.Rectangle((23.7, 9.0), 1.0, 2.8, fc=st.BAND, ec='none')); ax.text(24.2, 9.15, '右の卓へ\n上がる道', ha='center', va='bottom', fontsize=8, color=st.MUTED) ax.set_xlim(12.8, 25.8); ax.set_ylim(8.9, 12.5); ax.set_aspect('equal'); ax.set_xticks([]); ax.set_yticks([]) for s in ax.spines.values(): s.set_visible(False) ax.set_title(title, loc='left', fontsize=14, fontweight='bold', color=st.INK) ax.text(1.0, 1.02, verdict, transform=ax.transAxes, ha='right', va='bottom', fontsize=11.5, color=st.SHEET, fontweight='bold', bbox=dict(boxstyle='round,pad=0.35,rounding_size=0.2', fc=vcol, ec='none')) def slots(ax, xs, y=11.35, occ=None): for i, x in enumerate(xs): ax.add_patch(mp.Rectangle((x - 0.4, y - 0.4), 0.8, 0.8, fc=st.MAIN_SOFT, ec=st.MAIN, ls='--', lw=1, zorder=2)) if occ is None or i in occ: robot(ax, x, y, lab=str(i + 1)) def gap(ax, x1, x2, y, txt): ax.annotate('', xy=(x1, y), xytext=(x2, y), arrowprops=dict(arrowstyle='<->', color=st.MUTED, lw=1)) ax.text((x1 + x2) / 2, y + 0.06, txt, ha='center', va='bottom', fontsize=9, color=st.INK) def come(ax, x, y, lab='3'): robot(ax, x, y, col=COME_FILL, ec=COME, lab=lab, lw=2) ARW = dict(arrowstyle='->', color=COME, lw=2, connectionstyle='arc3,rad=-0.15') staff = [(13.75, 11.25), (15.75, 11.25)] fig, axs = plt.subplots(4, 1, figsize=(11, 15.5), dpi=130) ax = axs[0]; xs = [19.1 + 0.8 * i for i in range(6)]; base(ax, '今:1列・間0.8m・6点', '× 隣の台がセンサーに入って止まる', st.BAD) slots(ax, xs, occ=[0, 1, 3, 4]); gap(ax, xs[3], xs[4], 11.75, '0.8m') rx, ry = 20.45, 10.9; ax.annotate('', xy=(xs[2], 11.2), xytext=(19.0, 9.3), arrowprops=ARW) fan(ax, rx, ry, 120, st.BAD); come(ax, rx, ry) ax.text(18.0, 9.3, '戻ってくる台3は斜めに寄るので、\n隣の台2がセンサー(薄い扇)に入る', fontsize=10, va='bottom', ha='right', color=st.INK) ax = axs[1]; xs = [18.9 + 1.1 * i for i in range(5)]; base(ax, '(1) 1列・間1.1m・5点', '△ 斜めに寄ると、まだ隣に届くことがある', st.BAD) slots(ax, xs, occ=[0, 1, 3, 4]); gap(ax, xs[3], xs[4], 11.75, '1.1m') rx, ry = xs[2] - 0.35, 10.88; ax.annotate('', xy=(xs[2], 11.2), xytext=(19.3, 9.3), arrowprops=ARW) fan(ax, rx, ry, 120, st.BAD); come(ax, rx, ry) ax.text(18.6, 9.3, 'これより広い間は取れない\n(左の赤い斜線の所と右の灰の道があるため)', fontsize=10, va='bottom', ha='right', color=st.INK) ax = axs[2]; xs = [19.1 + 0.8 * i for i in range(6)]; base(ax, '(2) 間0.8mのまま、真下まで来てからまっすぐ入る', '○ まっすぐ入るので、横の台がセンサーに入らない', st.GOOD) slots(ax, xs, occ=[0, 1, 3, 4]); gap(ax, xs[3], xs[4], 11.75, '0.8m') ax.plot([19.0, xs[2]], [9.3, 10.0], color=COME, lw=2, solid_capstyle='butt'); ax.annotate('', xy=(xs[2], 11.15), xytext=(xs[2], 10.0), arrowprops=dict(arrowstyle='->', color=COME, lw=2)) ax.plot(xs[2], 10.0, 'o', ms=6, color=COME); ax.text(xs[2] + 0.15, 9.95, '入る点(待機点の真下)', fontsize=9, va='top', color=st.INK) fan(ax, xs[2], 10.45, 90, st.GOOD); come(ax, xs[2], 10.45) ax.text(18.6, 9.3, '店の形は今と同じ。\nロボットの入り方の決まりを足す', fontsize=10, va='bottom', ha='right', color=st.INK) ax = axs[3]; xs = [19.0 + 1.2 * i for i in range(4)]; base(ax, '(3) 1列・間1.2m・4点 + 受け渡し口の左に1点', '○ 間は広いが、スタッフの持ち場を動かす', st.GOOD) slots(ax, xs); gap(ax, xs[2], xs[3], 11.75, '1.2m') slots(ax, [14.9], occ=[]); robot(ax, 14.9, 11.35, lab='5') for (x, y) in staff: ax.add_patch(mp.RegularPolygon((x, y), 3, radius=0.2, fc=st.FAINT, ec='none', zorder=6)) ax.text(14.2, 10.55, '灰の三角=今のスタッフの持ち場\n(重なる所は動かす)', fontsize=9, color=st.MUTED, ha='center', va='top') fig.suptitle('⑧ ロボットの待機点の直し方(上から見た図)\n白い丸=待っているロボット、黒い縁の灰の丸=戻ってくるロボット、薄い扇=前のセンサー(中心から0.85m。形は簡単にした絵)', x=0.02, ha='left', fontsize=12, color=st.INK) plt.tight_layout(rect=(0, 0, 1, 0.955)); plt.savefig(sys.argv[2], facecolor=st.PAPER) print(sys.argv[2])