"""TOP の導入前ガイド・配膳ロボットのカードの絵(public/site/srl/cta-iso.svg)を作る。 試算と同じ店(plan-p1.svg:席・キッチン・レジの位置)を、斜め上から見た立体の絵にする。 色は配膳ロボットの LP で使っている色だけ(オレンジ #f2600c・黄色 #f2c230・青 #2f5bd8・濃い灰色)。 ロボットの通り道は、通路の中心を通る見せ方の線で、試算の結果ではない。 使い方:python3 tools/make_cta_iso.py """ import re, math import os ROOT=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) s=open(os.path.join(ROOT,'public/site/srl/plan-p1.svg')).read() R=[] for m in re.finditer(r']*)/>',s): a=dict(re.findall(r'([\w-]+)=\"([^\"]*)\"',m.group(1))) R.append((float(a['x']),float(a['y']),float(a['width']),float(a['height']),a.get('fill'),a.get('stroke'),'stroke-dasharray' in a)) tables=[(r[0]+0.1,r[1]+0.1,r[2]-0.2,r[3]-0.2)+r[4:] for r in R if r[5]=='#111' and r[4]=='#fff'] kitchen=[r for r in R if r[4]=='#e3e3df' and r[0]>=14] others_k=[r for r in R if r[4]=='#e3e3df' and r[0]<14] walls=[r for r in R if r[4]=='#777'] others=[r for r in R if r[4]=='#ffffff']+others_k # 通り道(通路の中心を通る) PASS=(17.7,10.9) routes=[[PASS,(17.7,12.1),(9.2,12.1),(9.2,6.6)], [PASS,(17.7,12.1),(5.5,12.1),(5.5,4.6)], [PASS,(17.7,12.1),(1.8,12.1),(1.8,8.4)], [PASS,(17.7,12.1),(12.7,12.1),(12.7,9.0)]] ORANGE='#f2600c'; YEL='#f2c230'; BLUE='#2f5bd8'; DARK='#242424'; MID='#3a3a3a' def pts(r): return ' '.join(f'{x},{y}' for x,y in r) robots=[(9.2,9.4),(5.5,12.1)] staff=[(12.7,5.0),(3.0,12.6),(19.5,11.4)] def rect(r,fill,stroke='none',sw=0,rx=0.12): x,y,w,h=r[:4]; return f'' def robot(x,y,c=ORANGE,ring='#fff',r=0.62): return f'' def person(x,y,c=BLUE,r=0.42): return f'' VB='viewBox="-1.2 -1.2 26.4 18.4"' def svg(inner,bg,vb=VB): return f'{inner}' # 2 立体(斜め上から) c=math.cos(math.radians(30)); sn=math.sin(math.radians(30)) def P(x,y,z): return ((x-y)*c,(x+y)*sn-z) def poly(ps,fill,stroke='none',sw=0): return f'' def box(x,y,w,h,z,top,side1,side2): X,Y=x+w,y+h o=poly([P(X,y,0),P(X,Y,0),P(X,Y,z),P(X,y,z)],side1) o+=poly([P(x,Y,0),P(X,Y,0),P(X,Y,z),P(x,Y,z)],side2) o+=poly([P(x,y,z),P(X,y,z),P(X,Y,z),P(x,Y,z)],top) return o def iso(): o=poly([P(0,0,0),P(24,0,0),P(24,16,0),P(0,16,0)],'#ffffff') o+=poly([P(0,0,0),P(24,0,0),P(24,0,1.2),P(0,0,1.2)],'#3a3a3a')+poly([P(0,0,0),P(0,16,0),P(0,16,1.2),P(0,0,1.2)],'#242424') o+=''.join(f'' for rt in routes) items=[('b',r[:4],0.75,(YEL,'#d9a91c','#c4951a')) for r in tables]+[('b',r[:4],1.0,('#4a4a4a','#2f2f2f','#242424')) for r in kitchen]+[('b',r[:4],0.6,('#e6e6e6','#cfcfcf','#bdbdbd')) for r in others] items+=[('b',(x-0.4,y-0.4,0.8,0.8),1.3,(ORANGE,'#d4520a','#bf4a09')) for x,y in robots] items+=[('p',(x-0.3,y-0.3,0.6,0.6),0,None) for x,y in staff] # 奥にあるものから描く(x か y で完全に手前にあるものを後に) def behind(a,b): ax,ay,aw,ah=a[1]; bx,by,bw,bh=b[1] return ax+aw<=bx+1e-6 or ay+ah<=by+1e-6 order=[]; rest=items[:] while rest: for it in rest: if not any(behind(o2,it) is False and behind(it,o2) is False and False for o2 in rest): pass # 他のどれよりも手前でないもの(=自分の奥にまだ描いていないものがないもの)を選ぶ pick=None for it in rest: if not any(o2 is not it and behind(o2,it) for o2 in rest): pick=it; break if pick is None: pick=min(rest,key=lambda t:t[1][0]+t[1][1]) order.append(pick); rest.remove(pick) for t,r,z,cols in order: if t=='b': o+=box(r[0],r[1],r[2],r[3],z,*cols) else: cx,cy=P(r[0]+0.3,r[1]+0.3,0); o+=f'' xs=[P(x,y,0)[0] for x,y in [(0,0),(24,0),(24,16),(0,16)]]; ys=[P(0,0,1.4)[1],P(24,16,0)[1]] vb=f'viewBox="{min(xs)-0.6:.2f} {ys[0]-0.6:.2f} {max(xs)-min(xs)+1.2:.2f} {ys[1]-ys[0]+1.2:.2f}"' return f'{o}' open(os.path.join(ROOT,'public/site/srl/cta-iso.svg'),'w').write(iso()) print('public/site/srl/cta-iso.svg')