.PS # Planes.m4 # https://tex.stackexchange.com/questions/727666/gate-all-around-fet-gaafet-nanosheet-3d-illustration threeD_init NeedDpicTools # These 3D diagrams are like many others: define the surface facets, # use normal vectors to determine visibility, sort and plot the visible # facets from back to front. divert(-1) ##################################################################### # Recover point coordinates define(`triple',`x_[$1], y_[$1], z_[$1]') # Store a point as x_[i], y_[i], z_[i] define(`mktriple', `x_[$1] = $2 y_[$1] = $3 z_[$1] = $4 ') # Normal vector to stored facet define(`facetnormal',`cross3D( diff3D(triple((`$1')*3+1),triple((`$1')*3)), diff3D(triple((`$1')*3+2),triple((`$1')*3+1)))') define(`facetcenter',`sprod3D(0.5,sum3D(triple($1*3),triple($1*3+2)))') # Facets are rectangles; store NW, NE, SE corners # `mkpfacet(index,NW2D,NE2D,-d)' define(`mkpfacet',` mktriple((`$1')*3, 0,`$2'.x,`$2'.y) # This uses a right-hand set of mktriple((`$1')*3+1, 0,`$3'.x,`$3'.y) # coords with depth 1st value mktriple((`$1')*3+2,`$4',`$3'.x,`$3'.y) mktriple(0,facetnormal(`$1')) if dot3D(triple(0),View3D) < 0 then { mktriple((`$1')*3,`$4',`$3'.x,`$3'.y) mktriple((`$1')*3+2, 0,`$2'.x,`$2'.y) } ') # View angles azimuth, elevation, rotation (degrees), # Implicitly increments m4x define(`mkthreeplanes',` #mkthreeplanes( wd2h param, ht param, dpth param ) # Size parameters define(`m4a',`ifelse(`$1',,1.5,(`$1'))') define(`m4b',`ifelse(`$1',,0.4,(`$2'))') define(`m4d',`ifelse(`$1',,0.5,(`$3'))') # Define intersecting lines in the plane A0: -m4a,-m4b; A1: m4a,-m4b B0: Rot_(A0,120); B1: Rot_(A1,120) C0: Rot_(A0,240); C1: Rot_(A1,240) AB: intersect_(A0,A1,B0,B1) BC: intersect_(B0,B1,C0,C1) CA: intersect_(C0,C1,A0,A1) # Define the 9 visible facets mkpfacet(m4inx,A0,CA,-m4d) mkpfacet(m4inx,CA,AB,-m4d) mkpfacet(m4inx,AB,A1,-m4d) mkpfacet(m4inx,B0,AB,-m4d) mkpfacet(m4inx,AB,BC,-m4d) mkpfacet(m4inx,BC,B1,-m4d) mkpfacet(m4inx,C0,BC,-m4d) mkpfacet(m4inx,BC,CA,-m4d) mkpfacet(m4inx,CA,C1,-m4d) ') # Cuboid # Requires centre plus three lengths plus 3 angles or equivalent, e.g. 9 dof # plus, somehow, color information. Implicitly increments m4cux # define(`mkcuboid',`# ( xC,yC,zC, wdh,hgt,depth, xrot,yrot,zrot) pushdef(`m4cubx',`define(`m4cux',ifdef(`m4cux',`incr(m4cux)',1))m4cux') pushdef(`xr',`$7') pushdef(`yr',`$8') pushdef(`zr',`$9') dnl pushdef(`wd2',ifelse(`$4',,boxwd,(`$4'))/2) dnl pushdef(`hg2',ifelse(`$5',,boxht,(`$5'))/2) dnl pushdef(`de2',ifelse(`$6',,boxwd,(`$6'))/2) dnl pushdef(`dx',`ifelse(`$1',,0,`$1')') pushdef(`dy',`ifelse(`$2',,0,`$2')') dnl pushdef(`dz',`ifelse(`$3',,0,`$3')') dnl ixc = m4cubx # Front: placecorner(ixc*3,de2,wd2,-hg2) # FSE placecorner(ixc*3+1,de2,wd2,hg2) # FNE placecorner(ixc*3+2,de2,-wd2,hg2) # FNW mktriple(0,facetnormal(ixc)) if dot3D(triple(0),View3D) < 0 then { placecorner(ixc*3,-de2,-wd2,-hg2) # FSE placecorner(ixc*3+1,-de2,-wd2,hg2) # FNE placecorner(ixc*3+2,-de2,wd2,hg2)} # FNW ixc = m4cubx # Right: placecorner(ixc*3,-de2,wd2,-hg2) # RSE placecorner(ixc*3+1,-de2,wd2,hg2) # RNE placecorner(ixc*3+2,de2,wd2,hg2) # RNW mktriple(0,facetnormal(ixc)) if dot3D(triple(0),View3D) < 0 then { placecorner(ixc*3,de2,-wd2,-hg2) # LSE placecorner(ixc*3+1,de2,-wd2,hg2) # LNE placecorner(ixc*3+2,-de2,-wd2,hg2)}# LNW ixc = m4cubx # Top: placecorner(ixc*3,de2,wd2,hg2) # TSE placecorner(ixc*3+1,-de2,wd2,hg2) # TNE placecorner(ixc*3+2,-de2,-wd2,hg2) # TNW mktriple(0,facetnormal(ixc)) if dot3D(triple(0),View3D) < 0 then { placecorner(ixc*3,-de2,wd2,-hg2) # USE U=underside placecorner(ixc*3+1,de2,wd2,-hg2) # UNE placecorner(ixc*3+2,de2,-wd2,-hg2)}# UNW popdef(`m4cubx',`xr',`yr',`zr',`wd2',`hg2',`de2',`dx',`dy',`dz') ') define(`rots',`rot3Dz(ifelse(zr,,0,(zr)*dtor_),rot3Dy(ifelse(yr,,0,(yr)*dtor_), rot3Dx(ifelse(xr,,0,(xr)*dtor_),`$1',`$2',`$3')))') define(`placecorner',`mktriple(`$1',sum3D(dx,dy,dz,rots(`$2',`$3',`$4')))') # Recover the 4th (SW) corner and draw # `drawfacet(index,r,g,b)' # `drawfacet(index,line attributes)' define(`drawfacet',` dnl print "`$0'($@)" SE[`$1']: project(triple((`$1')*3)) NE[`$1']: project(triple((`$1')*3+1)) NW[`$1']: project(triple((`$1')*3+2)) SW[`$1']: NW[`$1']+SE[`$1']-NE[`$1'] N[`$1']: 0.5 between NW[`$1'] and NE[`$1'] C[`$1']: 0.5 between NW[`$1'] and SE[`$1'] Line[`$1']: line from N[`$1'] to NE[`$1'] then to SE[`$1'] \ then to SW[`$1'] then to NW[`$1'] then to N[`$1'] invis `$2' ') # Shortcut `processfacets(nfacets)' define(`processfacets', `indexfacets(`$1',nvisible) drawfacets(nvisible) ') # Create nvisible, arrays dircos[1..nvisible], # dist[1..nvisible], and index # sorted[1..nvisible] of facets; then sort. # Uses macros facetnormal(i) and facetcenter(i) define(`indexfacets',`nvis = 0 for i=1 to `$1' do { mktriple(0,facetnormal(i)) dx = dot3D(triple(0),View3D) if dx > 0 then { nvis +=1 dircos[nvis] = abs(dx/length3D(triple(0))) # dir cosine normal wrt View3D dist[nvis] = dot3D(facetcenter(i),View3D) # distance along View3D sorted[nvis] = i } }; `$2' = nvis if nvis > 1 then { dpquicksort(dist,1,nvis,sorted) } ') # Compute posefactor and color, then draw. define(`drawfacets', `for i=1 to `$1' do { posefactor=sqrt(dircos[i]*i/(`$1')) ifdef(`facetcolor', facetcolor, mktriple(1,(2+posefactor)/3,(2+posefactor)/3,(2+posefactor)/3) ) drawfacet(sorted[i],shaded rgbstring(triple(1))) } ifdef(`facetcolor',`popdef(`facetcolor')') ') ##################################################################### divert(0)dnl # Threeplanes [ setview( 10, 40 ) define(`m4x',0) mkthreeplanes(3/2,0.4,1); nfacets = m4x pushdef(`facetcolor',`mktriple(1,max(0,1-2*dircos[sorted[i]]), dircos[sorted[i]],dircos[sorted[i]])') processfacets(nfacets) ] define setfacetcolor { dnl This reduces color saturation depending on pose mktriple(1, (2*($1)+posefactor)/3,(2*($2)+posefactor)/3,(2*($3)+posefactor)/3) } # Transistor [ hsvtorgb(220,0.75,1, r1,g1,b1) # blueish hsvtorgb(60,0.75,1, r2,g2,b2) # greenish setview(-40, 20 ) skale = 1/2 footw = 5*skale footh = 0.5*skale footd = 3.5*skale cstripd = footd*0.3 bludp = (footd-cstripd)/2 twd = cstripd srch = 0.35*skale twh = 7.5*srch define(`footcolor',`0.45,0.45,0.45') define(`m4cux',0) # ( xC,yC,zC, wd2h,hg2t,depth, xrot,yrot,zrot) mkcuboid(0,0,footh/2,footw,footh,footd) mkcuboid(0,0,footh+bludp/2,footw,bludp,cstripd) mkcuboid( footd/2-bludp/2,0,footh+bludp/2,footw,bludp,bludp) mkcuboid(-footd/2+bludp/2,0,footh+bludp/2,footw,bludp,bludp) mkcuboid(0,0,footh+bludp+twh/2,twd,twh,footd) shelfw = (footw-twd)/2 for_(0,2,1, `mkcuboid(0,-footw/2+shelfw/2,footh+bludp+srch*(3/2+2*m4x), shelfw,srch,cstripd) mkcuboid(0, footw/2-shelfw/2,footh+bludp+srch*(3/2+2*m4x), shelfw,srch,cstripd) ') nfacets = m4cux pushdef(`facetcolor', `if sorted[i]<=6 then { setfacetcolor(footcolor) } \# first two blocks else { if sorted[i] <=12 then { setfacetcolor(r1,g1,b1) } \# blue blocks else { if sorted[i] <=15 then {setfacetcolor(r2,g2,b2) } \ else { setfacetcolor(footcolor) }}}') indexfacets(nfacets,nvisible) # Tweak the sort: t = sorted[17]; sorted[17] = sorted[18]; sorted[18] = t t = sorted[10]; sorted[10] = sorted[6]; sorted[6] = t drawfacets(nvisible) ] with .sw at last [].se+(0.2,0) .PE