import json, sys, matplotlib; matplotlib.use('Agg') import matplotlib.pyplot as plt, matplotlib.patches as P from matplotlib import font_manager as fm fp=fm.FontProperties(fname='/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc') B='/home/claude/p2m-site/public/sim/layouts/' L=json.load(open(B+'p4_relaxed_side.json'))['layout'] U=json.load(open(B+'unity/p4_relaxed_side.json')) W,D=L['outer']['w'],L['outer']['d'] fig,ax=plt.subplots(figsize=(14,10.5)) ax.add_patch(P.Rectangle((0,0),W,D,fill=False,lw=2)) e=L['entrance']; ax.plot([0,0],[e['a0'],e['a1']],color='w',lw=4); ax.text(-0.3,(e['a0']+e['a1'])/2,'入口',fontproperties=fp,ha='right',va='center',fontsize=10) for r in L['rooms']: x0,y0,x1,y1=r['rect']; ax.add_patch(P.Rectangle((x0,y0),x1-x0,y1-y0,fc={'back':'#e4e4e0','guest':'#f1e6d6','drink':'#d8e8f4'}[r['kind']],ec='#999')) ax.text((x0+x1)/2,(y0+y1)/2,r['label'],ha='center',va='center',fontproperties=fp,fontsize=8) for w in L['walls']: x0,y0,x1,y1=w['rect']; ax.add_patch(P.Rectangle((x0,y0),x1-x0,y1-y0,fc='#555',ec='none')) for k in U['robot_keepout']: x0,y0,x1,y1=k['rect']; ax.add_patch(P.Rectangle((x0,y0),x1-x0,y1-y0,fc='none',ec='#c33',ls=':',lw=1.2)) for t in L['tables']: ax.add_patch(P.Rectangle((t['x'],t['y']),t['w'],t['h'],fc='w',ec='k',lw=.8)) ax.text(t['x']+t['w']/2,t['y']+t['h']/2,t['id'][1:]+'\n'+str(t['seats'])+'人',ha='center',va='center',fontsize=6,fontproperties=fp) d=L['dish_up'][0]['rect']; ax.add_patch(P.Rectangle((d[0],d[1]),d[2]-d[0],d[3]-d[1],fc='#333')) s=L['robot_standby']['rect']; ax.add_patch(P.Rectangle((s[0],s[1]),s[2]-s[0],s[3]-s[1],fc='none',ec='#2a5cc8',ls='--',lw=1.5)); ax.text((s[0]+s[2])/2,s[1]-0.25,'ロボット待機(3台)',ha='center',fontproperties=fp,fontsize=8,color='#2a5cc8') st=L['start']; ax.plot(*st,'o',color='#2a5cc8',ms=7); ax.text(st[0],st[1]-0.45,'受け渡し口の前',ha='center',fontproperties=fp,fontsize=8) if len(sys.argv)>1: for k,v in U['routes']['from_pass'].items(): xs,ys=zip(*v['points']); ax.plot(xs,ys,color='#2a5cc8',alpha=.35,lw=1.2) for p in U['places']: if p['kind'] in ('StaffStandby',): ax.plot(*p['point'],'s',color='#2a7a2a',ms=4) ax.set_xlim(-1.5,W+.5); ax.set_ylim(-.8,D+.5); ax.set_aspect('equal') ax.set_xticks(range(0,int(W)+1,1)); ax.set_yticks(range(0,int(D)+1,1)); ax.grid(alpha=.15); ax.tick_params(labelsize=7) ax.set_title(L['name']+('(青線:受け渡し口から各卓へのロボットの道)' if len(sys.argv)>1 else ''),fontproperties=fp,fontsize=12) def mark(n,box,txt,tx,ty): x0,y0,x1,y1=box ax.add_patch(P.Rectangle((x0,y0),x1-x0,y1-y0,fc='#d33',alpha=.12,ec='#d33',lw=1.8)) ax.text(tx,ty,n+' '+txt,fontproperties=fp,fontsize=9.5,color='#b00',ha='left',va='center',bbox=dict(fc='w',ec='#d33',lw=.8,pad=2)) mark('①',(15.6,1.8,20.4,5.65),'ドリンクバーの上下が両方ふさがりやすい\n上:客が立つ・並ぶ帯を T30・T38 への道が通る\n下:T27〜T29 に止まると左右0.55mしか残らない',13.2,-0.45) mark('②',(13.3,5.3,17.9,6.5),'受け渡し口の前と待機場所が1.2m(③⑦④と同じ形)',15.0,7.0) mark('③',(0.6,3.2,4.6,5.0),'左の通路(T05〜T13)の入口が、入口・レジのすぐ上\n38卓中7卓の道がここを通る(⑤は直した後で46卓中10卓)',0.2,3.75) plt.tight_layout(); plt.savefig(sys.argv[1] if len(sys.argv)>1 else 'p4_plan.png',dpi=120)