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