"""Draw projected cone and four invented synthetic face avatars.""" import json, math from pathlib import Path from PIL import Image, ImageDraw, ImageFilter root=Path(__file__).resolve().parents[1];out=root/'preview/v4/scan_assets' for record in json.loads((out/'projection.json').read_text()): layer=Image.new('RGBA',(1280,720));d=ImageDraw.Draw(layer) origin=tuple(record['origin']);ring=[tuple(p) for p in record['ring']] # Transparent beam facets and a softly luminous emitter; geometry follows the camera. for i in range(len(ring)): d.polygon([origin,ring[i],ring[(i+1)%len(ring)]],fill=(20,220,170,13)) d.line(ring+[ring[0]],fill=(80,255,215,110),width=2) for i in [0,10,20,30]:d.line([origin,ring[i]],fill=(50,240,190,80),width=1) # A travelling cross-section makes the cone visibly sweep through the group. progress=((record['frame']-198)%32)/31 scan=[(origin[0]+(p[0]-origin[0])*progress,origin[1]+(p[1]-origin[1])*progress) for p in ring] d.line(scan+[scan[0]],fill=(110,255,225,160),width=2) x,y=origin;d.ellipse((x-4,y-4,x+4,y+4),fill=(190,255,235,235)) glow=layer.filter(ImageFilter.GaussianBlur(5));Image.alpha_composite(glow,layer).save(out/('cone_%03d.png'%record['frame'])) for i in range(4): layer=Image.new('RGBA',(1280,720));d=ImageDraw.Draw(layer);x=56;y=205+i*79 d.rounded_rectangle((x,y,x+64,y+66),radius=5,fill=(8,31,37,255),outline=(75,245,200,240),width=1) cx=x+32;cy=y+31;skin=[(158,107,79),(200,147,111),(129,90,68),(220,175,140)][i] d.ellipse((cx-17,cy-23,cx+17,cy+23),fill=(*skin,255),outline=(95,240,190,255)) hair=[(31,24,21),(83,42,23),(18,19,25),(133,79,33)][i] d.pieslice((cx-18,cy-25,cx+18,cy+6),180,360,fill=(*hair,255)) for sign in [-1,1]: ex=cx+sign*7;d.line((ex-3,cy-4,ex+3,cy-4),fill=(20,25,24,255),width=2) d.line((cx,cy-2,cx-2,cy+7,cx+2,cy+7),fill=(67,53,42,255),width=1) d.arc((cx-6,cy+8,cx+6,cy+16),0,180,fill=(54,32,25,255),width=1) for px,py in [(cx-8,cy-5),(cx+8,cy-5),(cx,cy+5),(cx-5,cy+15),(cx+5,cy+15)]:d.ellipse((px-1,py-1,px+1,py+1),fill=(80,255,190,255)) layer.save(out/('face_%02d.png'%i))