* Circuit_macros Version 10.8, copyright (c) 2025 J. D. Aplevich under *
* the LaTeX Project Public Licence in file Licence.txt. The files of *
* this distribution may be redistributed or modified provided that this *
* copyright notice is included and provided that modifications are clearly *
* marked to distinguish them from this distribution. There is no warranty *
* whatsoever for these files. *
THE ARGUMENTS of circuit elements are optional; if omitted, default values
are assumed.
TWO-TERMINAL ELEMENTS are constructed as follows, with variations:
# Draw the initial invisible line (default length rp_len), and set the
# direction cosines:
eleminit_(`$1')
# Element body height and width
define(`m4v',...)define(`m4h',...)
# Visible lines:
{ line to rvec_(rp_len/2-m4h/2,0)
# The body drawn within a block:
{[ element body lines ] with .internal position at Here }
line to rvec_(rp_len/2-m4h/2,0) }
# Some elements overlay a block to define the body size.
{[box invis ht_ m4v wid_ m4h ] at rvec_(rp_len/2,0)}
# The final invisible line:
line to rvec_(rp_len,0) invis
A side effect of the eleminit_ macro is to change the current drawing angle.
NON-TWO-TERMINAL ELEMENTS are usually constructed within a block:
set dimension parameters
[ set size and direction from the initial linespec argument if any
set orientation (left or right)
draw internal elements
define internal locations
]
If there is a linespec argument, it determines orientation
but not the placement of the element, since [] blocks are placed
as if they were boxes.
DEBUGGING: The statement
print "`$0'($@)" ;
inserted into a macro will display the macro name and current arguments
provided the arguments do not contain double quotes. The line
`# $0'($@) will write a comment containing the same information into the
.pic output. Similarly, the m4 macro m4msg( text ) will display the
text during m4 processing.
The non-two-terminal circuit elements enclosed in [] blocks allow
a final argument not shown in the argument list. The last argument is
expanded just before exit from the [] block to allow custom additions
to the elements.
Subcomponents of some circuit elements are drawn selectively according
to a "dna_" string and a sequence of calls to sc_draw(`dna_',arg2,arg3,arg4).
If the second argument of sc_draw is a substring of the first, it is deleted
from the first and the third argument is expanded, otherwise the fourth
argument (which may be null) is expanded.
==============================================================================
This file redefines default arrow dimensions and the dotrad_ macro.
=============================================================================='
`capacitor( linespec,chars,R,height,wid )
Arg2 chars:
[d]F or blank: flat plates; d=hatched fill
[d]C = polarized, curved plate; d=variable
CP = constant phase
E = polarized rectangular plates
K = filled rectangular plates
M = rectangular plates
N = one rectangular plate
P = alternate polarized
+ = polarity sign to right of drawing dir
+L =polarity sign to left
arg3 = R: reversed orientation
arg4 = height (defaults F: dimen_/3;
C,P: dimen_/4; E,K: dimen_/5)
arg5 = wid (defaults F: height*0.3;
C,P: height*0.4; E,K: height) '
define(`capacitor',
`ifelse(`$3',R,`reversed(`capacitor',`$1',`$2',,shift(shift(shift($@))))',
`eleminit_(`$1')
define(`dna_',`ifelse(`$2',,F,`$2')')dnl
{ sc_draw(`dna_',F,
`define(`m4cht',`ifelse(`$4',,`dimen_/3',`($4)')')dnl
define(`m4cwd',`ifelse(`$5',,`m4cht*0.3',`($5)')')dnl
line to rvec_(rp_len/2-m4cwd/2,0)
{line from rvec_(0,-m4cht/2) \
to rvec_(0,m4cht/2)}
ifelse(m4a,d,`for_(1,3,1,{line from rvec_(0,m4cwd*(m4x-5/2)) \
to rvec_(m4cwd,m4cwd*(m4x-3/2))})')
move to rvec_(m4cwd,0)
{line from rvec_(0,-m4cht/2) \
to rvec_(0,m4cht/2)}
line to rvec_(rp_len/2-m4cwd/2,0) ')
sc_draw(`dna_',CP,
`define(`m4cht',`ifelse(`$4',,`dimen_/3',`($4)')')dnl
define(`m4cwd',`ifelse(`$5',,`m4cht*0.8',`($5)')')dnl
line to rvec_(rp_len/2,0)
{line from rvec_(-m4cwd/2,m4cht/2) to Here \
then to rvec_(-m4cwd/2,-m4cht/2) }
{line from rvec_(0,m4cht/2) to rvec_(m4cwd/2,0) \
then to rvec_(0,-m4cht/2) }
line from rvec_(m4cwd/2,0) to rvec_(rp_len/2,0)
')
sc_draw(`dna_',C,
`define(`m4cht',`ifelse(`$4',,`dimen_/4',`($4)')')dnl
define(`m4cwd',`ifelse(`$5',,`m4cht*0.4',`($5)')')dnl
define(`m4cr',`dimen_*0.25')dnl
line to rvec_(rp_len/2-m4cwd/2,0)
{line from rvec_(0,-m4cht/2) \
to rvec_(0,m4cht/2)}
{arc cw ifelse(m4a,d,-> wid lthick*4 ht lthick*5) \
from rvec_(m4cwd,-m4cht/2) \
to rvec_(m4cwd,m4cht/2) \
with .c at rvec_(m4cwd+sqrt((m4cr)^2-(m4cht/2)^2),0) }
line from last arc.c+vec_(-m4cr,0) \
to rvec_(rp_len/2+m4cwd/2,0) ')
sc_draw(`dna_',P,
`define(`m4cht',`ifelse(`$4',,`dimen_/4',`($4)')')dnl
define(`m4cwd',`ifelse(`$5',,`m4cht*0.4',`($5)')')dnl
define(`m4cr',`dimen_*0.25')dnl
line to rvec_(rp_len/2-m4cwd/2,0)
{line from rvec_(m4cwd,-m4cht/2) \
to rvec_(0,-m4cht/2) \
then to rvec_(0,m4cht/2) \
then to rvec_(m4cwd,m4cht/2) }
{line from rvec_(m4cwd*2/3,-m4cht*3/8) \
to rvec_(m4cwd*2/3,m4cht*3/8)}
line from rvec_(m4cwd*2/3,0) \
to rvec_(rp_len/2+m4cwd/2,0) ')
sc_draw(`dna_',E,
`define(`m4cht',`ifelse(`$4',,`dimen_/5',`($4)')')dnl
define(`m4cwd',`ifelse(`$5',,`m4cht',`($5)')')dnl
define(`m4cs',`(m4cwd/3.2)')dnl
line to rvec_(rp_len/2-m4cwd/2,0)
m4linethicktemp = linethick; thinlines_
{ lbox(m4cs,m4cht) }
move to rvec_(m4cwd,0)
{ifsvg(`lbox(-m4cs,m4cht,fill_(0))',`m4fshade(m4fill,lbox(-m4cs,m4cht))')}
linethick_(m4linethicktemp)
line to rvec_(rp_len/2-m4cwd/2,0) ')
sc_draw(`dna_',M,
`define(`m4cht',`ifelse(`$4',,`dimen_/5',`($4)')')dnl
define(`m4cwd',`ifelse(`$5',,`m4cht',`($5)')')dnl
define(`m4cs',`(m4cwd/3.2)')dnl
line to rvec_(rp_len/2-m4cwd/2,0)
m4linethicktemp = linethick; thinlines_
{ lbox(m4cs,m4cht) }
move to rvec_(m4cwd,0)
{ lbox(-m4cs,m4cht) }
linethick_(m4linethicktemp)
line to rvec_(rp_len/2-m4cwd/2,0) ')
sc_draw(`dna_',K,
`define(`m4cht',`ifelse(`$4',,`dimen_/5',`($4)')')dnl
define(`m4cwd',`ifelse(`$5',,`m4cht',`($5)')')dnl
define(`m4cs',`(m4cwd/3.2)')dnl
line to rvec_(rp_len/2-m4cwd/2,0)
{ifsvg(`lbox(m4cs,m4cht,fill_(0))',`m4fshade(m4fill,lbox(m4cs,m4cht))')}
move to rvec_(m4cwd,0)
{ifsvg(`lbox(-m4cs,m4cht,fill_(0))',`m4fshade(m4fill,lbox(-m4cs,m4cht))')}
line to rvec_(rp_len/2-m4cwd/2,0) ')
sc_draw(`dna_',N,
`define(`m4cht',`ifelse(`$4',,`dimen_/5',`($4)')')dnl
define(`m4cwd',`ifelse(`$5',,`m4cht*2/3',`($5)')')dnl
define(`m4cs',`(m4cwd/3.2*3/2)')dnl
line to rvec_(rp_len/2-m4cwd/2,0)
{ lbox(m4cs,m4cht) }
move to rvec_(m4cwd,0)
{line from rvec_(0,m4cht/2) to rvec_(0,-m4cht/2) }
line to rvec_(rp_len/2-m4cwd/2,0) ')
}
ifinstr(`$2',+L,
`{ move to rvec_(rp_len/2-m4cwd/2-m4cht/3,m4cht/3)
{line thick 0.5 from rvec_(m4cht/6,0) \
to rvec_(-m4cht/6,0)}
line thick 0.5 from rvec_(0,m4cht/6) \
to rvec_(0,-m4cht/6)}',
`$2',+,
`{ move to rvec_(rp_len/2-m4cwd/2-m4cht/3,-m4cht/3)
{line thick 0.5 from rvec_(m4cht/6,0) \
to rvec_(-m4cht/6,0)}
line thick 0.5 from rvec_(0,m4cht/6) \
to rvec_(0,-m4cht/6)}')
{[box invis ht_ m4cht wid_ m4cwd ] at rvec_(rp_len/2,0)}
line to rvec_(rp_len,0) invis ')')
`resistor( linespec, cycles, chars, cycle wid )
chars: AC: complex element
E: ebox
ES: ebox with slash
F: FDNR (freq-dependent neg resistor)
Q: offset
H: squared
N: IEEE (default)
B: not burnable
T: thermistor
V: varistor variant
R: to right of drawing direction'
define(`resistor',
`eleminit_(`$1'); M4S: last line.start; M4E: last line.end
define(`m4type',ifelse(`$3',,N,`$3',R,N,`$3')`')dnl
define(`m4neg',sc_draw(`m4type',R,-))dnl
define(`m4cycles',`ifelse(`$2',,3,(`$2'))')dnl
define(`m4cwid',`ifelse(`$4',,(dimen_/6),`($4)')')dnl
define(`m4lgth',`(m4cycles*m4cwid)')dnl
ifelse(
`$2',E, # This is obsolete but kept for now
`ebox(`$1',shift(shift($@)))',
m4type,N,
`define(`m4nN',`eval(2*m4cycles)')dnl Default resistor:
define(`m4v',2)dnl
if m4lgth > rp_len then { eleminit_(to rvec_(m4lgth,0)) }
tr_xy_init(last line.c, m4cwid/4, m4neg)dnl
{ line from last line.start to tr_xy(-m4nN,0)\
for_(2,m4nN,2,
`then to tr_xy(eval(2*m4x-3-m4nN), m4v) \
then to tr_xy(eval(2*m4x-1-m4nN),-m4v) \')dnl
then to tr_xy(m4nN, 0) \
then to last line.end # This could be replaced for obtuse directions:
[box invis ht_ m4cwid*m4v/2 wid_ m4cwid*m4nN/2] at 2nd last line.c
}',
m4type,Q,
`define(`m4nQ',`eval(2*m4cycles)') define(`m4v',2)dnl
if m4cwid*m4nQ/2 > rp_len then {
eleminit_(to rvec_(m4cwid*m4nQ/2,0)) }
tr_xy_init(last line.c, m4cwid/4, m4neg)dnl
{ line from last line.start to tr_xy(-m4nQ,0)\
for_(2,m4nQ,2,
`then to tr_xy(eval(2*m4x-2-m4nQ), m4v*2) \
then to tr_xy(eval(2*m4x-m4nQ),0) \')dnl
then to tr_xy(m4nQ, 0) \
then to last line.end
[box invis ht_ m4cwid*m4v/2 wid_ m4cwid*m4nQ/2] \
at 2nd last line.c + ta_xy(0,m4v)
}',
m4type,ES,
`ebox(`$1',m4lgth,dimen_/5)
{line from last line.c+vec_( dimen_/2*0.3, dimen_/5/2) \
to last line.c+vec_(-dimen_/2*0.3,-dimen_/5/2)}',
m4type,F,
`define(`m4cht',`dimen_/3') define(`m4cwd',`m4cht*0.9')dnl
{line to rvec_(rp_len/2-m4cwd/2,0)
{[for i=0 to m4cycles do {line from vec_(i*m4cwd/m4cycles,0) \
to vec_(i*m4cwd/m4cycles,m4cht)}] at rvec_(m4cwd/2,0)}
line from rvec_(m4cwd,0) to rvec_(rp_len/2+m4cwd/2,0)}',
m4type,H,
`define(`m4nH',`eval(2*m4cycles-1)')dnl
define(`m4hh',`m4cwid*6/5/4') define(`m4v',7/3)dnl
if m4hh*m4nH/2 > rp_len then { eleminit_(to rvec_(m4hh*m4nH/2,0)) }
tr_xy_init(last line.c, m4hh, m4neg)dnl
{ line from last line.start to tr_xy(-m4nH,0)\
for_(-m4nH,m4nH,2,
`ifelse(eval(((m4x+m4nH)/2)%2),0,
`then to tr_xy(m4x,m4v) \
then to tr_xy(eval(m4x+2),m4v) \',
`then to tr_xy(m4x,0) \
ifelse(m4x,m4nH,,`then to tr_xy(eval(m4x+2),0)')\')')dnl
then to last line.end
[move from tr_xy(-m4nH,0) to tr_xy(m4nH,0) \
then to tr_xy(m4nH,m4v) then to tr_xy(-m4nH,m4v)] \
at 2nd last line.c+vec_(0,m4neg`'m4hh*m4v/2) }',
m4type,T,
`resistor(`$1',`$2',sc_draw(`m4type',T),`$4')
[ tl=m4lgth/2+m4cwid
spline ifdpic(ctension_) from rvec_(ifdpic(0,-tl*3/40),m4cwid*4/3)\
to rvec_( tl/3,m4cwid*4/3) then to rvec_( tl,m4cwid*8/9) \
then to rvec_( tl,-m4cwid*8/9) then to rvec_( tl/3,-m4cwid*4/3) \
then to rvec_(-tl/3,-m4cwid*4/3) then to rvec_(-tl,-m4cwid*8/9) \
then to rvec_(-tl,m4cwid*8/9) then to rvec_(-tl/3,m4cwid*4/3) \
then to rvec_(ifdpic(0,tl*3/40),m4cwid*4/3) `$4'
] with .c at last line.c ',
m4type,V,
`define(`m4ht',`(m4lgth/2)')dnl
{line to rvec_(max(0,rp_len/2-m4lgth/2),0)
{[m4fshade(m4fill,line to rvec_(0,ifinstr(`$3',R,,-)m4ht/2) \
then to rvec_(m4lgth,ifinstr(`$3',R,-)m4ht/2) \
then to rvec_(m4lgth,0) then to Here)] at rvec_(m4lgth/2,0) }
line from rvec_(m4lgth,0) to rvec_(max(0,rp_len/2+m4lgth/2),0) } ',
m4type,B,
`resistor(`$1',`$2',sc_draw(`m4type',B),`$4'); M4LBC: last line.c
m4lbwd = last [].wid_+lthick*2; m4lbht = last [].ht_+lthick*2
[lbox(m4lbwd,m4lbht,thick 0.4)] with .c at M4LBC
[lbox(m4lbwd+lthick*4,m4lbht+lthick*4,thick linethick/2)] with .c at M4LBC',
m4type,AC,
`ebox(`$1')
{ ACsymbol(at last [],m4cwid*3.5/4,m4cwid/2,R)
[] wid 2nd last [].wid ht 2nd last [].ht at 2nd last [] } ')
ifelse(m4type,E,`ebox(`$1')',
`line invis from M4S to M4E') ')
`potentiometer(linespec, cycles,
fractional pos, length, fractional pos, length,...)
Resistor in a block, tapped at fractional positions
with specified (possibly negative) arrow lengths.
Taps are labelled T1, T2, ...'
define(`potentiometer',`[R: resistor(`$1',`$2')
define(`m4n',`ifelse(`$2',,3,(`$2'))')dnl
Start: R.start; End: R.end; C: R.c
m4pot_arrows(1,ifelse(`$3',,0.5,`$3'),ifelse(`$4',,`dimen_*5/12',`$4'),
shift(shift(shift(shift($@)))))] ')
define(`m4pot_arrows',`ifelse(`$2',,,`FrP: C+vec_((`$2'-0.5)*m4n*dimen_/6,0)
T`$1': FrP + vec_(0,ifelse(`$3',,`dimen_*5/12',`$3'))
x = (`$2')*4*m4n+1; x = (int(x)%4)+(x-int(x))
{arrow from T`$1' to FrP+vec_(0,dimen_/12*(1-(x-2)*sign(x-2)))}
m4pot_arrows(incr($1),shift(shift(shift($@))))')')
`KelvinR(cycles,[R],cycle wid)
IEEE resistor with kelvin taps added
if arg1 is blank then a [] block is used
Uses m4nN and tr_xy from resistor'
define(`KelvinR',`[
M4R: resistor(,`$1',,`$3') define(`m4KRm',`ifinstr(`$2',R,-,+)')
{ dot(at tr_xy(-m4nN,0),lthick)
line to tr_xy(-m4nN-1,m4KRm`'2) then to tr_xy(-m4nN-1,m4KRm`'4)
T1: Here
dot(at tr_xy(m4nN,0),lthick)
line to tr_xy(m4nN+1,m4KRm`'2) then to tr_xy(m4nN+1,m4KRm`'4)
T2: Here }
Start: M4R.start; End: M4R.end; C: M4R.c
`$4' ]') ')
`FTcap(chars)
Feed-through capacitor; composite element
derived from a two-terminal element.
Defined points: .Start, .End, .C
chars: A|B|C|D element type'
define(`FTcap',`[ define(`FTctyp',`ifelse(`$1',,A,`$1')')dnl
ifelse(FTctyp,A,
`capacitor(to vec_(dimen_*2/3,0))
Start: last line.start; End: last line.end; C: last line.c
Conductor: line from C+vec_(0,dimen_/3) to C+vec_(0,-dimen_/3)
T1: last line.start; T2: last line.end',
FTctyp,B,
`capacitor(to vec_(dimen_*2/3,0),C)
Start: last line.start; End: last line.end; C: last line.c
r = last arc.rad-hlth
T1: (0.5 between 2nd line.end and last arc.c-vec_(r,0)) + vec_(0,dimen_/3)
T2: T1+(0,-dimen_*2/3)
Conductor: line from T1 to T2',
FTctyp,C,
`line to vec_(dimen_*2/3,0)
Start: last line.start; End: last line.end; C: last line.c
rp_a = rp_ang
capacitor(from C to C-vec_(0,dimen_/10),C)
point_(rp_a)
line from last line.end to last line.end-vec_(0,dimen_/3)
T: Here',
FTctyp,D,
`Start: Here
capacitor(to rvec_(dimen_/3,0),C)
C: Here
{ line to rvec_(0,-dimen_/3); T: Here }
End: rvec_(dimen_/3,0)
rp_a = rp_ang
capacitor(from End to Here,C)
point_(rp_a)')
`$2' ]')
`addtaps([ahead | type=ahead;name=Name],
fractional pos, length, fractional pos, length,...)
ahead = blank or one of . - <- -> <->
Tap names are Tap1, Tap2, ... or
Name1, Name2, ... if specified'
define(`addtaps',`
ifelse(`$2',,`undefine(`m4tap_x')popdef(`m4type',`m4name')',
`ifdef(`m4tap_x',`define(`m4tap_x',incr(m4tap_x))',
`define(`m4tap_x',1) dnl 1st time through
M4tap_w: last [].w_; M4tap_e: last [].e_
pushkeys_(`$1',type::N; name:Tap:N)dnl
ifelse(m4type,,`ifinstr(`$1',=,,`poppushdef(`m4type',`$1')')')dnl
M4tap_xy: (last [].wid_,last [].ht_)')
{define(`m4tapl',`ifelse(`$3',,`dimen_/3',`$3')')dnl
move to (`$2' between M4tap_w and M4tap_e) + vec_(0,sign(m4tapl)*M4tap_xy.y/2)
ifinstr(m4type,.,`{dot(,lthick)}');dnl
line ifelse(m4type,.,,m4type,-,,m4type) to rvec_(0,m4tapl)
m4name`'m4tap_x: Here }
addtaps(,shift(shift(shift($@))))')')
`tapped(`two-terminal element', . | <- | -> | <-> ,
fractional pos, length, fractional pos, length,...)
Draw the two-terminal element and taps in a [] block'
define(`tapped',`[ $1
Start: last line.start; End: last line.end; C: last line.c
addtaps(shift($@)) ]')
`shielded(`two-terminal element',L|U, line attributes )
L= shield left half (wrt drawing direction)
R= shield right half (default both halves)'
define(`shielded',`[ $1
Start: last line.start; End: last line.end; C: last line.c
W: last line.c - vec_(last [].wid_/2+dimen_/8,0)
E: last line.c + vec_(last [].wid_/2+dimen_/8,0)
NW: last [].nw_ + vec_(-dimen_/8,dimen_/8)
NE: last [].ne_ + vec_(dimen_/8,dimen_/8)
SE: last [].se_ + vec_(dimen_/8,-dimen_/8)
SW: last [].sw_ + vec_(-dimen_/8,-dimen_/8)
ifinstr(`$2',L,`line from W to NW then to NE then to E dashed `$3'',
`$2',R,`line from W to SW then to SE then to E dashed `$3'',
`line from W to NW then to NE then to SE then to SW then to W dashed `$3'')
`$4']')
`b_current( label, above_|below_, O[ut],
S[tart]|E[nd], frac )
Branch current for last-drawn element. The arrowhead
is drawn frac (default 2/3) of the way between
the line end and element body.'
define(`b_current',
`define(`m4y',`ifelse(`$5',,2/3,`($5)')')dnl
define(`m4v',`ifinstr(`$4',E,
`ifinstr(`$3',O,-)',`ifinstr(`$3',O,,-)')arrowht')dnl
define(`m4h',`(rp_len-last [].wid_)/2')
{ move to last line.start+vec_(ifinstr(`$4',E,`rp_len-')dnl
ifinstr(`$3',O,`(m4h-arrowht)*m4y',`(m4h*m4y+arrowht/3)'),0)
arrow <- m4c_l to rvec_(m4v,0) ifelse(`$1',,,
`m4lstring(`$1',"sp_`iflatex(`$ `$1'$',`$1')'sp_") \
ifelse(`$2',,`above_',`$2')')}')
`larrow( label, <-, separation )
Arrow alongside the left of the last-drawn
element'
define(`larrow',`define(`m4h',`min(lin_leng(last line),linewid)/2')dnl
define(`m4v',`ifelse(`$3',,`5pt__',`($3)')')dnl
{arrow `$2' from last [].n_+vec_(-m4h,m4v) \
to last [].n_+vec_(m4h,m4v) \
m4lstring(`$1',"sp_`iflatex(`$ `$1'$',` $1')'sp_") above_}')
`rarrow( label, <-, separation )
Arrow alongside the right of the last-drawn
element'
define(`rarrow',`define(`m4h',`min(lin_leng(last line),linewid)/2')dnl
define(`m4v',`ifelse(`$3',,`5pt__',`($3)')')dnl
{arrow `$2' from last [].s_+vec_(-m4h,-m4v) \
to last [].s_+vec_(m4h,-m4v) \
m4lstring(`$1',"sp_`iflatex(`$ `$1'$',` $1')'sp_") below_}')
`inductor( linespec, W|L, cycles, M|P|K[n],
loop wid )
W=wide arcs (default narrow); L=looped arcs
arg3= integer (number of loops)
arg4= M[n]=metal core
P[n]=(ferrite) powder core (dashed lines)
K[n]=long-dashed core lines
n=integer (default 2 lines)
arg5 loop wid defaults W,L: dimen_/5,
other: dimen_/8'
define(`inductor',`eleminit_(`$1')
define(`m4hlw',`ifelse(`$5',,`dimen_/10',`($5)/2')')dnl half loop wid
define(`m4n',`ifelse(`$3',,4,`$3')')dnl
ifelse(`$2',W, `define(`m4wd',((2*m4n-2)*m4c2t+2*m4ct)*m4hlw)',
`$2',L, `define(`m4wd',(m4n+1)*m4hlw)',
`define(`m4ht',`ifelse(`$5',,`dimen_/16',(`$5')/2)')dnl half other loop wid
define(`m4wd',m4n*m4ht*2)')dnl
{ line to rvec_((rp_len-m4wd)/2,0)
{M4coil: [ S: Here;
ifelse(`$2',W,`define(`m4ht',`(1+m4st)*m4hlw')dnl
define(`m4dp',`(m4s2t-m4st)*m4hlw') round
arc cw from Here to rvec_(vscal_(m4hlw,m4ct+m4c2t,m4st-m4s2t)) \
with .c at rvec_(vscal_(m4hlw,m4ct,m4st)); round
for m4i=3 to m4n do { arc cw from Here to rvec_(vscal_(m4hlw,2*m4c2t,0)) \
with .c at rvec_(vscal_(m4hlw,m4c2t,m4s2t)); round }
arc cw from Here to rvec_(vscal_(m4hlw,m4ct+m4c2t,m4s2t-m4st)) \
with .c at rvec_(vscal_(m4hlw,m4c2t,m4s2t)); round ',
`$2',L,`define(`m4ht',`m4hlw*10/8')define(`m4dp',`m4hlw/2')dnl
round; spline ifdpic(0.55) to rvec_(0,m4ht) \
for_(1,m4n,1,`\
then to rvec_((m4x+0.3)*m4hlw, m4ht) \
then to rvec_((m4x+0.3)*m4hlw,-m4dp) \
then to rvec_((m4x-0.3)*m4hlw,-m4dp) \
then to rvec_((m4x-0.3)*m4hlw, m4ht) \')\
then to rvec_(m4wd,m4ht) \
then to rvec_(m4wd,0); round ',
`define(`m4dp',0)dnl
ifelse(ifpstricks(T)`'ifmpost(T)`'ifpgf(T)`'ifsvg(T),T,
`define(`m4y')',`undefine(`m4y')')dnl
ifdef(`m4y',`{line to rvec_(0,-hlth)};')
for m4i=1 to m4n do {
arc cw from Here to rvec_(m4ht*2,0) with .c at rvec_(m4ht,0)
ifdef(`m4y',`{line to rvec_(0,-hlth)}') } ') ] with .S at Here }
ifelse(ifinstr(`$4',M,T,`$4',P,T,`$4',K,T),T,
`define(`m4nL',ifelse(len(`$4'),1,2,substr(`$4',1)))dnl
define(`m4hs',`(dimen_/24+(m4nL-1)*dimen_/16)')dnl
{ m4m_core(M4coil.S+vec_(m4wd/2,0), m4wd, m4ht+dimen_/24, dimen_/16,
ifinstr( `$4',P,`dashed m4wd/(2*m4n+1)',
`$4',K,`dashed m4wd/(2*m4n+1)*3'), m4nL)
[ box invis wid M4coil.wid ht M4coil.ht at M4coil
M: move from M4Core`'m4nL.start to M4Core`'m4nL.end ] \
with .M.c at M4Core`'m4nL.c }')
line from rvec_(m4wd,0) to rvec_((rp_len+m4wd)/2,0) }
line to rvec_(rp_len,0) invis ')
`m4m_core(bottom center, length, ht offset,
separation, linetype, nlines)
nlines=lines for the metal core'
define(`m4m_core',`for_(1,`$6',1,`{M4Core`'m4x: line \
from `$1'+vec_(-(`$2')/2,`$3'+(`$4')*(m4x-1)) \
to `$1'+vec_( (`$2')/2,`$3'+(`$4')*(m4x-1)) `$5''})')
define(`m4ct',`Cos(25)')define(`m4st',`Sin(25)')
define(`m4c2t',`Cos(50)')define(`m4s2t',`Sin(50)')
`transformer( linespec, L|R, np,
[A|M[n]|P[n]|K[n]][W|L][D1|D2|D12|D21], ns )
2-winding transformer or choke:
np = number of primary arcs
ns = number of secondary arcs
A = air core;
M[n] = metal core (default); n=number of lines
P[n] = powder (dashed) core
K[n] = long dashed core
W = wide windings; L = looped windings
D1: phase dots at P1 and S1 ends; D2: dots
at P2 and S2 ends; D12: dots at P1 and S2
ends; D21: dots at P2 and S1 ends'
define(`transformer', `[ P1: Here define(`m4drt',m4_dir_)
define(`m4WL',`ifinstr(`$4',W,W,`$4',L,L)')dnl
define(`m4np',`ifelse(`$3',,4,(`$3'))')dnl
define(`m4ns',`ifelse(`$5',,4,(`$5'))')dnl
ifelse(`$1',,`mvw = max(\
ifelse(m4WL,W,`dimen_/5*((m4np-1)*m4c2t+m4ct)',`m4np*dimen_/8'),dimen_*2/3)
move to P1+vec_(mvw,0)',
move `$1' )
P2: Here
TP: 0.5 between P1 and P2
L1: inductor(from ifelse(`$2',R,`P2 to P1',`P1 to P2'),m4WL,`$3')
define(`m4WP',m4wd)dnl
define(`m4t',`ifelse(m4WL,W,((2*m4ns-2)*m4c2t+2)*m4hlw,m4WL,L,(m4ns+1)*m4hlw,
m4ns*m4ht*2)')dnl
ifinstr(`$4',A,
`move to last line.c+vec_(0,m4ht*ifelse(m4WL,W,3,m4WL,L,3,4))',
`define(`m4LL',`regexp(`$4',[MPK]\([0-9][0-9]*\),\1)')dnl
define(`m4nL',`ifelse(m4LL,,2,m4LL)')dnl
m4m_core(rvec_(-(rp_len/2),0), max(m4wd,m4t), m4ht+dimen_/12, dimen_/8,
ifinstr( `$4',P,`dashed m4wd/(2*m4n+1)',
`$4',K,`dashed m4wd/(2*m4n+1)*3'), m4nL)
move to last line.c+vec_(0,m4ht+dimen_/12) ')
TS: Here
S2: rvec_( ifelse(`$2',R,-)(ifelse(`$5',,rp_len/2,m4t/2)), 0 )
S1: 2 between S2 and Here
L2: inductor(from ifelse(`$2',R,`S1 to S2',`S2 to S1'),m4WL,`$5')
rpoint_(from P1 to P2) define(`m4WS',m4wd)
ifinstr(`$4',D1,
`m4trdot(P1,P2,-,m4WP,ifelse(`$2',R,-),D1:)
ifinstr(`$4',D12,`m4trdot(S1,S2, ,m4WS,ifelse(`$2',R,,-),D2:)',
`m4trdot(S1,S2,-,m4WS,ifelse(`$2',R,,-),D2:)')',
`$4',D2,
`m4trdot(P1,P2,,m4WP,ifelse(`$2',R,-),D1:)
ifinstr(`$4',D21,`m4trdot(S1,S2,-,m4WS,ifelse(`$2',R,,-),D2:)',
`m4trdot(S1,S2, ,m4WS,ifelse(`$2',R,,-),D2:)')')
m4xpand(m4drt`'_)
`$6' ]')
define(`m4trdot',`{`$6'dot(at (0.5 between `$1' and `$2') \
+vec_(`$3'((`$4')/2+m4hlw),`$5'dimen_/16), dotrad_/2)}')
`delay( linespec, width, attributes or keys )
keys:
wdth=expr;
lgth=expr;
type=A|S;
body=attributes; e.g. shaded '
define(`delay',`eleminit_(`$1')
pushkeys_(`$3',`wdth:ifelse(`$2',,delay_rad_*2,`$2'); lgth:m4`'wdth*5/6;
type:A:N; body::N;') dnl
ifinstr(`$3',=,,`ifelse(m4body,,`poppushdef(`m4body',`$3')')')dnl
ifelse(m4type,S,`popdef(`m4lgth',`m4wdth')dnl
pushkeys_(`$3',`lgth:dimen_*6/5; wdth:m4`'lgth/4')')dnl
{ line to rvec_(rp_len/2-m4lgth/2,0)
{ifelse(m4type,A,`[ W: Here
line from rvec_(m4wdth/3,-m4wdth/2) to rvec_(0,-m4wdth/2) \
then to rvec_(0,m4wdth/2) then to rvec_(m4wdth/3,m4wdth/2) m4body
arc cw to rvec_(0,-m4wdth) with .c at rvec_(0,-m4wdth/2) m4body ]',
m4type,S,
`rotbox(m4lgth,m4wdth,m4body,r=m4wdth/2,
{rotbox(m4wdth/4,m4wdth,) with .W at rvec_(-m4lgth+m4wdth/2,0)})')\
with .W at Here }
line from rvec_(m4lgth,0) to rvec_(rp_len/2+m4lgth/2,0) }
line to rvec_(rp_len,0) invis dnl
popdef(`m4wd',`m4wdth',`m4type',`m4body') ')
`xtal( linespec, keys ) (2-terminal crystal)
keys:
type=N (default) or R (round);
type N keys:
lgth=expr; (body length)
wdth=expr; (body width)
bxwd=expr; (body inner box width)
box= box attributes; (shaded ...)
type R keys:
outerdiam=expr;
innerdiam=expr;
outer= outer circle attributes; (dotted ...)
inner= inner circle attributes; (shaded ...)'
define(`xtal',`eleminit_(`$1') pushkey_(`$2',type,N,N)
ifelse(m4type,R,`pushkeys_(`$2',`outerdia:dimen_/3;innerdia:m4`'outerdia*0.4;
outer::N; inner::N;') define(`m4wd',m4outerdia) ',
`pushkeys_(`$2',`wdth:dimen_/4; lgth:m4wdth*2/3; bxwd:m4lgth/2; box::N;')dnl
define(`m4wd',m4lgth) ')
{ line to rvec_(rp_len/2-m4wd/2,0)
{[ Orig: Here; ifelse(m4type,R,
`{circle diam m4outerdia at rvec_(m4outerdia/2,0) m4outer}
{circle diam m4innerdia at rvec_(m4outerdia/2,0) m4inner}
popdef(`m4type',`m4outerdia',`m4innerdia',`m4outer',`m4inner') ',
`{line from rvec_(0,-m4wdth/3) \
to rvec_(0,m4wdth/3)}
{ move to rvec_(m4lgth/2-m4bxwd/2,0)
line to rvec_(0,m4wdth/2) \
then to rvec_(m4bxwd,m4wdth/2) \
then to rvec_(m4bxwd,-m4wdth/2) \
then to rvec_(0,-m4wdth/2) \
then to Here m4box }
move to rvec_(m4lgth,0)
{line from rvec_(0,-m4wdth/3) \
to rvec_(0,m4wdth/3)}
popdef(`m4type',`m4wdth',`m4lgth',`m4bxwd',`m4box')') ] with .Orig at Here}
line from rvec_(m4wd,0) to rvec_(rp_len/2+m4wd/2,0) }
line to rvec_(rp_len,0) invis ')
`source( linespec, chars,
diameter, R, attributes, body name)
chars:
AC = AC source;
B = bulb;
F = fluorescent;
G = generator;
H = step function;
I = current source;
i = alternate current source;
ii = double arrowhead current source;
ti = truncated-bar current source;
dci = DC current source;
L = lamp;
N = neon; NA = neon 2; NB = neon 3;
P = pulse;
Q = charge;
R = ramp;
S[C[r]|E[r]] = sinusoid;
SC = quarter arc; SE = arc; r = right orientation;
T = triangle;
U = square-wave;
V = voltage source;
v = alternate voltage source;
tv = truncated bar voltage source;
dcv = DC voltage source;
X = interior X;
other = custom interior label or waveform;
arg 4: R = reversed polarity;
arg 5 modifies the circle with e.g., color or fill
arg 6 names the body [] block'
define(`source',`ifelse(`$4',R,
`reversed(`source',`$1',`$2',`$3',,shift(shift(shift(shift($@)))))',
`eleminit_(`$1')
define(`m4h',ifelse(`$3',,`sourcerad_',`($3)/2'))dnl
ifelse(
`$2',G,`m4_sourceGQ(`$6',$@)',
`$2',Q,`m4_sourceGQ(`$6',$@)',
`{ line to rvec_(rp_len/2-m4h,0)
move to rvec_(m4h,0)
{ Src_C: circle rad m4h ifelse(`$2',dci,invis) `$5' at Here }
ifelse(`$2',,,
`$2',F,`{ line from rvec_(-m4h,0) \
to rvec_(-m4h/2,0)}
{ line from rvec_(-m4h/2,-m4h/2) \
to rvec_(-m4h/2,m4h/2)}
{ line from rvec_(m4h/2,-m4h/2) \
to rvec_(m4h/2,m4h/2)}
{ line from rvec_(m4h,0) \
to rvec_(m4h/2,0)}',
`$2',I,`{arrow from rvec_(-m4h*3/4,0) \
to rvec_(m4h*3/4,0)}',
`$2',dci,`{arrow from rvec_(-m4h*3/4,0) \
to rvec_(m4h*3/4,0)}
ifdef(`dcigapangle_',,`define(`dcigapangle_',20)')dnl
{arc from Src_C+vec_(Rect_(m4h,270+dcigapangle_/2)) \
to Src_C+(Rect_(m4h,90-dcigapangle_/2)) with .c at Src_C}
{arc from Src_C+vec_(Rect_(m4h,90+dcigapangle_/2)) \
to Src_C+(Rect_(m4h,270-dcigapangle_/2)) with .c at Src_C} ',
`$2',ti,`{line thick 2*linethick from rvec_(0,-m4h) \
to rvec_(0,m4h) chop m4h/4}',
`$2',ii,`{line from rvec_(-m4h,0) \
to rvec_(m4h,0)}
{line thick 1.2*linethick from rvec_(m4h/12,-m4h*0.45) \
to rvec_(m4h*5/6,0) \
then to rvec_(m4h/12,m4h*0.45)}
{line thick 1.2*linethick from rvec_(-m4h*3/4,-m4h*0.45) \
to Here \
then to rvec_(-m4h*3/4,m4h*0.45)}',
`$2',i,`{line from rvec_(0,-m4h) \
to rvec_(0,m4h)}',
`$2',B,`{line from rvec_(-m4h,0) \
to rvec_(-m4h*2/3,0)
round
arc ccw to rvec_(m4h*12/12,0) with .c at rvec_(m4h*12/24,0)
arc ccw to rvec_(-m4h*2/3,0) with .c at rvec_(-m4h*1/3,0)
arc ccw to rvec_(m4h*12/12,0) with .c at rvec_(m4h*12/24,0)
round
line to rvec_(m4h/3,0)}',
`$2',H,`{ line from Here+(-m4h/2,-m4h/3) \
to Here+(0,-m4h/3) \
then to Here+(0,m4h/3) \
then to Here+(m4h/2,m4h/3) }',
`$2',L,`{line from rvec_(-m4h,0) \
to rvec_(-m4h/4,0)
round
spline to rvec_(m4h/12,m4h*2/3) \
then to rvec_(m4h*5/12,m4h*2/3) \
then to rvec_(m4h/2,0)
round
line to rvec_(m4h*3/4,0)}',
`$2',NA,`{ line from rvec_(-m4h,0) \
to rvec_(-m4h/5,0)
{ line to rvec_(0,m4h) with .c at Here } }
{ line from rvec_(m4h,0) \
to rvec_(m4h/5,0)
{ line to rvec_(0,m4h) with .c at Here } }
{ dot(at rvec_(-m4h/2,-m4h/2)) } ',
`$2',dcv,`{ line to rvec_(0,m4h) with .c at rvec_(-m4h/5,0) }
{ line to rvec_(0,m4h) with .c at rvec_(m4h/5,0) } ',
`$2',NB,`{ line from rvec_(-m4h,0) \
to rvec_(-m4h/2,0)
{ line to rvec_(0,m4h) with .c at Here } }
{ line from rvec_(m4h,0) \
to rvec_(m4h/2,0)
{ dot(,,1) } }
{ dot(at rvec_(0,-m4h/2)) } ',
`$2',N,`{ {line from rvec_(-m4h,0) \
to rvec_(-m4h/2,0)}
for_(70,250,180,
`{ line from rvec_(Rect_(m4h/2,-m4x)) \
to rvec_(Rect_(m4h/2,m4x))
round }
{ arc cw from rvec_(Rect_(m4h/2,m4x)) \
to rvec_(Rect_(m4h/2,-m4x)) \
with .c at Here
round }')
{line from rvec_(m4h/2,0) \
to rvec_(m4h,0)}}',
`$2',V,`{"ifsvg(-,`\scriptsize$-$')" at rvec_(-m4h/2,0) ifsvg(+(0,textht/10))}
{"ifsvg(svg_small(+),`\scriptsize$+$')" \
at rvec_( m4h/2,0) ifsvg(+(0,textht/10))}',
`$2',tv,`{line thick 2*linethick from rvec_(-m4h,0) \
to rvec_(m4h,0) chop m4h/4}',
`$2',v,`{line from rvec_(-m4h,0) \
to rvec_(m4h,0)}',
`$2',AC,`{ACsymbol(,,,AR)}',
`$2',P,`{ line from Here+(-m4h/2,-m4h/4) \
to Here+(-m4h/4,-m4h/4) \
then to Here+(-m4h/4,m4h/4) \
then to Here+(m4h/4,m4h/4) \
then to Here+(m4h/4,-m4h/4) \
then to Here+(m4h/2,-m4h/4) }',
`$2',U,`{ line from Here+(-m4h/2,0) \
to Here+(-m4h/2,m4h/3) \
then to Here+(0,m4h/3) \
then to Here+(0,-m4h/3) \
then to Here+(m4h/2,-m4h/3) \
then to Here+(m4h/2,0) }',
`$2',R,`{ line from Here+(-m4h*2/3,-m4h/3) \
to Here+(m4h/3,m4h/2) \
then to Here+(m4h/3,-m4h/3) }',
`$2',SCr,`{ arc cw from rvec_(-m4h,0) \
to rvec_(0,-m4h) \
with .c at rvec_(-m4h,-m4h) }',
`$2',SC,`{ arc from rvec_(-m4h,0) \
to rvec_(0,m4h) \
with .c at rvec_(-m4h,m4h) }',
`$2',SEr,`{ arc cw from Cintersect(Here,m4h,rvec_(0,-2*m4h),1.8*m4h,R) \
to Cintersect(Here,m4h,rvec_(0,-2*m4h),1.8*m4h) \
with .c at rvec_(0,-2*m4h) }',
`$2',SE,`{ arc from Cintersect(Here,m4h,rvec_(0,2*m4h),1.8*m4h) \
to Cintersect(Here,m4h,rvec_(0,2*m4h),1.8*m4h,R) \
with .c at rvec_(0,2*m4h) }',
`$2',S,`{ACsymbol(,,,R)}',
`$2',T,`{ line from Here+(-m4h*3/4,-m4h/4) \
to Here+(-m4h/4,m4h/4) \
then to Here+(m4h/4,-m4h/4) \
then to Here+(m4h*3/4,m4h/4) }',
`$2',X,`define(`m4v',`m4h/sqrt(2)')dnl
{line from rvec_(-m4v,m4v) \
to rvec_(m4v,-m4v)}
{line from rvec_(-m4v,-m4v) \
to rvec_(m4v,m4v)}',
`{$2}' )
line from rvec_(m4h,0) \
to rvec_(rp_len/2,0)}
{ifelse(`$6',,,`$6':)[box invis ht_ m4h*2 wid_ m4h*2] at rvec_(rp_len/2,0)}')
line to rvec_(rp_len,0) invis ')')
`Internal to source macro:'
define(`m4_sourceGQ',
`m4sh = m4h*3/4
m4sv = sqrt((m4h)^2-m4sh^2)
{ line to rvec_(rp_len/2-(m4h+m4sh),0)
{ifelse(`$1',,,`$1':)[ Cx: rvec_(m4h,0)
ifelse(`$6',,,
`{circle invis rad m4h `$6' with .c at Cx}
{circle invis rad m4h `$6' with .c at Cx+vec_(m4sh*2,0)}')
L: Cx+vec_(m4sh, m4sv)
R: Cx+vec_(m4sh,-m4sv)
M1: Cx-vec_(m4h/6,0)
C1: circle rad m4h with .c at Cx `$5'
C2: ifelse(`$3',G,`circle rad m4h',`arc rad m4h from R to L') \
`$5' with .c at C1 +vec_(m4sh*2,0)
M2: C2+vec_(m4h/6,0)
] at rvec_(m4h+m4sh,0)}
line from rvec_((m4h+m4sh)*2,0) \
to rvec_(rp_len/2+(m4h+m4sh),0) } ')
`ttmotor( linespec, string, diameter, brushwid, brushht )'
define(`ttmotor',`eleminit_(`$1')
define(`m4r',ifelse(`$3',,`sourcerad_',`($3)/2'))dnl
define(`m4w',ifelse(`$4',,`sourcerad_/4',`($4)'))dnl
define(`m4h',ifelse(`$5',,`sourcerad_/2',`($5)'))dnl
define(`m4cr',`(m4r-sqrt(max(m4r*m4r-m4h*m4h/4,0)))')dnl
{ line to rvec_(max(rp_len/2-m4r-m4w,0),0)
{ line from rvec_(m4w+m4cr,m4h/2) \
to rvec_(0,m4h/2) \
then to rvec_(0,-m4h/2) \
then to rvec_(m4w+m4cr,-m4h/2) }
{ TTM_C: circle rad m4r \
at rvec_(m4w+m4r,0) ifelse(`$2',,,`m4lstring($2,"$2")') }
move to rvec_((m4w+m4r)*2,0)
{ line from rvec_(-m4w-m4cr,m4h/2) \
to rvec_(0,m4h/2) \
then to rvec_(0,-m4h/2) \
then to rvec_(-m4w-m4cr,-m4h/2) }
line to rvec_(max(rp_len/2-m4r-m4w,0), 0) }
{ [box invis ht_ m4r*2 wid_ (m4r+m4w)*2] at last circle.c }
line to rvec_(rp_len,0) invis ')
`consource( linespec ,V|I|tv|v|ti|i|P, R,
attributes )
Controlled source
Arg3:
V= voltage
I= current
v= voltage type 2
tv= voltage type 3
i= current type 2
ti= current type 3
P= proximity sensor
arg 4 can be used to modify the body with e.g.
color, fill, or ;internal symbols
e.g. consource(,,,; "S" at C)'
define(`consource',`ifelse(`$3',R,
`reversed(`consource',`$1',`$2',,shift(shift(shift($@))))',
`eleminit_(`$1')
{line to rvec_(rp_len/2-csdim_,0)
{[ N: rvec_(csdim_,csdim_)
S: rvec_(csdim_,-csdim_)
E: rvec_(2*csdim_,0)
W: Here; C: rvec_(csdim_,0)
{line to N then to E then to S then to W `$4'}
ifelse(`$2',I,
`{arrow to E chop csdim_/4}',
`$2',ti,
`{line thick 2*linethick from N to S chop csdim_/4}',
`$2',i,
`{line from N to S}',
`$2',V,
`{"iflatex(`\scriptsize$-$',-)" \
at rvec_(csdim_*0.5,0) ifsvg(+(0,textht/10))}
{"iflatex(`\scriptsize$+$',+)" \
at rvec_(csdim_*1.5,0) ifsvg(+(0,textht/10))}',
`$2',tv,
`{line thick 2*linethick to E chop csdim_/4} ',
`$2',v,
`{line to E} ',
`$2',P,
`{ Proxim(2*csdim_) at rvec_(csdim_,0) }') ] with .W at Here}
line from last [].E to rvec_(rp_len/2+csdim_,0)}
line to rvec_(rp_len,0) invis ')')
`geiger( linespec, r, diameter, R, attributes, body name)
Arguments as for source except arg2 r = right orientation '
define(`geiger',`pushdef(`m4h',ifelse(`$3',,`sourcerad_',`($3)/2'))dnl
pushdef(`m4R',`ifelse(`$4',R,+180)')dnl
source(`$1',F,shift(shift($@)))
{dot(at rvec_(-rp_len/2,0)+vec_(Rect_(m4h*2/3,ifelse(`$2',r,,-)110 m4R)))}
{"iflatex($+$,+)" at rvec_(-rp_len/2,0) \
+vec_(Rect_(m4h*3/2,ifelse(`$2',r,,-)30 m4R))}
{em_arrows(ND,rp_ang*rtod_ ifelse(`$2',r,+,-)135 m4R,m4h) with .Head \
at rvec_(-rp_len/2,0)+vec_(Rect_(m4h*5/4,ifelse(`$2',r,-)45 m4R))} dnl
popdef(`m4h',`m4R') ')
`Proxim(size, U|D|L|R|degrees, attributes)
Proximity symbol
Arg2 default: current direction'
define(`Proxim',`[
define(`m4prwid',`ifelse(`$1',,(dimen_/2),`($1)')')dnl
setdir_(ifelse(`$2',,`ifdef(`m4a_',rp_ang*rtod_,0)',`$2'))
M4PRN: rvec_(0, m4prwid/2)
M4PRE: rvec_(m4prwid/2,0)
M4PRS: rvec_(0,-m4prwid/2)
M4PRW: rvec_(-m4prwid/2,0)
{ line from 1/2 between M4PRN and M4PRE to M4PRE then to M4PRS \
then to M4PRW then to M4PRN then to 1/2 between M4PRN and M4PRE `$3' }
{ line from 1/4 between M4PRW and M4PRN to 1/4 between M4PRE and M4PRN }
{ line from 1/4 between M4PRW and M4PRS to 1/4 between M4PRE and M4PRS }
`$4'; resetdir_ ]')
`Magn(len, ht, U|D|L|R|degrees)
Magnetic relay action symbol'
define(`Magn',`[
define(`m4mawi2',`ifelse(`$1',,(dimen_/4),`(($1)/2)')')dnl
define(`m4mah2',`ifelse(`$2',,(dimen_/8),`(($2)/2)')')dnl
setdir_(ifelse(`$3',,`ifdef(`m4a_',rp_ang*rtod_,0)',`$3'))
m4fshade(0, line from vec_( 0, m4mah2) \
to vec_( m4mawi2, m4mah2) \
then to vec_( m4mawi2,-m4mah2) \
then to vec_( m4mawi2/2,-m4mah2) \
then to vec_( m4mawi2/2,0) \
then to vec_(-m4mawi2/2,0) \
then to vec_(-m4mawi2/2,-m4mah2) \
then to vec_(-m4mawi2,-m4mah2) \
then to vec_(-m4mawi2, m4mah2) \
then to vec_( 0, m4mah2))
`$4'; resetdir_ ]')
`battery( linespec, n, R )
Arg 3: reversed polarity'
define(`battery',`ifelse(`$3',R,
`reversed(`battery',`$1',`$2',,shift(shift(shift($@))))',
`eleminit_(`$1')
define(`m4n',`ifelse(`$2',,1,(`$2'))')define(`m4cs',`dimen_/12')dnl
define(`m4wd',`m4cs*(m4n*2-1)')define(`m4ht',`dimen_/2')dnl
{ line to rvec_(rp_len/2-m4wd/2,0)
for m4i = 0 to 2*(m4n-1) by 2 do {
{ line from rvec_(m4i*m4cs,m4ht/4) \
to rvec_(m4i*m4cs,-m4ht/4) }
{ line from rvec_((m4i+1)*m4cs,m4ht/2) \
to rvec_((m4i+1)*m4cs,-m4ht/2) } }
line from rvec_(m4wd,0) \
to rvec_(rp_len/2+m4wd/2,0) }
{[box invis ht_ m4ht wid_ m4wd] at rvec_(rp_len/2,0)}
line to rvec_(rp_len,0) invis ')')
`ebox(linespec, length, ht, greyvalue,
box attributes)
Length and ht (of the element) are relative to
the direction of linespec'
Alternative:
`ebox(linespec, keys)
keys:
lgth=expr; wdth=expr;
text="centered text";
box=box attributes, e.g. shaded "green"'
define(`ebox',`eleminit_(`$1')
{ifinstr(`$2',=,
`pushkeys_(`$2',`lgth:dimen_/2; wdth:dimen_/5; text::N; box::N;')
line to rvec_(max(0,rp_len/2-m4lgth/2),0); M4ebC: rvec_(m4lgth/2,0)
lbox(m4lgth,m4wdth,m4box)
ifelse(m4text,,,`{m4text at M4ebC};')',
`pushdef(`m4lgth',`ifelse(`$2',,dimen_/2,`$2')')dnl
pushdef(`m4wdth',`ifelse(`$3',,dimen_/5,`$3')')dnl
line to rvec_(max(0,rp_len/2-m4lgth/2),0)
ifelse(`$4',,`lbox(m4lgth,m4wdth,`$5')',
`m4fshade(`$4',lbox(m4lgth,m4wdth,`$5'))')')
line to rvec_(max(0,rp_len/2-m4lgth/2),0)}
{[ box invis ht_ m4wdth wid_ m4lgth ] at rvec_(rp_len/2,0)}
popdef(`m4wdth',`m4lgth')ifinstr(`$2',=,`popdef(`m4text',`m4box')')dnl
line to rvec_(rp_len,0) invis ')
`fuse( linespec, chars, wid, ht, attributes )
chars dA|B|C|D|S|SB|HB|HC or dA (=D)'
define(`fuse',`eleminit_(`$1')
pushdef(`m4fusetype',`ifelse(`$2',,A,`$2',D,dA,`$2')')dnl
pushdef(`m4ht',ifelse(`$4',,`dimen_/5'ifinstr(`$2',H,*5/3),`($4)'))dnl
pushdef(`m4d',ifinstr(`$2',H,`m4ht/5',0))dnl
pushdef(`m4wd',ifelse(`$3',,`m4ht*2',`($3)'))dnl
{line to rvec_(max(0,rp_len/2-m4wd/2),0)
sc_draw(`m4fusetype',HB,
`{move to rvec_(m4d,0); lbox(m4wd-2*m4d,m4ht-2*m4d)}
{lbox(m4wd,m4ht,`$5')}
line to rvec_(m4wd+max(0,rp_len/2-m4wd/2),0)')
sc_draw(`m4fusetype',HC,
`{move to rvec_(m4d,0); {lbox(m4wd-2*m4d,m4ht-2*m4d,`$5')}
{line from rvec_((m4wd-2*m4d)/5,m4ht/2-m4d) \
to rvec_((m4wd-2*m4d)/5,-m4ht/2+m4d)}
line from rvec_((m4wd-2*m4d)*4/5,m4ht/2-m4d) \
to rvec_((m4wd-2*m4d)*4/5,-m4ht/2+m4d) }
{lbox(m4wd,m4ht)}
move to rvec_(m4wd,0); line to rvec_(max(0,rp_len/2-m4wd/2),0)')
sc_draw(`m4fusetype',A,
`arc cw to rvec_(m4ht,0) rad m4ht/2 with .c at rvec_(m4ht/2,0)dnl
ifelse(m4a,d,`; {dot(at last arc.start,,1)}')
arc ccw to rvec_(m4ht,0) rad m4ht/2 with .c at rvec_(m4ht/2,0)
line to rvec_(max(0,rp_len/2-m4wd/2),0)dnl
ifelse(m4a,d,`; dot(at last line.start,,1)')')
sc_draw(`m4fusetype',SB,
`{lbox(m4wd,m4ht,`$5')}
{line to rvec_(m4wd+max(0,rp_len/2-m4wd/2),0)}
{m4fshade(m4fill,lbox(m4wd/5,m4ht))}
move to rvec_(m4wd,0); line to rvec_(max(0,rp_len/2-m4wd/2),0)')
sc_draw(`m4fusetype',B,
`{lbox(m4wd,m4ht,`$5')}
line to rvec_(m4wd+max(0,rp_len/2-m4wd/2),0)')
sc_draw(`m4fusetype',C,
`{lbox(m4wd,m4ht,`$5')}
{line from rvec_(m4wd/5,-m4ht/2) \
to rvec_(m4wd/5,m4ht/2)}
{line from rvec_(m4wd*4/5,-m4ht/2) \
to rvec_(m4wd*4/5,m4ht/2)}
move to rvec_(m4wd,0); line to rvec_(max(0,rp_len/2-m4wd/2),0)')
sc_draw(`m4fusetype',S,
`{lbox(m4wd,m4ht,`$5')}
{m4fshade(m4fill,lbox(m4wd/5,m4ht))}
move to rvec_(m4wd,0); line to rvec_(max(0,rp_len/2-m4wd/2),0)')
}
{[box invis ht_ m4ht wid_ m4wd] at rvec_(rp_len/2,0)}
popdef(`m4wd',`m4d',`m4ht',`m4fusetype')dnl
line to rvec_(rp_len,0) invis ')
`arrester( linespec,
[chars][D[L|R]],
body len[:arrowhead ht],
body ht[:arrowhead wid],
attributes )
arg2 chars:
G= spark gap (default)
g= general (dots)
E= gas discharge
S= box enclosure
C= carbon block
A= electrolytic cell
H= horn gap
P= protective gap
s= sphere gap
F= film element
M= multigap
modifiers:
R= right orientation
L= left orientation
D= 3-terminal element for S, E only with
terminals A, B, G'
define(`arrester',
`define(`m4rdna',`patsubst(`$2',D\|L\|R)')dnl
ifelse(m4rdna,,`define(`m4rdna',G)')dnl
define(`m4rL',ifinstr(`$2',L,-))dnl
define(`m4rR',ifinstr(`$2',R,-))dnl
define(`m4aht',`(m4Rightstr(`$3',arrowht*2/3))')dnl
define(`m4awd',`(m4Rightstr(`$4',
ifelse(m4rdna,g,dotrad_*2,m4rdna,M,dotrad_*2,arrowwid*4/3)))')dnl
define(`m4wd',`(ifinstr( dnl body length
m4rdna,C,`m4Leftstr(`$3',dimen_/3)',
m4rdna,F,`m4Leftstr(`$3',dimen_/3)',
m4rdna,s,`m4Leftstr(`$3',dimen_/4)',
m4rdna,E,`m4Leftstr(`$3',dimen_*5/8)',
`m4Leftstr(`$3',dimen_/2)'))')dnl
define(`m4ht',`(ifinstr( dnl body height
Loopover_(`Z',`ifinstr(m4rdna,Z,T)',C,A,s),T,`m4Leftstr(`$4',dimen_/4)',
m4rdna,F,`m4Leftstr(`$4',dimen_/3)',
`m4Leftstr(`$4',dimen_/5)'))')dnl
ifinstr(`$2',D,
`[ define(`m4LL',m4rL)dnl
ifinstr(m4rdna,S,
`R: arrester(ifelse(`$1',,`to rvec_(m4wd*2,0)',`$1'),m4rdna,
shift(shift($@)))
Gb: line from R.c+vec_(0,m4LL m4ht/2) to R.c+vec_(0,m4LL (-m4ht*3/2))
A: R.start; B: R.end; C: R.c; G: Here ',
m4rdna,E,
`R: arrester(ifelse(`$1',,`to rvec_(m4wd*8/5,0)',`$1'),m4rdna,
shift(shift($@)))
Gb: line from R.c+vec_(0,m4LL m4wd/8) to R.c+vec_(0,m4LL (-m4wd*3/4))
A: R.start; B: R.end; C: R.c; G: Here ',
`M4ErrorMsg(`D argument of Arrester() applies to types S, E only!') ')
`$6' ]',
`eleminit_(`$1',elen_) dnl 2-terminal elements:
{line to rvec_(max(0,rp_len/2-m4wd/2),0)
{[ Orig: Here
ifinstr(m4rdna,G,`
{sarrow(to rvec_(m4aht,0),\
wdth=m4awd;lgth=m4aht;head=shaded "black" `$5';)}
move to rvec_(m4wd,0)
sarrow(to rvec_(-m4aht,0),\
wdth=m4awd;lgth=m4aht;head=shaded "black" `$5';)',
m4rdna,g,
`{dot(at rvec_(m4awd/2,0),rad=m4awd/2;circle=fill_(0) `$5')}
dot(at rvec_(m4wd-m4awd/2,0),rad=m4awd/2;circle=fill_(0) `$5')',
m4rdna,M,
`{dot(at rvec_(m4awd/2,0),rad=m4awd/2;circle=fill_(0) `$5')}
{dot(at rvec_(m4wd/2,0),rad=m4awd/2;circle=fill_(0) `$5')}
dot(at rvec_(m4wd-m4awd/2,0),rad=m4awd/2;circle=fill_(0) `$5')',
m4rdna,C,
`lbox(m4wd/3,m4ht,`$5'); move to rvec_(m4wd/3,0)
lbox(m4wd/3,m4ht,`$5')',
m4rdna,A,
`{line to rvec_(m4wd/4,0)}
for_(1,3,1,`line from rvec_(0,m4ht/2) to rvec_(m4wd/4,0) \
then to rvec_(0,-m4ht/2); move to rvec_(m4wd/4,m4ht/2)
ifelse(m4x,3,,move to rvec_(m4wd/8,0))') ',
m4rdna,H,
`line to rvec_(m4ht,0); round
{arc ifelse(m4rR,-,,c)cw from Here to rvec_(-m4ht,m4rR m4ht) \
with .c at rvec_(-m4ht,0)}
move to rvec_(m4wd-2*m4ht,0); round
{arc ifelse(m4rR,-,c)cw from Here to rvec_(m4ht,m4rR m4ht) \
with .c at rvec_(m4ht,0)}
line to rvec_(m4ht,0)',
m4rdna,P,`
{sarrow(to rvec_(m4aht,0),wdth=m4awd;lgth=m4aht; `$5';)}
move to rvec_(m4wd,0)
sarrow(to rvec_(-m4aht,0),wdth=m4awd;lgth=m4aht; `$5';)',
m4rdna,s,
`{line to rvec_(m4ht/2*(sqrt(2)-1),0)}
{arc from rvec_(0,-m4ht/2) to rvec_(0,m4ht/2) \
with .c at rvec_(-m4ht/2,0)}
move to rvec_(m4wd,0)
{arc from rvec_(0,m4ht/2) to rvec_(0,-m4ht/2) \
with .c at rvec_(m4ht/2,0)}
{line to rvec_(-m4ht/2*(sqrt(2)-1),0)}',
m4rdna,F,
`{line from rvec_(0,m4ht/2) to rvec_(0,-m4ht/2)}
{line from rvec_(m4wd/2,m4ht/2) to rvec_(m4wd/2,-m4ht/2)}
line from rvec_(m4wd,m4ht/2) to rvec_(m4wd,-m4ht/2)',
m4rdna,S,
`{lbox(m4wd,m4ht,`$5')}
sarrow(to rvec_(m4wd/2,0),\
wdth=m4awd;lgth=m4aht;head=shaded "black";) ',
m4rdna,E,
`{circle diam m4wd at rvec_(m4wd/2,0) `$5'}
{sarrow(to rvec_(m4wd*3/8,0),\
wdth=m4awd;lgth=m4aht;head=fill_(0);)}
{sarrow(from rvec_(m4wd,0) to rvec_(m4wd*5/8,0),\
wdth=m4awd;lgth=m4aht;head=fill_(0);)}
dot(at rvec_(m4wd*6/8,m4wd/4),dotrad_*2/3) ')
] with .Orig at Here }
line from rvec_(m4wd,0) to rvec_(max(0,rp_len/2+m4wd/2),0) }
line invis to rvec_(rp_len,0)') ')
`memristor( linespec, wid, ht, attributes )'
define(`memristor',`eleminit_(`$1')
define(`m4ht',ifelse(`$3',,`dimen_/5',`($3)'))define(`m4htx',`m4ht/4')dnl
define(`m4wd',ifelse(`$2',,`dimen_/2',`($2)'))define(`m4wdx',`m4wd*4/25')dnl
{ line to rvec_(max(0,rp_len/2-m4wd/2),0)
{[lbox(m4wd,m4ht,`$4')] at rvec_(m4wd/2,0)}
line to rvec_(m4wdx,0) \
then to rvec_(m4wdx,m4htx) \
then to rvec_(m4wdx*2,m4htx) \
then to rvec_(m4wdx*2,-m4htx) \
then to rvec_(m4wdx*3,-m4htx) \
then to rvec_(m4wdx*3,m4htx) \
then to rvec_(m4wdx*4,m4htx) \
then to rvec_(m4wdx*4,0) \
then to rvec_(m4wdx*5,0)
m4fshade(m4fill,lbox(m4wd/4,m4ht))
line to rvec_(max(0,rp_len/2-m4wd/2),0) }
line invis to rvec_(rp_len,0)')
`pvcell( linespec, wid, ht, attributes )'
define(`pvcell',`eleminit_(`$1')
define(`m4wd',ifelse(`$2',,`dimen_/2',`($2)'))dnl
define(`m4ht',ifelse(`$3',,`dimen_/5',`($3)'))dnl
{ line to rvec_(max(0,rp_len/2-m4wd/2),0)
{[lbox(m4wd,m4ht,`$4')] at rvec_(m4wd/2,0)}
{line from rvec_(0,-m4ht/2) to rvec_(m4wd/3,0) then to rvec_(0,m4ht/2)}
move to rvec_(m4wd,0); line to rvec_(max(0,rp_len/2-m4wd/2),0) }
line invis to rvec_(rp_len,0)')
`heater( linespec, nparts|keys, wid, ht,
boxspec|[E[R][T]] )
If arg5 contains E, draws an
heatere(linespec,keys,[R][T]) otherwise a
heatert(linespec,nparts,wid,ht,boxspec)'
define(`heater',`ifinstr(`$5',E,
`heatere(`$1',`$2',`$5')',
`heatert($@)')')
`heatere( linespec, keys, [R|T] )
R: right orientation
T: truncates leads to the width of the body
keys: (for body)
lgth=expr;
wdth=expr; (default lgth*2/5)
cycles=expr;
line=attributes'
define(`heatere',
`pushkeys_(`$2',`lgth:dimen_/2; wdth:m4`'lgth*2/5; cycles:3; line::N;')dnl
ifinstr(`$3',R,`pushdef(`m4ng',-)pushdef(`m4cw')pushdef(`m4ccw',cw)',
`pushdef(`m4ng') pushdef(`m4cw',cw)pushdef(`m4ccw')')dnl
eleminit_(ifinstr(`$3',T,m4wdth,`$1'))
{ line to rvec_(rp_len/2-m4wdth/2,0); round
{[S: Here; r = m4lgth/(4*m4cycles+1)
arc m4cw m4line to rvec_(r,m4ng`'r) with .c at rvec_(r,0)
for i=1 to m4cycles do { arc m4ccw m4line to rvec_(0,m4ng`'2*r) \
with .c at rvec_(0,m4ng`'r)
arc m4cw m4line to rvec_(0,m4ng`'2*r) with .c at rvec_(0,m4ng`'r) }
line m4line to rvec_(m4wdth-2*r,0)
for i=1 to m4cycles do {arc m4cw m4line to rvec_(0,m4ng`'(-2*r)) \
with .c at rvec_(0,m4ng`'(-r))
arc m4ccw m4line to rvec_(0,m4ng`'(-2*r)) with .c at rvec_(0,m4ng`'(-r)) }
arc m4cw m4line to rvec_(r,m4ng`'(-r)) with .c at rvec_(0,m4ng`'(-r)); round
] with .S at Here }
line from rvec_(m4wdth,0) to rvec_(rp_len/2+m4wdth/2,0) }
line invis to rvec_(rp_len,0)dnl
popdef(`m4lgth',`m4wdth',`m4cycles',`m4line',`m4ng',`m4cw',`m4ccw') ')
`heatert(linespec, nparts|keys, wid,ht,boxspec)
keys: parts=expr;
lgth=expr;
wdth=expr;
box=attributes;
args 3-5 unused if any key is given
arg5= body attributes'
define(`heatert',`eleminit_(`$1')
ifelse(regexp(`$2',`parts=\|lgth=\|wdth=\|box='),-1, dnl not very elegant
`pushdef(`m4parts',ifelse(`$2',,4,`$2'))dnl
pushdef(`m4lgth',ifelse(`$3',,`dimen_/2',`($3)'))dnl
pushdef(`m4wdth',ifelse(`$4',,`dimen_/5',`($4)'))dnl
pushdef(`m4box',`$5')',
`pushkeys_(`$2',`parts:4; lgth:dimen_/2; wdth:dimen_/5; box::N')')dnl
{ line to rvec_(max(0,rp_len/2-m4lgth/2),0)
{[lbox(m4lgth,m4wdth,m4box)] at rvec_(m4lgth/2,0)}
for m4ix=1 to m4parts-1 do {
{line from rvec_(m4ix*m4lgth/(m4parts),m4wdth/2) \
to rvec_(m4ix*m4lgth/(m4parts),-m4wdth/2) m4box}}
line from rvec_(m4lgth,0) \
to rvec_(max(0,rp_len/2+m4lgth/2),0) }
line invis to rvec_(rp_len,0) popdef(`m4parts',`m4lgth',`m4wdth',`m4box')')
`lamp(linespec,[R][T],attributes)'
define(`lamp',`pushdef(`m4ng',`ifinstr(`$2',R,-)')pushdef(`m4hw',`dimen_/10')dnl
pushdef(`m4dp',(m4ng`'m4hw/2))pushdef(`m4ht',(m4ng`'dimen_/8))dnl
eleminit_(ifinstr(`$2',T,m4hw*2,`$1'))
{ [ circle rad dimen_/5 `$3' ] at rvec_(rp_len/2,m4ng`'dimen_/3.2) }
{ line to rvec_(rp_len/2-m4hw,0) \
then to rvec_(rp_len/2-m4hw,m4ng`'dimen_/3.2)
spline ifdpic(ctension_) to rvec_(0,m4ht) \
then to rvec_(1.3*m4hw, m4ht) \
then to rvec_(1.3*m4hw,-m4dp) \
then to rvec_(0.7*m4hw,-m4dp) \
then to rvec_(0.7*m4hw, m4ht) \
then to rvec_(2*m4hw,m4ht) \
then to rvec_(2*m4hw,0)
line to rvec_(0,-(m4ng`'dimen_/3.2)) \
then to rvec_(rp_len/2-m4hw,-(m4ng`'dimen_/3.2)) }
line invis to rvec_(rp_len,0) popdef(`m4ng',`m4hw',`m4dp',`m4ht') ')
`thermocouple(linespec, wid, ht, L|R [T])
T=truncated leads;
R=right orientation'
define(`thermocouple',`pushdef(`m4wd',ifelse(`$2',,`dimen_/5',`($2)'))dnl
eleminit_(ifinstr(`$4',T,m4wd,`$1'))
pushdef(`m4ht',ifelse(`$3',,`dimen_/2',`($3)'))dnl
pushdef(`m4ths',`ifinstr(`$4',R,-)')dnl
{line to rvec_(max(0,rp_len/2-m4wd/2),0) \
then to rvec_(max(0,rp_len/2-m4wd/2),m4ths`'(m4ht-m4wd/2)) \
then to rvec_(rp_len/2,m4ths`'m4ht) \
then to rvec_(max(0,rp_len/2-m4wd/2)+m4wd,m4ths`'(m4ht-m4wd/2)) \
then to rvec_(max(0,rp_len/2-m4wd/2)+m4wd,0) \
then to rvec_(rp_len,0)}
{ dot(at rvec_(rp_len/2,m4ths`'m4ht)) }
{[box invis ht_ m4ht wid_ m4wd] at rvec_(rp_len/2,m4ths`'m4ht/2)}
line to rvec_(rp_len,0) invis popdef(`m4wd',`m4ht',`m4ths')')
`cbreaker( linespec, L|R, D|Th|TS, body name )
circuit breaker to left or right of linespec,
D=with dots; Th=thermal; TS=squared thermal
Default body bounding box name is Br'
define(`cbreaker',`ifinstr(`$3',T,
`tbreaker($@)',
`mbreaker($@)')')
define(`tbreaker',`eleminit_(`$1') define(`m4ho',0)
{ifinstr(`$3',TS,
`define(`m4h',`dimen_/5')define(`m4v',`m4h/2')define(`m4ho',`m4v/2')dnl
m4j = max(0,rp_len/2-m4h/2)
line to rvec_(m4j,0) \
then to rvec_(m4j,ifelse(`$2',R,-)m4h/2) \
then to rvec_(m4j+m4h,ifelse(`$2',R,-)m4h/2) \
then to rvec_(m4j+m4h,0) \
then to rvec_(m4j*2+m4h,0) ',
`define(`m4h',`dimen_*2/5')define(`m4v',`m4h/2')define(`m4ho',0)dnl
m4j = max(0,rp_len/2-m4h/2)
line to rvec_(m4j,0)
{round
arc cw to rvec_( m4h/4,0)+vec_(Rect_(m4h/4,-75)) with .c at rvec_( m4h/4,0)}
move to rvec_(m4h,0)
{round
arc cw to rvec_(-m4h/4,0)+vec_(Rect_(m4h/4,105)) with .c at rvec_(-m4h/4,0)}
line to rvec_(m4j,0)
') }
{ifelse(`$4',,Br,`$4'):[box invis ht_ m4v wid_ m4h ] at rvec_(rp_len/2,ifelse(`$2',R,-)m4ho) }
line to rvec_(rp_len,0) invis ')
define(`mbreaker',`eleminit_(`$1') define(`m4R',`ifelse(`$2',R,-)')
define(`m4h',`dimen_/3') define(`m4cr',`((m4h+2*dimen_/32)*5/8)')dnl
define(`m4ht',`(m4cr-sqrt(m4cr^2-(m4h/2+dimen_/32)^2)+dimen_/16)')dnl
{line to rvec_(max(0,rp_len/2-m4h/2),0)
{ifelse(`$3',D,`dot(,,1)
move to rvec_(0,m4R`'dotrad_);')dnl
arc ifelse(`$2',R,c)cw from rvec_(-dimen_/32,m4R`'dimen_/16) \
to rvec_(m4h+dimen_/32,m4R`'dimen_/16) rad m4cr \
with .c at rvec_(m4h/2,m4R`'(m4ht-m4cr))}
{line from rvec_(m4h,0) \
to rvec_(m4h+max(0,rp_len/2-m4h/2),0)
ifelse(`$3',D,`dot(at last line.start,,1)') }
ifelse(`$4',,Br,`$4'): [box invis ht_ m4ht ifelse(`$3',D,`+2*dotrad_') \
wid_ m4h+dimen_/16] at rvec_(m4h/2,m4R`'(m4ht/2)) }
line to rvec_(rp_len,0) invis ')
`jumper(linespec,chars|keys)
Two-terminal solder jumper with named body parts.
chars: character sequence normally beginning
with C and ending with D specifying the jumper
components and their attribs: C is first, D last,
E is empty (blank) gap, J is filled gap, B is
box component.
The components are named T1, T2, ...
e.g. CED is a simple open jumper (default);
CJD closed; CEBED three-contact open;
CJBED three-contact open and closed.
keys:
type=chars as above;
body=attributes; (e.g. fill_(0.5))
wdth=expr;
name=chars; body name'
define(`jumper',`eleminit_(`$1')
pushkeys_(`$2',`type:m4typ:N; body:fill_(0):N; wdth:dimen_/5; name::N;')dnl
ifelse(m4type,m4typ,
`poppushdef(`m4type',`ifelse(`$2',,CED,`ifinstr(`$2',=,CED,`$2')')')')dnl
pushdef(`m4r',m4wdth/2) pushdef(`m4lgth',`m4r*len(m4type)')dnl
{ line to rvec_(rp_len/2-m4lgth/2,0)
{ line from rvec_(m4lgth,0) to rvec_(rp_len/2+m4lgth/2,0) }
{ifelse(m4name,,,m4name:) [ S: Here
for_(1,len(m4type),1,`define(`m4ch',`substr(m4type,decr(m4x),1)')dnl
T`'m4x: ifelse(m4ch,C,
`[ arc to rvec_(0,-m4wdth) with .c at rvec_(0,-m4r) m4body
round(,,m4body); L: line to rvec_(0,m4wdth) m4body; round(,,m4body)
] with .L.c at rvec_(m4r,0); move to last [].L.c ',
m4ch,J,`rotbox(m4r,m4r,m4body)',
m4ch,B,`rotbox(m4r,m4wdth,m4body)',
m4ch,E,`move to rvec_(m4r,0)',
m4ch,D,`[ arc to rvec_(0,m4wdth) with .c at rvec_(0,m4r) m4body
round(,,m4body); L: line to rvec_(0,-m4wdth) m4body; round(,,m4body)
] with .L.c at Here; move to T`'m4x.L.c+vec_(m4r,0)')')
] with .S at Here } }
line invis to rvec_(rp_len,0) undefine(`m4ch') dnl
popdef(`m4type',`m4body',`m4wdth',`m4name',`m4r',`m4lgth') ')
`gap( linespec,fill,A )
Gap with filled dots e.g.
gap(down_ linewid/2,1); rlabel(+,v_1,-)
A: chopped arrow between dots'
define(`gap',`eleminit_(`$1')
dot(,,ifelse(`$2',,0,`$2')); dot(at last line.end,,ifelse(`$2',,0,`$2'))
ifelse(`$3',A,
`{arrow from last line.start to last line.end chop dotrad_*3}')
{[box invis ht_ 0 wid_ min(rp_len,(dimen_*4/9+rp_len)/3)] at last line.c}
')
`arrowline( linespec )
line with midpoint arrowhead
e.g. arrowline(up 1 dotted); llabel(,I_2)'
define(`arrowline',`line ifelse(`$1',,`to rvec_(elen_,0)',`$1')
{ eleminit_(from last line.start to last line.end) }
{ arrow from last line.start to last line.end \
chop lin_leng(last line)/2-arrowht/2
[box invis ht_ arrowwid wid_ arrowht] at last line.c }')
`ground( at position, T|stem length, N|F|S|L|P[A]|E,
D|U|L|R|degrees)
T=truncated stem; N=normal ground,
F=frame, S=signal, L=low-noise, P=protective,
E=European; PA=protective alternate
Down (default), Up, Left, Right, angle (deg)'
define(`ground',`box invis ht 0 wid 0 with .c ifelse(`$1',,`at Here',`$1')
define(`m4v',`dimen_/6')define(`m4h',`dimen_/16')dnl
{setdir_(ifelse(`$4',,-90,`$4'))
ifelse(`$2',,`line from last box.c to rvec_(dimen_/4,0)',
`$2',T,,`line from last box.c to rvec_(`$2',0)')
ifelse(`$3',F,
`{line from rvec_(dimen_/8,m4v-dimen_/12) \
to rvec_(0,m4v) \
then to rvec_(0,-m4v) \
then to rvec_(dimen_/8,-m4v-dimen_/12)}
line to rvec_(dimen_/8,-dimen_/12)',
`$3',S,
`{line to rvec_(0,m4v) \
then to rvec_(m4v*1.5,0) \
then to rvec_(0,-m4v) \
then to Here }',
`$3',Q,
`{shade(0,line to rvec_(0,m4v) \
then to rvec_(m4v*1.5,0) \
then to rvec_(0,-m4v) \
then to Here) }',
`$3',L,
`{move to rvec_(m4h,0)
arc cw rad m4v*3/2 from rvec_(Rect_(m4v*3/2,-60)) \
to rvec_(Rect_(m4v*3/2,60)) with .c at Here}
ground(,T,,`$4')',
`$3',PA,
`{Grnd_T: line to rvec_(0,m4v*1.6) \
then to rvec_(5.5*m4h,0) \
then to rvec_(0,-m4v*1.6) \
then to Here}
ground(at rvec_(m4h,0),T,,`$4')',
`$3',P,
`{Grnd_C: circle rad m4v*3/2 at rvec_(m4h,0)}
ground(,T,,`$4')',
`$3',E,
`{line from rvec_(0,m4v*2/3) \
to rvec_(0,-m4v*2/3) thick linethick*2}',
`{line from rvec_(0,m4v) \
to rvec_(0,-m4v)}
{line from rvec_(m4h,dimen_/9) \
to rvec_(m4h,-dimen_/9)}
line from rvec_(2*m4h,dimen_/14) \
to rvec_(2*m4h,-dimen_/14)')
resetdir_} ')
`antenna(at position, T|stem length, A|L|T|S|D|P|F,
U|D|L|R|degrees)
arg2=T: truncate stem
arg3= A aerial; L loop, T triangle, S diamond,
D dipole, P phased, F fork;
up (default), down, left, right, angle (deg)'
define(`antenna',`[ T: Here
define(`m4v',`dimen_/2')define(`m4h',`dimen_/12')dnl
define(`m4atype',ifelse(`$3',,A,`$3'))dnl
setdir_(ifelse(`$4',,90,`$4'))
ifelse(
m4atype,L,
`T1: rvec_(0,m4h); T2: rvec_(0,-m4h)
ifelse(`$2',,`move to rvec_(m4h*2,0)', `$2',T,,`move to rvec_(`$2',0)')
line from T1 to rvec_(0,m4h) \
then to rvec_(0,m4v/2) \
then to rvec_(m4v-m4h,m4v/2) \
then to rvec_(m4v-m4h,-m4v/2+m4h) \
then to rvec_(m4h,-m4v/2+m4h) \
then to rvec_(m4h,m4v/2-m4h) \
then to rvec_(m4v,m4v/2-m4h) \
then to rvec_(m4v,-m4v/2) \
then to rvec_(0,-m4v/2) \
then to rvec_(0,-m4h) \
then to T2',
m4atype,T,
`ifelse(`$2',,`move to rvec_(m4h*2,0)', `$2',T,,`move to rvec_(`$2',0)')
line to rvec_(m4v*3/4,m4v*sqrt(3)/4) \
then to rvec_(m4v*3/4,-m4v*sqrt(3)/4) \
then to Here
line from rvec_(m4v*3/4,0) \
to T',
m4atype,S,
`T1: rvec_(0,m4h); T2: rvec_(0,-m4h)
ifelse(`$2',,`move to rvec_(m4h*2,0)', `$2',T,,`move to rvec_(`$2',0)')
line from T1 to rvec_(0,m4h) \
then to rvec_(m4v*3/4-m4h,m4v*3/4) \
then to rvec_(2*m4v*3/4-m4h,0) \
then to rvec_(m4v*3/4-m4h,-m4v*3/4) \
then to rvec_(0,-m4h) \
then to T2',
m4atype,D,
`T1: rvec_(0,m4h); T2: rvec_(0,-m4h)
ifelse(`$2',,`move to rvec_(m4v,0)', `$2',T,,`move to rvec_(`$2',0)')
{ line from T1 to rvec_(0,m4h) \
then to rvec_(0,m4h*3) }
{ line from T2 to rvec_(0,-m4h) \
then to rvec_(0,-m4h*3) }',
m4atype,P,
`ifelse(`$2',,`move to rvec_(m4h*2/3,0)', `$2',T,,`move to rvec_(`$2',0)')
line from T to Here
{ line from rvec_(0,-m4v/3) \
to rvec_(0,m4v/3) }
{ line from rvec_(m4h,-m4v*2/3) \
to rvec_(m4h,m4v*2/3) }',
m4atype,F,
`ifelse(`$2',,`move to rvec_(m4h*2,0)', `$2',T,,`move to rvec_(`$2',0)')
{ line from rvec_(m4v*3/4,m4v*sqrt(3)/4) \
to rvec_(0,m4v*sqrt(3)/4) \
then to rvec_(0,-m4v*sqrt(3)/4) \
then to rvec_(m4v*3/4,-m4v*sqrt(3)/4)}
line from rvec_(m4v*3/4,0) \
to T',
m4atype,A,
`ifelse(`$2',,`move to rvec_(m4h*2,0)', `$2',T,,`move to rvec_(`$2',0)')
{ line from rvec_(m4v*3/4, m4v*sqrt(3)/4) to Here \
then to rvec_(m4v*3/4,-m4v*sqrt(3)/4) }
line from rvec_(m4v*3/4,0) \
to T')
`$5'; resetdir_ ] with .T ifelse(`$1',,`at Here',`$1')
move to last [].T')
`heatsink(at position, keys, U|D|L|R|degrees)
keys: lgth=expr; hght=expr; fin=attributes;
base=attributes; fincount=expr;
Arg3: drawing direction (default: R)'
define(`heatsink',`[ setdir_(`$3',R)
pushkeys_(`$2',`lgth:dimen_*3/4; hght:m4`'lgth/3; fin::N;
base::N; fincount:6;')dnl
SW: (0,0); NW: vec_(0,m4hght); SE: vec_(m4lgth,0); NE: vec_(m4lgth,m4hght)
B: line from SW to SE m4base
T: line from SE+(NE-SE)/4 to SW+(NW-SW)/4 m4base
for i=0 to m4fincount-1 do {
move to (0.5+i)/m4fincount between T.end and T.start
line to Here+(NW-SW)*3/4 m4base m4fin }
`$4'; resetdir_ popdef(`m4lgth',`m4hght',`m4fin',`m4base',`m4fincount')
] ifelse(`$1',,`at Here',`$1')')
`adjust(at position,keys)
Adjustment screw in a [] block
keys:
size=expr;
angle=degrees; slot angle
slotwid=expr; slot width
circle=attributes; shade, outline etc'
define(`adjust',`[ pushkeys_(`$2',
`size:dimen_/4; angle:60; circle::N; slotwid:m4`'size/3')
C: circle diam m4size at (0,0) m4circle
ap = asin(m4slotwid/m4size)*rtod_
line from (Rect_(m4size/2,m4angle-ap)) to (Rect_(m4size/2,m4angle-180+ap))
line from (Rect_(m4size/2,m4angle+180-ap)) to (Rect_(m4size/2,m4angle+ap))
popdef(`m4size',`m4angle',`m4circle',`m4slotwid')
] ifelse(`$1',,`at Here',`$1') ')
`switch( linespec,L|R,[O|C][D],L|B|D,attribs )
Wrapper for bswitch, lswitch, dswitch
R=right orientation (default L=left)
if arg4=blank or L:
arg3 = [O|C][D][K][A]
D = circle at contact and hinge (dD = hinge
only, uD = contact only)
K=closed switch;
A=arrowhead on switch blade;
O=opening arrow; C=closing arrow
if arg4=B (button switch): arg3 = O|C
O=normally open; C=normally closed;
if arg4=D: arg3 = same as for dswitch and
arg5 is arg4 of dswitch GC or GX'
define(`switch',`ifelse(
`$4',, `lswitch(`$1',`$2',`$3')',
`$4',L,`lswitch(`$1',`$2',`$3')',
`$4',B,`bswitch(`$1',`$2',`$3')',
`$4',D,`define(`m4qna_',`$3')dnl
define(`m4rna_',W`'ifinstr(`$2',C,dBK,B)`'m4qna_)dnl
dswitch(`$1',`$2',m4rna_,`$5')')')
`bswitch( linespec,L|R,chars ) pushbutton switch
R=right orientation (default L=left)
chars: O= normally open, C=normally closed'
define(`bswitch',`eleminit_(`$1') dnl
define(`m4h',`dimen_/3') define(`m4cs',`0.069186*dimen_')dnl (2.5pt)
define(`m4v',`ifelse(`$2',R,-m4cs,m4cs)')define(`dna_',`$3') dnl
{line to rvec_(rp_len/2-m4h/2,0) chop 0 chop m4cs}
{ Bsw_T1: circle rad m4cs at rvec_(rp_len/2-m4h/2,0); move to last circle
{ Bsw_T2: circle rad m4cs at rvec_(m4h,0) }; ifelse(`$4',,,`{`$4'}')
sc_draw(`dna_',C,dnl
`{ line from rvec_(-m4cs,-(m4v)) \
to rvec_(m4h+m4cs,-(m4v)) }
{ line from rvec_(m4h/2,-(m4v)) \
to rvec_(m4h/2,m4v*3) }
{[box invis ht_ 4*m4cs wid_ m4h+2*m4cs] at rvec_(m4h/2,m4v)}',
`{ line from rvec_(-m4cs,m4v*2.5) \
to rvec_(m4h+m4cs,m4v*2.5) }
{ line from rvec_(m4h/2,m4v*2.5) \
to rvec_(m4h/2,m4v*4.5) }
{[box invis ht_ 5.5*m4cs wid_ m4h+2*m4cs] at rvec_(m4h/2,m4v*1.75)}')
line from rvec_(m4h,0) \
to rvec_(m4h/2+rp_len/2,0) chop m4cs chop 0 }
line to rvec_(rp_len,0) invis ')
`lswitch( linespec,L|R,chars ) knife switch
R=right orientation (default L=left)
chars=[O|C][[ud]D][K][A]
D = circle at contact and hinge (dD = hinge
only, uD = contact only)
K=closed switch;
A=arrowhead on switch blade;
O=opening arrow; C=closing arrow'
define(`lswitch',`eleminit_(`$1') dnl
define(`m4v',`dimen_/4')define(`m4cs',`dimen_/4*Sin(10)')dnl
define(`dna_',`$3')define(`m4d',-1)define(`m4k',15)dnl
m4t1 = arrowht; m4t2 = arrowwid;
arrowht = dimen_/0.75*0.08; arrowwid = dimen_/0.75*0.053
{line to rvec_(rp_len/2-dimen_/6,0)
sc_draw(`dna_',K,`define(`m4k',25)dnl
{{ifinstr(`$3',A,arrow m4c_l,line) \
to LCtangent(Here,rvec_(dimen_/3,0),dotrad_,`$2') chop 0 chop -dotrad_}
line from rvec_(dimen_/3,0) to rvec_(dimen_/3,ifelse(`$2',R,-)dotrad_)}',
`{ifinstr(`$3',A,arrow m4c_l,line) \
to rvec_(dimen_/4,ifelse(`$2',R,-)dimen_/4)}')
sc_draw(`dna_',C,`{ arc <- m4c_l ifelse(`$2',R,,`c')cw \
from rvec_(Rect_(dimen_/4,ifelse(`$2',R,,-)m4k))\
to rvec_(Rect_(dimen_/4,ifelse(`$2',R,-)60)) \
with .c at rvec_(Rect_(-dimen_/4,ifelse(`$2',R,-)(60-m4k)/2)) }')
sc_draw(`dna_',O, `{ arc -> m4c_l ifelse(`$2',R,,`c')cw \
from rvec_(Rect_(dimen_/4,ifelse(`$2',R,,-)10))\
to rvec_(Rect_(dimen_/4,ifelse(`$2',R,-)75)) \
with .c at rvec_(Rect_(-dimen_/4,ifelse(`$2',R,-)(75-10)/2)) }') }
{{line from rvec_(rp_len/2+dimen_/6,0) \
to rvec_(rp_len,0) }
sc_draw(`dna_',D,
`ifelse(m4a,u,,`dot(at rvec_(rp_len/2-dimen_/6,0),,1)')
ifelse(m4a,d,,`dot(at last line.start,,1)')') }
{ [box invis ht_ dimen_/4+m4cs wid_ dimen_/3] \
with .c at rvec_(rp_len/2,ifelse(`$2',R,-)(m4v-(m4cs))/2)}
arrowht = m4t1 ; arrowwid = m4t2; ifelse(`$4',,,`{`$4'}')
line to rvec_(rp_len,0) invis ')
`dswitch(linespec, R, W[ud]B chars, attributes)
Comprehensive IEEE-IEC single-pole switch:
arg2=R: orient to the right of drawing dir
arg4 is a key-value sequence for the body of
GC and GX options;
GC keys: diam, circle
GX keys: lgth, wdth, box, text
arg 3:
blank means WB by default
B=contact blade open
Bc=contact blade closed
Bm= mirror blade
Bo=contact blade more widely open
dB=contact blade to the right of direction
Cb = circuit breaker function (IEC S00219)
Co = contactor function (IEC S00218)
C = external operating mechanism
D = circle at contact and hinge (dD = hinge
only, uD = contact only)
DI = Disconnector; isolator (IEC S00288)
E = emergency button
EL = early close (or late open)
LE = late close (or early open)
F = fused
GC = disk control mechanism, attribs:
diam=expr; circle=circle attribs;
GX = box control mechanism, attribs:
lgth=expr;wdth=expr;box=box attr; text=char;
H = time delay closing
uH = time delay opening
HH = time delay opening and closing
K=vertical closing contact line
use WdBK for a normally-closed switch
L = limit
M = maintained (latched)
MM = momentary contact on make
MR = momentary contact on release
MMR = momentary contact on make and release
O = hand operation button
P = pushbutton
Pr[T|M] = proximity [touch-sensitive or
magnetically controlled]
R = time-delay operating arm
Sd = Switch-disconnector
Th = thermal control linkage
Tr = tripping
W = baseline with gap
Y = pull switch
Z = turn switch'
define(`dswitch',`eleminit_(`$1')
define(`dna_',ifelse(`$3',,WB,`$3')`')dnl
define(`m4R',`ifelse(`$2',R,-)')define(`m4sc',`dimen_/24')dnl
M4CC: last line.c
sc_draw(`dna_',W,
`{ line from M4CC+vec_( 4*m4sc,0) to last line.end }
{ line to M4CC+vec_(-4*m4sc,0) }')
{[ tr_xy_init(,m4sc,m4R)
T: M4_xyO; B: T
sc_draw(`dna_',Bm,
`define(`m4c',ifelse(m4a,d,-))dnl
B: line from tr_xy(-4,0) \
to tr_xy(5.0,m4c`'4.5)
line invis from B.start to B.end chop 0 chop -m4_xyU*5/4
m4fshade(0,circle rad m4_xyU*5/4 at last line .end)')
sc_draw(`dna_',Bo,
`define(`m4c',ifelse(m4a,d,-))dnl
B: line from tr_xy(-4,0) \
to tr_xy(4,m4c`'13/sqrt(3))')
sc_draw(`dna_',Bc,
`B: line from tr_xy(-4,0) \
to tr_xy( 4,0)')
sc_draw(`dna_',B,
`define(`m4c',ifelse(m4a,d,-))dnl
B: line from tr_xy(-4,0) \
to tr_xy(5.0,m4c`'4.5)')
sc_draw(`dna_',Cb,
`line from tr_xy(2,-2) to tr_xy(6, 2)
line from tr_xy(2, 2) to tr_xy(6,-2)')
sc_draw(`dna_',Co,`ifelse(m4R,-,
`arc ifelse(m4c,-,,c)cw from tr_xy(4,0) \
to tr_xy(8,0) with .c at tr_xy(6,0)',
`arc ifelse(m4c,-,c)cw from tr_xy(4,0) \
to tr_xy(8,0) with .c at tr_xy(6,0)') ')
sc_draw(`dna_',GC,
`pushkeys_(`$4',`diam:12*m4sc;circle::N;text::N')dnl
line from B.c to B.c+ta_xy(0,4)
GC: circle diam m4diam m4circle dnl
ifelse(m4text,,,`m4lstring(m4text,"m4text")') \
at Here+ta_xy(0,m4diam/2/(m4sc)) popdef(`m4diam',`m4circle',`m4text')')
sc_draw(`dna_',GX,
`pushkeys_(`$4',`lgth:10*m4sc;wdth:10*m4sc;box::N;text::N')dnl
line from B.c to B.c+ta_xy(0,4)
GX: rotbox(m4lgth,m4wdth,m4box) at Here+ta_xy(0,m4lgth/2/(m4sc))
ifelse(m4text,,,`m4lstring(m4text,"m4text") at GX.C') dnl
popdef(`m4lgth',`m4wdth',`m4box',`m4text')')
sc_draw(`dna_',C,
`T: B.c+ta_xy(0,ifelse(m4a,d,-)12)
C: line dashed from B.c to T ')
sc_draw(`dna_',DI,
`DI: line from tr_xy(4,2) to tr_xy(4,-2)')
sc_draw(`dna_',D,
`ifelse(m4a,u,,`dot(at tr_xy(-4,0),,1)')
ifelse(m4a,d,,`dot(at tr_xy(4,0),,1)')')
sc_draw(`dna_',EL,
`EL: line from 0.99 along_(B) to B.end \
then to B.end + ta_xy(vperp(B,m4c`'2.5,R))')
sc_draw(`dna_',LE,
`LE: line from 0.99 along_(B) \
to B.end \
then to B.end + ta_xy(vperp(B,m4c`'2.5))')
sc_draw(`dna_',K,
`K: line from tr_xy(4,0) \
to tr_xy(4,m4c`'5)')
sc_draw(`dna_',F,
`DT: 1/8 along_(B); DQ: 5/8 along_(B)
F: line from DT to DT + ta_xy(neg_(m4c)1/2,1) \
then to DQ + ta_xy(neg_(m4c)1/2,1) \
then to DQ + ta_xy(m4c`'1/2,-1) \
then to DT + ta_xy(m4c`'1/2,-1) \
then to DT ')
sc_draw(`dna_',L,
`DT: 11/16 along_(B) define(`m4e',ifelse(m4a,d,-))
line from 5/16 along_(B) \
to DT + ta_xy(neg_(m4e)1,ifelse(m4c,m4e,,-)2) \
then to DT')
sc_draw(`dna_',Sd,
`dot(at tr_xy(4,0),m4_xyU*3/2,1)
line from tr_xy(4,2)+vec_(m4_xyU*3/2,0) \
to tr_xy(4,-2)+vec_(m4_xyU*3/2,0)')
sc_draw(`dna_',Th,
`define(`m4t',ifelse(m4a,d,-))dnl
T: B.c+ta_xy(0,m4t`'12)
line from B.c to B.c+ta_xy(0,m4t`'4.5) \
then to B.c+ta_xy(3,m4t`'4.5) \
then to B.c+ta_xy(3,m4t`'7.5) \
then to B.c+ta_xy(0,m4t`'7.5) \
then to T ')
sc_draw(`dna_',Tr,
`m4angtmp = rp_ang; point_(lin_ang(B))
DT1: 0.4 along_(B); DT2: 0.65 along_(B)
m4dTr = distance(DT1,DT2)
move to DT1+vec_(0,m4c`'m4dTr/2)
m4fshade(0,lbox(m4dTr,m4dTr))
point_(m4angtmp) ')
sc_draw(`dna_',PrM,
`T: Proxim(dimen_/3) at B.c+ta_xy(0,ifelse(m4a,d,-)8)
line dashed dimen_/16 from B.c to T chop 0 chop dimen_/6
Magn(dimen_/3,dimen_/6) at T+vec_(0,ifelse(m4a,d,-)dimen_/4)')
sc_draw(`dna_',MMR,
`line from tr_xy(6,1.16) \
to tr_xy(4,0) \
then to tr_xy(6,-1.16)')
sc_draw(`dna_',MM,
`MM: line from tr_xy(5,0) \
to tr_xy(4,0) \
then to tr_xy(6,1.16)')
sc_draw(`dna_',MR,
`MR: line from tr_xy(5,0) \
to tr_xy(4,0) \
then to tr_xy(6,-1.16)')
sc_draw(`dna_',M,
`define(`m4t',ifelse(m4a,d,-))dnl
T: B.c+ta_xy(0,m4t`'12)
line dashed 1.5*m4sc from B.c to B.c+ta_xy(0,m4t`'4.5)
line to B.c+ta_xy(-3,m4t`'6) \
then to B.c+ta_xy(0,m4t`'7.5)
line dashed 1.5*m4sc to T ')
sc_draw(`dna_',O,
`line from T + ta_xy(-2.5,0) \
to T + ta_xy(2.5,0) ')
sc_draw(`dna_',PrT,
`T: Proxim(dimen_/3) at B.c+ta_xy(0,ifelse(m4a,d,-)8)
line dashed dimen_/16 from B.c to T chop 0 chop dimen_/6
line to rvec_(dimen_/4,0) with .c at T+vec_(0,ifelse(m4a,d,-)dimen_/6)')
sc_draw(`dna_',Pr,
`T: Proxim(dimen_/3) at B.c+ta_xy(0,ifelse(m4a,d,-)8)
line dashed dimen_/16 from B.c to T chop 0 chop dimen_/6 ')
sc_draw(`dna_',P,
`line from T + ta_xy(-2.5,-2.5) \
to T + ta_xy(-2.5,0) \
then to T + ta_xy(2.5,0) \
then to T + ta_xy(2.5,-2.5) ')
sc_draw(`dna_',Y,
`line from T + ta_xy(-2.5,2.5) \
to T + ta_xy(-2.5,0) \
then to T + ta_xy(2.5,0) \
then to T + ta_xy(2.5,2.5) ')
sc_draw(`dna_',Z,
`line from T + ta_xy(-2.5,-2.5) \
to T + ta_xy(-2.5,0) \
then to T + ta_xy(2.5,0) \
then to T + ta_xy(2.5,2.5) ')
sc_draw(`dna_',R,
`define(`m4t',ifelse(m4a,d,-))dnl
DT: 5/12 along_(B); DQ: 7/12 along_(B)
line from DT to DT + ta_xy(0,m4t`'12)
line from DQ to DQ + ta_xy(0,m4t`'(neg_(m4c)sqrt(3)/2+12))
T: 1/2 between Here and 2nd last line.end ')
sc_draw(`dna_',HH,
`arc ifelse(m4R,-,c)cw \
from T+ta_xy(3,3/2) \
to T+ta_xy(-3,3/2) with .c at T+ta_xy(0,4.0)
arc ifelse(m4R,,c)cw \
from T+ta_xy(3,-3/2) \
to T+ta_xy(-3,-3/2) \
with .c at T+ta_xy(0,-4.0) ')
sc_draw(`dna_',H,
`define(`m4t',ifelse(m4a,d,-))dnl
arc ifelse(m4t,m4R,,c)cw \
from T+ta_xy(3,m4t`'3/2) \
to T+ta_xy(-3,m4t`'3/2) \
with .c at T + ta_xy(0,m4t`'4.0) ')
sc_draw(`dna_',E,
`line from T + ta_xy(-2.5,0) \
to T + ta_xy(2.5,0)
arc ifelse(m4R,-,,c)cw to last line.start with .c at T + ta_xy(0,-1.5) ')
] with .M4_xyO at M4CC }
line to rvec_(rp_len,0) invis ')
`amp( linespec,size, attributes )
Amplifier'
define(`amp',`eleminit_(`$1') define(`m4wd',`ifelse(`$2',,`dimen_',`($2)')')dnl
{line to rvec_(max(0,rp_len/2-m4wd/2),0)
{[ End: vec_(m4wd,0); line from End \
to vec_(0,m4wd/2) \
then to vec_(0,-m4wd/2) \
then to End `$3'] with .End at rvec_(m4wd,0) }
line from rvec_(m4wd,0) to rvec_(max(m4wd,rp_len/2+m4wd/2),0) }
line to rvec_(max(rp_len,m4wd),0) invis ')
`integrator( linespec,size,attributes )'
define(`integrator',`eleminit_(`$1')
define(`m4wd',`ifelse(`$2',,`dimen_',`($2)')')dnl
{[ In: Here
{line from rvec_(m4wd/4,m4wd/2) \
to rvec_(0,m4wd/2) \
then to rvec_(0,-m4wd/2) \
then to rvec_(m4wd/4,-m4wd/2) `$3' }
line from rvec_(m4wd*5/4,0) \
to rvec_(m4wd/4,m4wd/2) \
then to rvec_(m4wd/4,-m4wd/2) \
then to rvec_(m4wd*5/4,0) `$3' ; Out: Here ] with .In at Here}
{line from rvec_(m4wd*5/4,0) to rvec_(max(rp_len,m4wd*5/4),0) }
line to rvec_(max(rp_len,m4wd*5/4),0) invis ')
`opamp(linespec,
- label, + label, size|keys, chars)
keys= lgth=expr;
wdth=expr;
body=attributes;
drawn as a []:
defined positions:
W, N, E, S, Out, E1, E2, In1, In2
size: expr (default lgth equals wdth)
chars:
P: power connections V1,V2
R: labels at In1,In2 swapped
T: truncated point '
define(`opamp',
`[ pushdef(`m4dlgth',`ifinstr(`$4',=,dimen_,ifelse(`$4',,dimen_,`($4)'))')dnl
pushkeys_(`$4',`body::N; lgth:m4dlgth; wdth:m4`'lgth;')dnl
pushdef(`dna_',`$5')dnl
ifelse(`$1',,`lgt=elen_',`eleminit_(`$1'); lgt=max(rp_len,m4lgth)')
W: Here
N: vec_(0,m4wdth/2)
S: vec_(0,-m4wdth/2)
E: vec_(m4lgth,0)
C: vec_(m4lgth/2,0)
{ sc_draw(`dna_',T,
`line to N then to 0.75 between N and E \
then to 0.75 between S and E then to S then to W m4body
line from 0.75 between W and E to E',
`line to N then to E then to S then to W m4body; move to E')
if lgt > m4lgth then { line to rvec_(lgt-m4lgth,0) }
Out: Here }
NE: vec_(m4lgth/2,m4wdth/4); E1: NE
SE: vec_(m4lgth/2,-m4wdth/4); E2: SE
In1: vec_(0,m4wdth/4)
In2: vec_(0,-m4wdth/4)
{ move to In`'ifinstr(dna_,R,2,1)
ifelse(`$2',,"iflatex(`{\scriptsize$-$}',-)" \
at rvec_(4pt__,0) ifsvg(+(0,textht/10)),m4lstring(`$2',"`$2'"))}
{ move to In`'ifinstr(dna_,R,1,2)
ifelse(`$3',,"iflatex(`{\scriptsize$+$}',+)" \
at rvec_(4pt__,0) ifsvg(+(0,textht/10)),m4lstring(`$3',"`$3'"))}
sc_draw(`dna_',P,
`{line from E1 to (vec_(m4lgth/2,m4wdth/4+m4wdth/8)); V1: Here}
{line from E2 to (vec_(m4lgth/2,-(m4wdth/4+m4wdth/8))); V2: Here}')
`$6' popdef(`m4dlgth',`dna_',`m4lgth',`m4wdth',`m4body')] ')
`dac(width,height,nIn,nN,nOut,nS)'
define(`dac',`[
define(`dac_ht',`ifelse(`$2',,(dimen_),`$2')')dnl
define(`dac_wd',`ifelse(`$1',,(dimen_+dac_ht/2),`$1')')dnl
In: Here
C: rvec_((dac_wd-dac_ht/2)/2,0)
NE: rvec_(dac_wd-dac_ht/2, dac_ht/2)
Out:rvec_(dac_wd,0)
SE: rvec_(dac_wd-dac_ht/2,-dac_ht/2)
NW: rvec_(0,dac_ht/2)
SW: rvec_(0,-dac_ht/2)
define(`m4dn',ifelse(`$3',,1,`eval($3)'))dnl
for_(1,m4dn,1,`In`'m4x: NW-vec_(0,dac_ht*(2*m4x-1)/(2*m4dn))')dnl
define(`m4dn',ifelse(`$4',,1,`eval($4)'))dnl
for_(1,m4dn,1,`N`'m4x: NW+vec_((dac_wd-dac_ht/2)*m4x/(m4dn+1),0)')dnl
define(`m4dn',ifelse(`$5',,1,`eval($5)'))dnl
for_(1,m4dn,1,`r = eval(2*m4x-1)/eval(m4dn*2)
Out`'m4x: Out-vec_(ifelse(eval((2*m4x-1)<m4dn),1,,-)dac_ht*(0.5-r),
dac_ht*(0.5-r))')dnl
define(`m4dn',ifelse(`$6',,1,`eval($6)'))dnl
for_(1,m4dn,1,`S`'m4x: SW+vec_((dac_wd-dac_ht/2)*m4x/(m4dn+1),0)')dnl
line to NW then to NE then to Out then to SE then to SW then to Here
`$7']')
`adc(width,height,nIn,nN,nOut,nS)'
define(`adc',`[
define(`adc_ht',`ifelse(`$2',,(dimen_),`$2')')dnl
define(`adc_wd',`ifelse(`$1',,(dimen_+adc_ht/2),`$1')')dnl
In: Here
C: rvec_(adc_ht/4+adc_wd/2,0)
NE: rvec_(adc_wd, adc_ht/2)
Out:rvec_(adc_wd,0)
SE: rvec_(adc_wd,-adc_ht/2)
NW: rvec_(adc_ht/2, adc_ht/2)
SW: rvec_(adc_ht/2,-adc_ht/2)
define(`m4dn',ifelse(`$3',,1,`eval($3)'))dnl
for_(1,m4dn,1,`r = eval(2*m4x-1)/eval(m4dn*2)
In`'m4x: In+vec_(ifelse(eval((2*m4x-1)<m4dn),1,,-)adc_ht*(0.5-r),
adc_ht*(0.5-r))')dnl
define(`m4dn',ifelse(`$4',,1,`eval($4)'))dnl
for_(1,m4dn,1,`N`'m4x: NW+vec_((adc_wd-adc_ht/2)*m4x/(m4dn+1),0)')dnl
define(`m4dn',ifelse(`$5',,1,`eval($5)'))dnl
for_(1,m4dn,1,`Out`'m4x: NE-vec_(0,adc_ht*(2*m4x-1)/(2*m4dn))')dnl
define(`m4dn',ifelse(`$6',,1,`eval($6)'))dnl
for_(1,m4dn,1,`S`'m4x: SW+vec_((adc_wd-adc_ht/2)*m4x/(m4dn+1),0)')dnl
line from Out to SE then to SW then to In then to NW then to NE then to Out
`$7']')
`diode(linespec,
B|b|CR|D|F|G|L|LE[R]|P[R]|S|Sh|T|U|V|v|w|Z|z|
chars,[R][E])
Adding K to arg2 draws open arrowheads
Adding M draws a mid-arrowhead crossbar
Arg 3: R=reversed polarity, E=enclosure'
define(`diode',
`ifinstr(`$3',R,
`reversed(`diode',`$1',`$2',patsubst(`$3',R),shift(shift(shift($@))))',
`define(`dma_',`$2')dnl
define(`m4ahd',ifinstr(dma_,K,,f))dnl
ifinstr(dma_,M,`define(`m4ahd',m4ahd`'M)')dnl
define(`dma_',patsubst(dma_,`K\|M'))dnl
define(`m4cts',`ifelse(
dma_,,LACR,
dma_,B,uLAZQuR,
dma_,b,uLAzoQuR,
dma_,CR,LACRrb,
dma_,D,LuAHdQR,
dma_,F,LFR,
dma_,G,uLAQuR,
dma_,LER,LdEACR,
dma_,LE,LuEACR,
dma_,L,LAcCR,
dma_,P,LuPACR,
dma_,PR,LdPACR,
dma_,Sh,LFcCR,
dma_,S,LASR,
dma_,T,LATR,
dma_,U,LA`'ifinstr(`$3',R,d,u)`'CR,
dma_,V,LACXdR,
dma_,v,LACvdR,
dma_,w,LAdvXdR,
dma_,Z,LAZR,
dma_,z,LAzR,
dma_)')
ifelse(dma_,B,`define(`m4dh',2*m4dh)',
dma_,D,`define(`m4dv',2*m4dv)',
dma_,G,`define(`m4dh',2*m4dh)',
dma_,Sh,`define(`m4ahd')',
dma_,L,`define(`m4ahd',xtract(m4ahd,M))')
eleminit_(`$1')
m4gen_d(m4cts,m4ahd)
ifinstr(`$3',E,`define(`m4dh',`dimen_*0.7')define(`m4dv',`m4dh')dnl
{ Diode_Env: circle diam m4dh at rvec_(rp_len/2,0) }')
define(`m4dm',
`ifelse(dma_,S,`m4dv/4',
dma_,Z,`(m4dv/4-linethick pt__/2)',
dma_,z,`(m4dv/4-linethick pt__/2)',
dma_,v,`m4dv/4',
dma_,w,`m4dv/4',
0)')dnl
{ [ box invis ht_ m4dv+linethick pt__*sqrt(3) wid_ m4dh+linethick pt__ + m4dm
] at rvec_(rp_len/2+m4dm/2,0) }
line invis to rvec_(rp_len,0)
')')
`m4gen_d(chars,[f][R][M][E]):
*This is an internal macro, subject to change*
*General: [u|d] for shift, R for orientation*
[u|d]A[c] arrowhead shifted up, down, or 0
[u|d]F[c] arrowhead open-sided (Shockley)
[u|d]B bar (gate) at arrowhead centre
[u|d]BB long bar (gate) at arrowhead centre
[u|d]C vertical bar at right of arrowhead
u: with limiter bar on left; d on right
[u|d]E em_arrows out
[u|d]F half arrowhead shifted
G gate for scr(,B), label G
rb current regulator bars
H double-length vertical bars
[u]L left stem, uL = shortened
M mid-arrow crossbar
N thyristor gate at anode, label Ga
[u|d]P em_arrows
[u|d]Q[c] shifted left arrowhead [centerline]
[u]R right stem, uR = shortened
S S-shape vertical bar
T T-diode vertical bar
W Thyristor gate from cathode, label G
X varicap diode-capacitor
[u|d]v varicap diode-capacitor curved plate
Y bilateral core
Z zener bar
z zener bar angled
zo zener bar outlined
arg 2: f= fill the arrowhead
M=arrowhead crossbar
R=right orientation
E=envelope flag '
define(`m4gen_d',`{dnl
define(`m4dv',`dimen_/6')define(`m4dh',sqrt(3)*m4dv/2)dnl
define(`ddna_',`ifelse(`$1',,`LACR',`$1')')dnl
define(`ddf_',`ifelse(`$1',,f,`$2')')dnl
define(`m4tR',`ifinstr(`$2',R,(-1),1)')dnl
define(`m4dy',`(linethick pt__)*(sqrt(3)-1)/2')dnl
M4_s: last line.start; M4_e: last line.end
sc_draw(`ddna_',L,dnl left stem, uL = shortened
`line from M4_s to 0.5 between M4_s and M4_e \
chop 0 chop m4dh`'ifelse(m4a,,/2)')
dnl Elements drawn from left of body
sc_draw(`ddna_',E,dnl EM radiation arrows pointing out
`ifelse(m4a,d,
`{em_arrows(,rp_ang*rtod_-135) with .Tail at rvec_(-m4dh*0.3,-m4dv*0.8)}',
`{em_arrows(,rp_ang*rtod_+135) with .Tail at rvec_(-m4dh*0.3,m4dv*0.8)}')')
sc_draw(`ddna_',P,dnl EM radiation arrows
`ifelse(m4a,d,
`{em_arrows(,rp_ang*rtod_+45) with .Head at rvec_(-m4dh*0.3,-m4dv*0.8)}',
`{em_arrows(,rp_ang*rtod_-45) with .Head at rvec_(-m4dh*0.3, m4dv*0.8)}')')
sc_draw(`ddna_',G,dnl SCR gate
`{Gm: line to ifinstr(`$2',E,2,3/2) between Here and \
rvec_(m4dh,ifelse(m4a,d,-)m4dv/2) ifinstr(`$2',E,`then to \
rvec_(m4dh*2,ifelse(m4a,d,-)sqrt((4*dimen_/10)^2-(m4dh*2)^2))')
G: Here}')
sc_draw(`ddna_',F,dnl half arrowhead shifted up, down, or 0
`sc_draw(`ddna_',Fc,`define(`m4Fc')')sc_draw(`ddna_',F,`undefine(`m4Fc')')dnl
define(`m4dn',`ifelse(m4a,u,m4dv/2,m4a,d,-m4dv/2,0)')
define(`m4dFline',`Gm: line from rvec_(0,m4tR*m4dn) \
to rvec_(0,m4tR*(m4dn+m4dv/2)) \
then to rvec_(m4dh-linethick pt__/2,m4tR*m4dn) \
then to rvec_(0,m4tR*m4dn)')
{ ifinstr(ddf_,f,`m4fshade(m4fill,m4dFline)',`m4dFline')
line to ifinstr(`$2',E,
`rvec_(0,-(m4tR*sqrt((dimen_*0.7/2)^2-(m4dh/2)^2)))',
`rvec_(0,-(m4tR*m4dv/2))')
G: Here }
ifdef(`m4Fc',`{line from rvec_(0,m4tR*m4dn) to rvec_(m4dh,m4tR*m4dn)}')
move to rvec_(m4dh,0) ')
ifinstr(ddna_,A,dnl Arrowhead shifted up, down, or 0
`sc_draw(`ddna_',Ac,`define(`m4Ac')')sc_draw(`ddna_',A,`undefine(`m4Ac')')dnl
define(`m4dn',`ifelse(m4a,u,m4dv/2,m4a,d,-m4dv/2,0)')dnl
define(`m4dFline',`line from rvec_(0,m4dn) \
to rvec_(0,m4dn+m4dv/2) \
then to rvec_(m4dh-linethick pt__/2,m4dn) \
then to rvec_(0,m4dn-m4dv/2) \
then to rvec_(0,m4dn)')
{ ifinstr(ddf_,f,`m4fshade(m4fill,m4dFline)',`m4dFline')}
ifdef(`m4Ac',`{line from rvec_(0,m4dn) to rvec_(m4dh,m4dn)}')
ifinstr(`$2',M,`{line from rvec_(m4dh/2,m4dn+m4dv/2) \
to rvec_(m4dh/2,m4dn-m4dv/2)}')
move to rvec_(m4dh,0) ')
sc_draw(`ddna_',B,dnl Perp bar at arrowhead centre
`{ifelse(m4a,u,dnl from arrow edge or across the centre line
`Gm: line from rvec_(-m4dh/2, m4dv/4) \
to ifinstr(`$2',E,`rvec_(-m4dh/2, dimen_*0.35)',
`rvec_(-m4dh/2, m4dv*5/4+m4dy)')',
m4a,d,
`Gm: line from rvec_(-m4dh/2,-m4dv/4) \
to ifinstr(`$2',E,`rvec_(-m4dh/2,-dimen_*0.35)',
`rvec_(-m4dh/2,-m4dv*5/4-m4dy)')',
`Gm: line from rvec_(-m4dh/2,-m4dv/2-m4dy) \
to rvec_(-m4dh/2, m4dv/2+m4dy)
G: Gm.c')
ifelse(m4a,,,G: last line.end) }')
sc_draw(`ddna_',C,dnl Vertical bar
`{ line from ifelse(m4a,d,`rvec_(m4dh/2,-m4dv/2-m4dy-m4dh/2) to')dnl
rvec_(0,-m4dv/2-m4dy) \
to rvec_(0, m4dv/2+m4dy) ifelse(m4a,u,
`to rvec_(m4dh/2, m4dv/2+m4dy+m4dh/2)') }')
m4gen_d2($@)dnl
m4gen_d3($@)dnl
}') dnl macro split to keep within m4 buffer size
define(`m4gen_d2',`dnl
dnl Elements drawn at right of body
sc_draw(`ddna_',rb,dnl Current regulator bars
`{line from rvec_(-m4dv/4,-m4dv/2-m4dy) \
to rvec_( m4dv/4,-m4dv/2-m4dy)}
{line from rvec_(-m4dv/4,m4dv/2+m4dy) \
to rvec_( m4dv/4,m4dv/2+m4dy)}')
sc_draw(`ddna_',H,dnl Double length double vertical bars
`{line from rvec_(0,-m4dv-m4dy) \
to rvec_(0, m4dv+m4dy)}
{line from rvec_(-m4dh,-m4dv-m4dy) \
to rvec_(-m4dh, m4dv+m4dy)}
move to rvec_(-m4dh,0)')
sc_draw(`ddna_',N,dnl thyristor gate at anode, label Ga
`{Gam: line from rvec_(-m4dh,-m4tR*m4dv/4) \
to rvec_(-m4dh*2,-m4tR*m4dv*3/4) ifinstr(`$2',E,`then to \
rvec_(-m4dh*2,-m4tR*sqrt((dimen_*0.7/2)^2-(m4dh*3/2)^2))')
Ga: Here}')
sc_draw(`ddna_',S,dnl S-shape vertical bar
`{line from rvec_(-m4dv/4,-m4dv/3) \
to rvec_(-m4dv/4,-m4dv/2-m4dy) \
then to rvec_(0,-m4dv/2-m4dy) \
then to rvec_(0, m4dv/2+m4dy) \
then to rvec_(m4dv/4,m4dv/2+m4dy) \
then to rvec_(m4dv/4,m4dv/3)}')
sc_draw(`ddna_',T,dnl T-diode vertical bar
`{line from rvec_(-m4dv/4,-m4dv/2-m4dy) \
to rvec_(0,-m4dv/2-m4dy) \
then to rvec_(0, m4dv/2+m4dy) \
then to rvec_(-m4dv/4,m4dv/2+m4dy)}')
sc_draw(`ddna_',v,dnl Variable capacitor curved plate
`ifelse(m4a,d,`define(`m4drad',`sqrt((m4dv/2+m4dy)^2+(m4dv)^2*3/4)')dnl
{arc cw from rvec_(-(m4drad-m4dv*sqrt(3)/2), m4dv/2+m4dy) \
to rvec_(-(m4drad-m4dv*sqrt(3)/2),-m4dv/2-m4dy) \
with .c at rvec_(-m4drad,0)}',
`{arc cw from rvec_(m4dv/3,-m4dv/2-m4dy) \
to rvec_(m4dv/3, m4dv/2+m4dy) \
with .c at rvec_(m4dv/3+m4dv*sqrt(3)/2,0)}
{line from rvec_(m4dv/3+m4dv*sqrt(3)/2-last arc.rad,0) \
to rvec_(m4dv/4,0)}')')
sc_draw(`ddna_',W,dnl cathode gate
`{Gm: line from rvec_(0,m4tR*m4dv/4) \
to rvec_(m4dh,m4tR*m4dv*3/4) ifinstr(`$2',E,
`then to rvec_(m4dh,\
m4tR*sqrt((dimen_*0.7/2)^2-(m4dh*3/2)^2))')
G: Here}')
sc_draw(`ddna_',X,dnl Variable capacitor plate
`{line from rvec_(m4dv/4,-m4dv/2-m4dy) \
to rvec_(m4dv/4, m4dv/2+m4dy)}')
sc_draw(`ddna_',Z,dnl Zener bar
`{line from rvec_(-m4dv/4,-m4dv/2-m4dy) \
to rvec_(0,-m4dv/2-m4dy) \
then to rvec_(0, m4dv/2+m4dy) \
then to rvec_(m4dv/4,m4dv/2+m4dy)}')
sc_draw(`ddna_',zo,dnl Outlined zener bar
`{line from rvec_(-m4dv/4,-m4dv/2-m4dy-lthick*2) \
to rvec_( lthick*0.7,-m4dv/2-m4dy) \
then to rvec_( lthick*0.7, m4dv/2+m4dy+lthick) }
{line from rvec_( m4dv/4, m4dv/2+m4dy+lthick*2) \
to rvec_(-lthick*0.7, m4dv/2+m4dy) \
then to rvec_(-lthick*0.7,-m4dv/2-m4dy-lthick) }')
sc_draw(`ddna_',z,dnl Zener bar
`{line from rvec_(-m4dv/4,-m4dv/2-m4dy) \
to rvec_(0, -m4dv/3-m4dy) \
then to rvec_(0, m4dv/3+m4dy) \
then to rvec_( m4dv/4, m4dv/2+m4dy)}')
ifinstr(ddna_,Q,dnl left arrowhead
`sc_draw(`ddna_',Qc,`define(`m4Qc')')sc_draw(`ddna_',Q,`undefine(`m4Qc')')dnl
define(`m4dn',`ifelse(m4a,u,m4dv/2,m4a,d,-m4dv/2,0)')dnl
{move to rvec_(m4dh,0)
define(`m4dFline',`line from rvec_(0,m4dn) \
to rvec_(0,m4dn+m4dv/2) \
then to rvec_(-(m4dh-linethick pt__/2),m4dn) \
then to rvec_(0,m4dn-m4dv/2) \
then to rvec_(0,m4dn) ')
ifinstr(ddf_,f,`m4fshade(m4fill,m4dFline)',`m4dFline')}
ifdef(`m4Qc',`{line from rvec_(0,m4dn) \
to rvec_(-(m4dh-linethick pt__/2),m4dn)}')
move to rvec_(m4dh,0)')dnl
') dnl macro split to keep within m4 buffer size
define(`m4gen_d3',`dnl
sc_draw(`ddna_',Y,dnl Bilateral switch
`define(`m4vt',`(m4tR*m4dv/2)')dnl
line from rvec_(0,-m4vt) to Here
define(`m4dFline',`line to rvec_(0,m4vt) \
then to rvec_(2*m4dh,0) \
then to rvec_(2*m4dh,-m4vt) then to Here ')
ifinstr(ddf_,f,`m4fshade(m4fill,m4dFline)',`m4dFline')
line from rvec_(2*m4dh,m4vt) to rvec_(2*m4dh,0)
{ Gm: line from rvec_(-m4dh,m4vt) \
to ifinstr(`$2',E,`rvec_(-m4dh,-m4tR*dimen_*0.35)',
`rvec_(-m4dh,-m4tR*m4dv*5/4)')
G: Here }')
sc_draw(`ddna_',R,dnl right stem, uR = shortened
`line from 0.5 between M4_s and M4_e to M4_e \
chop m4dh ifelse(m4a,,/2,m4a,d,/2+m4dv/4) chop 0')
')dnl
`em_arrows( type|keys,angle,length )
type=N|I|E [D|T]
N=nonionizing, I=ionizing, E=simple;
D=dot on arrow stem; T=anchor tail
keys: type=chars as above;
lgth=expr;
sep=expr; arrow separation
angle=degrees; absolute direction'
define(`em_arrows',`[
pushkeys_(`$1',`type:m4typ:N; angle:ifelse(`$2',,135,`($2)')*dtor_')dnl
ifelse(m4type,m4typ,`poppushdef(`m4type',`ifelse(`$1',,N,`$1')')')dnl
arrowhead = em_arrowhead
sc_draw(`m4type',N,
`pushkeys_(`$1',lgth:ifelse(`$3',,dimen_*0.46,`$3'); sep:em_arrowwid*9/8)dnl
{ A1: arrow m4c_l to rrot_(m4lgth,0,m4angle) wid em_arrowwid ht em_arrowht}
move to rrot_(0,-m4sep,m4angle)
{ A2: arrow m4c_l to rrot_(m4lgth,0,m4angle) wid em_arrowwid ht em_arrowht}')
sc_draw(`m4type',I,
`pushkeys_(`$1',lgth:ifelse(`$3',,dimen_*0.46,`$3'); sep:em_arrowwid*9/8)dnl
m4em_serp(A1)
move to rrot_(0,-m4sep,m4angle); m4em_serp(A2)')
sc_draw(`m4type',E,
`pushkeys_(`$1',lgth:ifelse(`$3',,dimen_*0.25,`$3'); sep:dimen_/8)dnl
{ A1: line to rrot_(m4lgth,0,m4angle) \
then to rrot_(m4lgth-dimen_/18,dimen_/18,m4angle) }
move to rrot_(0,-m4sep,m4angle)
{ A2: line to rrot_(m4lgth,0,m4angle) \
then to rrot_(m4lgth-dimen_/18,dimen_/18,m4angle) }')
sc_draw(`m4type',D,`dot(at A1.start); dot(at A2.start)')
sc_draw(`m4type',T,`m4em_anchor(A1.start); m4em_anchor(A2.start)')
Tail: 0.5 between A1.start and A2.start
Head: 0.5 between A1.end and A2.end
`$4' popdef(`m4typ',`m4type',`m4angle',`m4lgth',`m4sep') ]')
define(`m4em_serp',`{{`$1': line invis to rrot_(m4lgth,0,m4angle)}
for i=1 to (m4lgth-em_arrowht*3/4)/(em_arrowwid) do {
if i%2 then {define m4cw {cw}} else {define m4cw {ccw}}
arc m4cw to rrot_(em_arrowwid,0,m4angle) \
with .c at rrot_((em_arrowwid)/2,0,m4angle) }; round
arrow m4c_l to `$1'.end wid em_arrowwid ht em_arrowht*3/4 }')
define(`m4em_anchor',`{ move to `$1'
{arc cw to rrot_(0,em_arrowwid/2,m4angle) \
with .c at rrot_(0,em_arrowwid/4,m4angle)}
{arc to rrot_(0,-arrowwid/2,m4angle) \
with .c at rrot_(0,-arrowwid/4,m4angle)}}')
`thyristor(linespec,
[SCR|SCS|SUS|SBS|IEC][chars])
Composite element in [ ] block
(To place as two-terminal, see thyristor_t()).
SCR: silicon controlled rectifier (default)
SCS: silicon controlled switch
SUS: silicon unilateral switch
SBS: silicon bilateral switch
IEC: type IEC
chars:
A: arrowhead
F: half arrowhead
B: bidirectional diode
E: adds envelope
H: perpendicular gate, endpoint G
N: anode gate, endpoint Ga
R=right orientation
U: centre line in diodes
V: perpendicular gate at arrowhead centre
K: use open arrowheads'
define(`thyristor',
`define(`m4tharg',ifelse(`$2',,SCR,`$2')) dnl default
define(`m4thtype',xtract(m4tharg,SCR,SCS,SUS,SBS,IEC))dnl
ifelse(m4thtype,,`define(`m4thtype',xtract(m4tharg,B))')dnl
define(`m4thx',`patsubst(m4tharg,m4thtype)')dnl delete the type code
sc_draw(`m4thx',R,`define(`m4thf',R)',`define(`m4thf')')dnl orientation
sc_draw(`m4thx',E,`define(`m4thf',m4thf`'E)')dnl envelope
define(`m4thAc',xtract(m4thx,F,A))define(`m4thAc',patsubst(m4thAc,F,Fc))dnl
define(`m4thAc',ifelse(m4thAc,,A,m4thAc)`'ifinstr(m4thx,U,c))dnl centerline
define(`m4thf',m4thf`'ifinstr(m4thx,A,,m4thx,F,,m4thx,K,,f))dnl fill
ifelse(m4thtype,,
`[define(`m4thyd',`dimen_*0.7') eleminit_(`$1',m4thyd); dnl no type code
A: last line.start; K: last line.end; T1:A; T2:K
define(`m4tha',`patsubst(patsubst(patsubst(patsubst(m4thx,UA,Ac),V,B),
H,ifinstr(m4thf,R,d,u)B),U,c)')dnl
ifelse(xtract(m4tha,A,F,Q),,`define(`m4tha',m4tha`'A)dnl
define(`m4thf',m4thf`'ifinstr(m4thx,K,,f))')dnl
ifelse(xtract(m4tha,B,G,H,N,W),,`define(`m4tha',m4tha`'W)')dnl
m4gen_d(LRC`'m4tha,m4thf)
ifinstr(m4thf,E,`Env: circle diam m4thyd with .c at rvec_(rp_len/2,0)')
`$3']',
m4thtype,IEC,`bi_trans(`$1',
ifinstr(m4thf,R,,R),uEdCBUT,xtract(m4thf,E),A:E;K:C;G:T;`$3')',
`[define(`m4thyd',`dimen_*0.7') eleminit_(`$1',m4thyd)
A: last line.start; K: last line.end; T1:A; T2:K
ifelse(m4thtype,SCR,
`m4gen_d(LCRW`'m4thAc,m4thf)',
m4thtype,SCS,
`m4gen_d(LCRWN`'m4thAc,m4thf)',
m4thtype,SUS,
`m4gen_d(LFR,m4thf)',
m4thtype,SBS,
`m4gen_d(uLYuR,m4thf)',
m4thtype,B,`ifinstr(m4thf,R,
`m4gen_d(LdG'xtract(m4thx,G)`dA`'m4thAc`'HuQ`'m4thAc`'R,m4thf)',
`m4gen_d( LG'xtract(m4thx,G)`uA`'m4thAc`'HdQ`'m4thAc`'R,m4thf)')')
ifinstr(m4thf,E,`Env: circle diam m4thyd with .c at rvec_(rp_len/2,0)')
`$3']')')')
`thyristor_t(linespec, thyristor chars], label)
A wrapper to place thyristor(linespec,...)
as a two-terminal element with arg3
as label of the [] block (see also scr())'
define(`thyristor_t',`eleminit_(`$1')
M4_thyS: last line.start; M4_thyE: last line.end
ifelse(`$3',,,`$3:') thyristor(from M4_thyS to M4_thyE,`$2',`$4') \
with .A at M4_thyS; line invis from M4_thyS to M4_thyE')
`scr(linespec, [R][E], label) and similar
Place thyristor as a two-term element with
arg 3 as label of the [] block'
define(`scr',`eleminit_(`$1'); M4_scrS: last line.start; M4_scrE: last line.end
ifelse(`$3',,,`$3:') thyristor(from M4_scrS to M4_scrE,SCR`'`$2',`$4') \
with .A at M4_scrS; line invis from M4_scrS to M4_scrE')
define(`scs',`eleminit_(`$1'); M4_scsS: last line.start; M4_scsE: last line.end
ifelse(`$3',,,`$3:') thyristor(from M4_scsS to M4_scsE,SCS`'`$2',`$4') \
with .A at M4_scsS; line invis from M4_scsS to M4_scsE')
define(`sus',`eleminit_(`$1'); M4_susS: last line.start; M4_susE: last line.end
ifelse(`$3',,,`$3:') thyristor(from M4_susS to M4_susE,SUS`'`$2',`$4') \
with .A at M4_susS; line invis from M4_susS to M4_susE')
define(`sbs',`eleminit_(`$1'); M4_sbsS: last line.start; M4_sbsE: last line.end
ifelse(`$3',,,`$3:') thyristor(from M4_sbsS to M4_sbsE,SBS`'`$2',`$4') \
with .A at M4_sbsS; line invis from M4_sbsS to M4_sbsE')
`tgate( linespec, [B][R|L] ) Transmission gate
B= box form
L= left orientation'
define(`tgate',`[ eleminit_(`$1') pushdef(`m4tgm',ifinstr(`$2',L,-))
A: last line.start
B: last line.end
C: last line.center
ifinstr(`$2',B,
`ebox(from A to B,,dimen_/5)
Gb: C+vec_(0,m4tgm`'dimen_/5/2)
L1: line from 2 between Gb and C to 4 between Gb and C',
`m4gen_d(uLAQuR) pushdef(`m4dv',`dimen_/6')pushdef(`m4dh',sqrt(3)*m4dv/2)
Circle: circle thick max(4pt__,linethick/2) rad m4dh/4 \
at C+vec_(0,m4tgm`'m4dh/4*4/3)
L2: line from last circle+vec_(0,m4tgm`'m4dh/4) \
to C+vec_(0,m4tgm`'m4dh*3/2)
Gb: Here
L3: line from C to C-vec_(0,m4tgm`'m4dh) popdef(`m4dv',`m4dh')')
G: Here
`$3' popdef(`m4tgm')]')
`ptrans( linespec, [R|L] ) Pass transistor
L= left orientation'
define(`ptrans',`[ eleminit_(`$1') define(`m4ptm',ifinstr(`$2',L,-))
define(`m4pv',`dimen_/6')define(`m4pwd',m4pv*2)dnl
A: last line.start; Start: A
B: last line.end; End: B
C: last line.center
La1: line to rvec_(rp_len/2-m4pwd/2,0)
{ La2: line to rvec_(m4pwd,m4pv) \
then to rvec_(m4pwd,neg_(m4pv)) \
then to Here }
{ La3: line from rvec_(m4pwd,0) \
to rvec_(0,m4pv) \
then to rvec_(0,neg_(m4pv)) \
then to rvec_(m4pwd,0)
Circle: circle thick max(4pt__,linethick/2) rad m4pv/4 \
at C+vec_(0,m4ptm`'m4pv*5/6)
La4: line from last circle+vec_(0,m4ptm`'m4pv/4) \
to C+vec_(0,m4ptm`'m4pv*2)
Gb:Here
La5: line from C-vec_(0,m4ptm`'m4pv/2) \
to C-vec_(0,m4ptm`'m4pv*3/2)
G: Here }
La6: line from rvec_(m4pwd,0) \
to B
`$3']')
`tline( linespec, wid, len ) Transmission line'
define(`tline',`eleminit_(`$1')
define(`m4v',`ifelse(`$2',,`dimen_/6',`($2)')')dnl
define(`m4h',`ifelse(`$3',,`dimen_*2/3',min(rp_len-m4v/2,`$3'))')dnl
{line from last line.c+vec_(m4h/2+m4v/4,0) \
to last line.end}
{line to 2nd last line.c+vec_(-m4h/2,0); round
[ifdpic(
`line from rvec_(0,-m4v/2) \
to rvec_(m4h,-m4v/2)
spline 0.5523 to rvec_(m4v/4,0) \
then to rvec_(m4v/4,m4v) \
to rvec_(0,m4v)
line to rvec_(-m4h,0)
spline 0.5523 to rvec_(-m4v/4,0) \
then to rvec_(-m4v/4,-m4v) \
then to rvec_(m4v/4,-m4v) \
then to rvec_(m4v/4,0) \
then to Here',
`line from rvec_(m4v/4,-m4v/2) \
to rvec_(m4h-m4v/4,-m4v/2)
spline to rvec_(m4v/2,0) \
then to rvec_(m4v/2,m4v) \
then to rvec_(0,m4v)
line to rvec_(-m4h+m4v/2,0)
spline to rvec_(-m4v/2,0) \
then to rvec_(-m4v/2,-m4v) \
then to rvec_(0,-m4v)\
then to Here \
then to rvec_(-m4v/2,0) \
then to rvec_(-m4v/2,-m4v)\
then to rvec_(0,-m4v)')] with .c at rvec_(m4h/2,0) }
line to 3rd last line.end invis ')
`Darlington(L|R, chars)
arg2:
E= envelope
P= p-type,
B1= internal base lead,
R1= Q1 bias resistor; E1= ebox,
R2= Q2 bias resistor; E2= ebox,
D= damper diode
Z= zener bias diode
This macro would be somewhat simpler if the
joints had not been mitred (using Along_ and
mitre_)'
define(`Darlington', `[ rpoint_(dimen_/10) define(`m4DR',`ifinstr(`$1',R,-)')
define(`m4Da',`$2') pushdef(`dimen_',((dimen_)*0.8))dnl Smaller internals
hp_ang = rp_ang
Q1: bi_trans(,`$1',ifinstr(m4Da,P,u,d)ECBU)
E: Q1.E
Q1B: line from Q1.Bulk.c to Q1.Bulk.c + vec_(0,m4DR`'m4_U)
Q2: bi_trans(,`$1',ifinstr(m4Da,P,u,d)EBCBU) with .E at Here
Mitre_(Q1B,Q2.Em0)
B: Q2.B
T: Q2.C+(Q2.Bulk.c.x-Q2.B.x,Q2.Bulk.c.y-Q2.B.y)
QC: intersect_(Q2.C,T,Q1.E,Q1.C)
C: QC
L1: line from Along_(Q2.Cm0,hlth) to Q2.C then to QC then to Q1.C \
then to Along_(Q1.Cm0,hlth)
define(`m4DE1')sc_draw(`m4Da',E1,`define(`m4DE1',E)define(`m4Da',R1`'m4Da)')
define(`m4DE2')sc_draw(`m4Da',E2,`define(`m4DE2',E)define(`m4Da',R2`'m4Da)')
ifinstr(m4Da,E,
`Env: circle rad 7.75*m4_U at Q1.Bulk.c+vec_(1.5*m4_U,m4DR`'(-0.1*m4_U))
line from Q1.E to Q1.E+vec_(-2.2*m4_U,0); E: Here
Mitre_(last line,Q1.Em0)
line from QC to QC+vec_(2.2*m4_U,0); C: Here
pushdef(`dotrad_',(dotrad_/2))dnl
ifelse(ifinstr(m4Da,B1,T,m4Da,R1,T,m4Da,R2,T),T,`dot(at Q2.E)')
ifelse(ifinstr(m4Da,R2,T,m4Da,Z,T),T,
`M4D1: dot(at Q2.Bulk.c+vec_(0,m4DR`'m4_U))')
ifelse(ifinstr(m4Da,B1,T,m4Da,R1,T),T,`ifinstr(m4Da,R2,
`M4D2: dot(at Q2.E+vec_(-m4_U,0))')')
ifinstr(m4Da,B1,
`ifinstr(m4Da,R1,`dot(at Q2.E-vec_(3*m4_U,0))')
B1: Q2.E+vec_(-3*m4_U,m4DR`'5.2*m4_U)
line from B1 to Q2.E+vec_(-3*m4_U,0); corner')
ifinstr(m4Da,Z,`dot(at QC+vec_(m4_U*3/2,0))')
dot(at QC)
ifinstr(m4Da,D,`dot(at Q1.E)')
ifinstr(m4Da,R1,`dot(at Q1.E-vec_(m4_U,0))')
popdef(`dotrad_')',
`ifinstr(m4Da,B1,`move to Q2.E-vec_(3*m4_U,0); line to rvec_(-m4_U,0)
B1: Here')')
ifelse(ifinstr(m4Da,B1,T,m4Da,R1,T,m4Da,R2,T),T,
`line from Q2.E to Q2.E-vec_(m4_U,0)
ifelse(ifinstr(m4Da,B1,T,m4Da,R1,T),T,
`line to rvec_(-2*m4_U,0)
ifinstr(m4Da,R1,
`line to rvec_(-m4_U,0); corner pushdef(`dimen_',((dimen_)*0.6))
R1: resistor(to Q1.E+vec_(-m4_U/0.6,0),,m4DE1) popdef(`dimen_')
ifinstr(m4Da,E,,`corner;E: Here; line from Q1.E to E')
point_(hp_ang)')')')
ifinstr(m4Da,R2,
`line from M4D1 to M4D1+vec_(-4*m4_U,0); corner
pushdef(`dimen_',((dimen_)*0.6))dnl
R2: resistor(to M4D2,,m4DE2) popdef(`dimen_')
point_(hp_ang)')
ifinstr(m4Da,D,
`DE: Q1.E + vec_(m4_U*3/2,m4DR`'(-m4_U*3/2))
DS: QC - vec_(m4_U*3/2,m4DR`'m4_U*3/2)
line from Q1.E to DE
line from QC to DS
mitre_(DS,DE,Q1.E)
mitre_(DE,DS,QC)
Diode: diode(ifinstr(m4Da,P,`from DS to DE',`from DE to DS'))
point_(hp_ang)')
ifinstr(m4Da,Z,
`ifinstr(m4Da,E,,
`line from QC to QC+vec_(m4_U*3/2,0); corner; C: Here')
move to Q2.Bulk.c+vec_(0,m4DR`'m4_U)
line to rvec_(2*m4_U,0) then to rvec_(4.5*m4_U,m4DR`'(-2*m4_U)) \
then to rvec_(4.5*m4_U,m4DR`'(-2*m4_U-lthick/4))
Zener: diode(ifinstr(m4Da,P,`to QC+vec_(m4_U*3/2,0)',
`from QC+vec_(m4_U*3/2,0) to Here'),Z)
point_(hp_ang)')
popdef(`dimen_') `$4' ]')
`igbt(linespec, L|R, [L][[d]D])
Arg 3: L = 2nd gate type, D = parallel diode,
dD = dotted connections'
define(`igbt',`bi_trans(`$1',`$2',ifinstr(`$3',L,,GH)CBUdE`$3',,`$4')')
`Customizable bi_trans(linespec, L|R, chars, E)
chars
BU=bulk line
B=base line and label
uEn|dEn=emitters E0 to En
uE|dE=emitter line
Cn|uCn|dCn=collectors C0 to Cn (arrow u or d)
C|uC|dC=collector line (arrow u or d)
uT|dT=trigger line
G=gate line and location
H=gate line
L=L-gate line and location
S=Schottky
[d]D=named parallel diode, d=connection dots'
define(`bi_trans',
`define(`m4R',`ifelse(`$2',R,-)')define(`dna_',`ifelse(`$3',,BCuEBU,`$3')')dnl
define(`m4n',0)define(`m4dE',)dnl
[ ifelse(`$1',,`tr_xy_init(,m4_U,m4R); E: tr_xy(-3,0); C: tr_xy(3,0)',
`eleminit_(`$1'); tr_xy_init(last line.c,m4_U,m4R)
E: last line.start; line from E to tr_xy(-3,0) \
then to tr_xy(-3,0) + vec_( lthick*0.15,m4R`'lthick/3)
C: E+vec_(rp_len,0); line from C to tr_xy(3,0) \
then to tr_xy( 3,0) + vec_(-lthick*0.15,m4R`'lthick/3)')
Bulk: line sc_draw(`dna_',BU,,invis) from tr_xy(-2,4) \
to tr_xy(2,4)
sc_draw(`dna_',B,
`B: tr_xy(0,6.5); line from B to tr_xy(0,4)')
for_(1,8,1,
`sc_draw(`dna_',E`'m4x,`define(`m4n',m4x*1.5) define(`m4dE',m4a)
m4bi_Em(m4x,m4a,E)
line from tr_xy(-2,4) \
to tr_xy(-2-m4n,4)
Bulk: line invis from tr_xy(-2-m4n,4) \
to Bulk.end')')
sc_draw(`dna_',E,
`define(`m4dE',m4a) m4bi_Em(0,m4a,E)')
for_(1,8,1,
`sc_draw(`dna_',C`'m4x,`define(`m4n',m4x*1.5)
m4bi_Em(m4x,m4a,C)
line from tr_xy(2,4) \
to tr_xy(2+m4n,4)
Bulk: line invis from Bulk.start to tr_xy(2+m4n,4)')')
sc_draw(`dna_',C,
`m4bi_Em(0,m4a,C)')
sc_draw(`dna_',S,
`Bulk: line invis from Bulk.start+ta_xy(-1,0) \
to Bulk.end+ta_xy(1,0)
S1: line from Bulk.end+ta_xy(-1,0) \
to Bulk.end \
then to Bulk.end+ta_xy(0,-0.5) \
then to Bulk.end+ta_xy(-0.5,-0.5)
S2: line from Bulk.start+ta_xy(1,0) \
to Bulk.start \
then to Bulk.start+ta_xy(0,0.5) \
then to Bulk.start+ta_xy(0.5,0.5)')
sc_draw(`dna_',T,
`Tm: line from tr_xy(0,4) \
to tr_xy(2/3,(4 ifelse(m4a,u,+,-)4/1.8*2/3))
T: Here')
sc_draw(`dna_',G,
`G: tr_xy(0,6.5); line from G to tr_xy(0,4.7)')
sc_draw(`dna_',H,
`H1: line from tr_xy(-2,4.7) \
to tr_xy(2,4.7)')
sc_draw(`dna_',L,
`G: tr_xy(-1.5,6.2); line from G to tr_xy(-1.5,4.7) \
then to tr_xy(1.5,4.7)')
sc_draw(`dna_',D,
`D1: line from tr_xy(-5,0) \
to tr_xy(-5,-4)
D2: line from tr_xy( 5,0) \
to tr_xy( 5,-4)
ifelse(m4a,d,`dot(at tr_xy( 5,0)); dot(at tr_xy(-5,0))')
Diode: diode(ifelse(m4dE,d,from,to) tr_xy(-5,-4) \
ifelse(m4dE,d,to,from) tr_xy( 5,-4))
ifelse(m4dE,d,,rp_ang = rp_ang + pi_)
ifelse(`$1',,`E: tr_xy(-5,0); line from E to tr_xy(-3,0);
C: tr_xy(5,0); line from C to tr_xy(3,0)')')
ifinstr(`$4',E,
`A1: arc ifelse(`$2',R,c)cw from Bulk.end+ta_xy(-2,2.5) \
to Bulk.end+ta_xy(-2,-5.5) with .c at Bulk.end+ta_xy(-2,-1.5)
L1: line to Bulk.start+ta_xy(2,-5.5)
A2: arc ifelse(`$2',R,c)cw to Bulk.start+ta_xy(2,2.5) \
with .c at Bulk.start+ta_xy(2,-1.5)
L2: line to Bulk.end+ta_xy(-2,2.5)')
`$5'; manhattan ] ')
`emitters E0 ... En or collectors C0 ... Cn'
define(`m4bi_Em',
``$3'`$1': tr_xy(ifelse(`$3',E,-)(3+(`$1')*1.5),0)
`$3'm`$1': line from `$3'`$1' to tr_xy(ifelse(`$3',E,-)(1.2+(`$1')*1.5),4)
ifelse(`$2',,,`arrow m4c_l ht m4_Aht wid m4_Awd ifelse(`$2',d,<-) \
from 1/4 between `$3'm`$1'.start and `$3'm`$1'.end \
to 3/4 between `$3'm`$1'.start and `$3'm`$1'.end ')
ifelse(eval(`$1'>0),1,`m4bi_Em(eval(`$1'-1),`$2',`$3')')')
`Unijunction transistor ujt(linespec, R,P,E)
Bulk and terminals B1, B2, E defined
arg 2: drawn to the right of curr direction
arg 3: P-channel, default N
arg 4: envelope'
define(`ujt',
`[ ifelse(`$1',,,`eleminit_($1)')
B1: Here
ifelse(`$1',,,`line to rvec_(rp_len/2-m4_U*2,0)')
Bl1: line to rvec_(0,ifelse(`$2',R,-)3.5*m4_U)
Bulk: line from rvec_(-m4_U*0.5,0) \
to rvec_(m4_U*4.5,0)
Bl2: line from Bulk.end+vec_(-m4_U/2,0) \
to Bulk.end+vec_(-m4_U/2,ifelse(`$2',R,,-)3.5*m4_U) ifelse(`$1',,,`\
then to Bulk.c+vec_(rp_len/2,ifelse(`$2',R,,-)3.5*m4_U)')
B2: Here
E: Bulk.c+vec_(2*m4_U,ifelse(`$2',R,-)3.5*m4_U)
E1: line from E to Bulk.center
{arrow m4c_l from last line.ifelse(`$3',P,`end to 1',`start to 7')/8 \
between last line.start and last line.end wid m4_Awd ht m4_Aht }
ifelse(`$4',E,dnl
`Env: circle rad 4*m4_U with .c at Bulk.c')
`$5'; manhattan ] ')
`FETS: j_fet(linespec, R, P, E )
e_fet(linespec, R, P, E|S )
d_fet(linespec, R, P, E|S )
c_fet(linespec, R, P )
g_fet(linespec, R, P, shade spec )
with terminals S, D, G.
arg 2: G pin drawn to right of curr direction
arg 3: P-channel, default N
arg 4: envelope or simplified'
define(`j_fet',`mosfet(`$1',`$2',ifelse(`$3',P,u,d)GSDF,`$4',`$5')')
`Enhancement-mode FET e_fet(linespec,R,P,S,E)'
define(`e_fet',`mosfet(`$1',`$2',
ifelse(`$4',S,`TFD'ifelse(`$3',P,u,d)S,`LEDSQ'ifelse(`$3',P,d,u)B),
`$4',`$5')')
`Depletion-mode FET d_fet(linespec,R,P,S,E)'
define(`d_fet',`mosfet(`$1',`$2',
ifelse(`$4',S,`TFDR'ifelse(`$3',P,u,d)S,`LFDSQ'ifelse(`$3',P,d,u)B),
`$4',`$5')')
`Simplified switching c_fet(linespec,R,P)
arg 3: negated G pin'
define(`c_fet',`mosfet(`$1',`$2',`ZSDF'ifelse(`$3',P,d)T,,`$4')')
`Graphene FET g_fet(linespec,R,P,shadespec)'
define(`g_fet',`mosfet(`$1',`$2',ifinstr(`$3',P,d,u)SKTF,`$4',`$5') ')
`Fe_fet(linespec,R,chars) FET with
superimposed ferroelectric symbol:
arg1, arg2, arg3 are as for mosfet'
define(`Fe_fet',`mosfet(`$1',`$2',ifelse(`$3',,SDFT,`$3'),,
variable(,NN,60,dimen_/3,
at (0.5 between S and D)+vec_(0,ifelse(`$2',R,-)4*m4_U)); `$4')')
` The comprehensive mosfet(linespec,R,BDEFGLQRSTXZ,E)
Every drawn component is controlled by a letter or letter pair in arg 3;
adding or changing elements is easily done by adding a test for a letter
or letter sequence. The modifiers u and d are optional:
udB: center bulk connection pin; u or d arrow
D: D pin and lead
E: dashed substrate
F: solid-line substrate
udG: G pin to substrate at source; u or d arrow
udH: G pin to substrate at center; u or d arrow
K: graphene hexagon
L: G pin to channel (kept for compatibility
for now; the same as dM below)
udM: G pin to channel center or
u: pin at drain end, d: pin at source end
udMn: gates G0 to Gn as above
Py: parallel diode
Pz: parallel zener diode
Q: connect B pin to S pin
R: thick channel
udS: S pin and lead; u or d arrow
dT: G pin to center of channel d: not circle
X: XMOSFET terminal
Z: simplified complementary MOS
arg 2: body drawn to right of curr direction
arg 4: envelope'
define(`mosfet',
`define(`m4R',`ifelse(`$2',R,-)')dnl right orientation flag
define(`dna_',`ifelse(`$3',,DSEdMuBQ,`$3')@')dnl
define(`m4s',ifinstr(dna_,Z,2.5,3.5))dnl size parameter
define(`m4hs',2.5)define(`m4hhx',m4hs*sqrt(3))dnl hex side len
define(`m4K',ifinstr(dna_,K,K))dnl
[ ifelse(`$1',,
`tr_xy_init(,m4_U,m4R); ifinstr(dna_,K,
`S: tr_xy(-m4hs,0); D: tr_xy(m4hs,0); W: S; E: D
tr_xy_init(tr_xy(0,m4hhx/2-m4s),m4_U,m4R)',
`S: tr_xy(-2,0); D: tr_xy(2,0)')',
`eleminit_(`$1'); tr_xy_init(last line.c,m4_U,m4R)
ifinstr(dna_,K,
`S: last line.start; D: last line.end;
W: tr_xy(-m4hs,0); line from S to W
E: tr_xy( m4hs,0); line from D to E
tr_xy_init(tr_xy(0,m4hhx/2-m4s),m4_U,m4R)',
`S: last line.start; line from S to tr_xy(-2,0) \
then to tr_xy(-2,0)+vec_(0,m4R`'linethick pt__)
D: S+vec_(rp_len,0); line from D to tr_xy(2,0) \
then to tr_xy(2,0)+vec_(0,m4R`'linethick pt__)')')
sc_draw(`dna_',B,
`B: tr_xy(0,0); Bl: line from B to tr_xy(0,m4s)
ifelse(m4a,,,`arrow m4c_l ht m4_Aht wid m4_Awd ifelse(m4a,d,<-) \
from tr_xy(0,m4s/2)-vec_(0,m4R`'m4_Aht/2) \
to tr_xy(0,m4s/2)+vec_(0,m4R`'m4_Aht/2) ')')
sc_draw(`dna_',D,
`Dl: line from tr_xy(2,0) \
to tr_xy(2,m4s)')
sc_draw(`dna_',E,
`Channel: line invis from tr_xy(-2.5,m4s) \
to tr_xy(2.5,m4s)
line from tr_xy(-2.5,m4s) \
to tr_xy(-1,m4s)
line from tr_xy(-0.5,m4s) \
to tr_xy(0.5,m4s)
line from tr_xy(1,m4s) \
to tr_xy(2.5,m4s)')
sc_draw(`dna_',F,
`Channel: line from ifinstr(dna_,Z,
`tr_xy(-2,m4s) \
to tr_xy(2,m4s)',
`tr_xy(-2.5,m4s) \
to tr_xy(2.5,m4s)')')
sc_draw(`dna_',G,
`G: tr_xy(-2,(m4s+3.5))
ifelse(m4a,,`Gl: line from tr_xy(-2,m4s) \
to G',
m4a,d,`Gl: arrow m4c_l from G to tr_xy(-2,m4s) ht m4_Aht wid m4_Awd',
m4a,u,`Gl: line from tr_xy(-2,m4s) \
to G; arrow m4c_l ht m4_Aht wid m4_Awd \
from tr_xy(-2,(m4s+3-m4_Aht/(m4_U))) \
to tr_xy(-2,(m4s+3))')')
sc_draw(`dna_',H,
`G: tr_xy(0,(m4s+4))
ifelse(m4a,,`Hl: line from tr_xy(0,m4s) \
to G',
m4a,d,`Hl: arrow m4c_l from G to tr_xy(0,m4s) ht m4_Aht wid m4_Awd',
m4a,u,`Hl: line from tr_xy(0,m4s) \
to G; arrow m4c_l ht m4_Aht wid m4_Awd \
from tr_xy(0,(m4s+3-m4_Aht/(m4_U))) \
to tr_xy(0,(m4s+3))')')
sc_draw(`dna_',K,
`NW: W+ta_xy( m4hs/2, m4hhx/2)
SW: W+ta_xy( m4hs/2,-m4hhx/2)
SE: E+ta_xy(-m4hs/2,-m4hhx/2)
NE: E+ta_xy(-m4hs/2, m4hhx/2)
Kl: line from NW \
to W then to SW then to SE then to E then to NE then to NW `$4'')
sc_draw(`dna_',L,
`G: tr_xy(-2,(m4s+3.5))
Ll: line from tr_xy(2,(m4s+1)) \
to tr_xy(-2,(m4s+1)) \
then to G')
for_(1,4,1,
`sc_draw(`dna_',M`'m4x,`m4mo_Mm(m4x,m4a,`$4',ifinstr(dna_,Z,2,2.5))')')
sc_draw(`dna_',M,`ifelse(
m4a,, `G: tr_xy(0,(m4s+4))
Glh: line from tr_xy(2,(m4s+1)) \
to tr_xy(-2,(m4s+1))
Glv: line from tr_xy(0,(m4s+1)) \
to G',
m4a,u,`G: tr_xy(2,(m4s+3.5))
Gl: line from tr_xy(-2,(m4s+1)) \
to tr_xy(2,(m4s+1)) \
then to G',
m4a,d,`G: tr_xy(-2,(m4s+3.5))
Gl: line from tr_xy(2,(m4s+1)) \
to tr_xy(-2,(m4s+1)) \
then to G')')
sc_draw(`dna_',Py,`pushdef(`m4pdd_mosfet')')
sc_draw(`dna_',Pz,`pushdef(`m4pdd_mosfet',Z)')
ifdef(`m4pdd_mosfet',
`define(`m4q',m4a)dnl
Diode: diode(ifelse(m4q,d,to,from) tr_xy(-2,-2) \
ifelse(m4q,d,from,to) tr_xy( 2,-2),m4pdd_mosfet)
ifelse(m4q,d,rp_ang = rp_ang + pi_)
line from tr_xy(-2,0) \
to tr_xy(-2,-2) \
then to tr_xy(2,-2) \
then to tr_xy(2,0)
popdef(`m4pdd_mosfet')')
sc_draw(`dna_',Q,
`Ql: line from tr_xy(0,0)+vec_(0,m4R`'linethick pt__) \
to tr_xy(0,0) \
then to tr_xy(-2,0) \
then to tr_xy(-2,0)+vec_(0,m4R`'linethick pt__)')
sc_draw(`dna_',R,
`Rl: line thick 2*linethick from tr_xy(-2,m4s)\
-vec_(0,m4R`'linethick*3/2 pt__) \
to tr_xy(2,m4s)-vec_(0,m4R`'linethick*3/2 pt__) ')
sc_draw(`dna_',S,`ifelse(m4K,K,
`Sl: arrow m4c_l ht m4_Aht*2/3 wid m4_Awd \
from ifelse(m4a,u,NW to W,W to NW)',
`Sl: line from tr_xy(-2,0) \
to tr_xy(-2,m4s)
ifelse(m4a,,,`arrow m4c_l ht m4_Aht wid m4_Awd ifelse(m4a,d,<-) \
from tr_xy(-2,m4s/2)-vec_(0,m4R`'m4_Aht/2) \
to tr_xy(-2,m4s/2)+vec_(0,m4R`'m4_Aht/2) ')')')
sc_draw(`dna_',T,
`Tl: line from tr_xy(-2,(m4s+1)) \
to tr_xy(2,(m4s+1))
ifelse(m4a,d,`Nt: circle rad m4_U*2/3 with .c at tr_xy(0,(m4s+1+2/3))')
Gl: line from tr_xy(0,`(m4s+1'`ifelse(m4a,d,+4/3))') \
to tr_xy(0,(m4s+4)); G: Here')
sc_draw(`dna_',X,dnl From Matteo Agostinelli
`B: tr_xy(0,0); Xv: line from B to tr_xy(0,m4s-1)
Xh: line from tr_xy(-1.5,m4s-1) \
to tr_xy(1.5,m4s-1)')
ifelse(`$4',E,`Env: circle rad 4*m4_U with .c at tr_xy(0,m4s)')
`$5'; manhattan ] ')
define(`m4mo_Mm',dnl (m4n,m4a,[E])
`define(`m4mo_d',`eval((`$1')*2+1)')dnl
for_(0,`$1',1,
`define(`m4moc',`ifelse(`$2',u,
` (`$4')-`$4'*4*m4x/m4mo_d',`-`$4'+`$4'*4*m4x/m4mo_d')')dnl
ifinstr(`$3',E,
`M4moM: move from tr_xy(m4moc,m4s) to tr_xy(m4moc,m4s+1)
G`'m4x: LCintersect(M4moM,tr_xy(0,m4s),4*m4_U,R)',
`G`'m4x: tr_xy(m4moc,m4s+4)')
Gm`'m4x: line from G`'m4x to tr_xy(m4moc,m4s+1) \
then to tr_xy(m4moc`'ifelse(`$2',u,-,+)2*`$4'/m4mo_d,m4s+1) ') ')
`Extract substring plus preceding char if u or d'
define(`m4_dna',`define(`m4I_',index($1,`$2'))dnl
ifelse(m4I_,-1,`define(`m4t',0)',`define(`m4t',eval(m4I_+len($2)))dnl
define(`m4a',ifelse(substr($1,decr(m4I_),1),u,`define(`m4I_',decr(m4I_))'u,
substr($1,decr(m4I_),1),d,`define(`m4I_',decr(m4I_))'d))dnl
define(`$1',substr($1,0,m4I_)`'substr($1,m4t))')')dnl
`(r|l|c)label( label, label, label,
relative position, block name )
Element labels at the start, centre, and end
of the last [] block (or a named [] block)
in the current direction. Labels are
spaced and treated as math, but copied
literally if double quoted or defined
by sprintf.
Arg4 can be above, below, left, right
to supplement the default position.
Arg5 is the optional name of a [] block
and is last [] by default.'
`The hash (pound sign) is used in svg text so
we temporarily turn off comments for svg'
define(`rlabel',`ifsvg(`changecom(,)')dnl
m4label(`$1',`$2',`$3',.s_,below_,`$4',`$5')`'ifsvg(`changecom(`#',)')')
define(`clabel',`ifsvg(`changecom(,)')dnl
m4label(`$1',`$2',`$3',,,`$4',`$5')`'ifsvg(`changecom(`#',)')')
labels at centre and both ends of an element `dimen_' long
define(`m4label',`dnl
ifelse(`$1',,,
`{m4lstring(`$1',"sp_`'iflatex(`$ `$1'$',`$1')`'sp_") \
at ifelse(`$7',,last [],`$7').w_ $5 rjust_ $6};')dnl
ifelse(`$2',,,
`{m4lstring(`$2',"sp_`'iflatex(`$ `$2'$',`$2')`'sp_") \
at ifelse(`$7',,last [],`$7')$4 $5 $6};')dnl
ifelse(`$3',,,
`{m4lstring(`$3',"sp_`'iflatex(`$ `$3'$',`$3')`'sp_") \
at ifelse(`$7',,last [],`$7').e_ $5 ljust_ $6};')dnl
')
`dlabel(long,lateral,label,label,label,chars)
Labels for oblique or aligned elements
long, lateral: dispacement from center
with respect to drawing direction
chars:
X displacement is from the centre of the last
line rather than the centre of the last []
L,R,A,B align labels ljust, rjust, above,
or below (absolute) respectively'
define(`dlabel',`ifsvg(`changecom(,)')dnl
define(`m4long_',`ifelse(`$1',,`dimen_',`($1)')')dnl
define(`m4lat_',`ifelse(`$2',,`10bp__',`($2)')')dnl
ifelse(`$3',,,
`{m4lstring(`$3',"iflatex(`$ `$3'$',` $3')") \
at last ifinstr(`$6',X,line,[]).c+vec_(-m4long_,m4lat_) \
ifinstr(`$6',L,ljust,`$6',R,rjust) dnl
ifinstr(`$6',A,above,`$6',B,below) };') dnl
ifelse(`$4',,,
`{m4lstring(`$4',"iflatex(`$ `$4'$',` $4')") \
at last ifinstr(`$6',X,line,[]).c+vec_(0,m4lat_) \
ifinstr(`$6',L,ljust,`$6',R,rjust) dnl
ifinstr(`$6',A,above,`$6',B,below) };') dnl
ifelse(`$5',,,
`{m4lstring(`$5',"iflatex(`$ `$5'$',` $5')") \
at last ifinstr(`$6',X,line,[]).c+vec_(m4long_,m4lat_) \
ifinstr(`$6',L,ljust,`$6',R,rjust) dnl
ifinstr(`$6',A,above,`$6',B,below) };') ifsvg(`changecom(`#',)')')
`eleminit_( linespec, default length )
compute element direction and length.
eleminit_ defines the position, length,
and angle of two-terminal elements. It calls
rpoint_ with its linespec or circuit-element
default. The rpoint_ macro draws the invisible
line determined by its argument, calculates the
length and angle, and gives the angle to the
point_ macro to set the rotation parameters used
by vec_ and rvec_.'
define(`eleminit_',
`rpoint_(ifelse(`$1',,`to rvec_(ifelse(`$2',,`elen_',`$2'),0)',`$1'))')
`parallel_(`elementspec', `elementspec', ...
Parallel combination of two-terminal elements
in a [] block. Each elementspec is quoted and
of the form
[Sep=val;][Label:] element; [attributes]
where an attribute is of the form
[llabel(...);]|[rlabel(...);][b_current(...);]
Sep=val; in the first branch sets the default
separation of all branches to val; in a later
element Sep=val; applies only to that branch.
An element may have normal arguments but should
not change the drawing direction.
An argument may also be series_(args) or
parallel_(args) without attributes or quotes.
example:
define(`elen_',dimen_) setdir_(Down)
parallel_(
`resistor;llabel(,R);inductor(,W);llabel(,L)',
`capacitor;rlabel(,C)')
'
define(`parallel_',
`[ ifdef(`m4rp_ang',rp_ang = m4rp_ang;) pwid = 0
stackargs_(`m4parR',$@) stackexec_(`m4parR',`m4parS')dnl
define(`m4br',0) define(`m4parsep',`m4sepdefault')dnl
stackdo_(`m4parS',
`define(`m4pel',m4parS)
pushkey_(m4pel,Sep,m4parsep)dnl
ifelse(m4br,0,`define(`m4parsep',m4Sep)')dnl
ifinstr(m4pel,Sep=,`define(`m4pel',substr(m4pel,eval(index(m4pel,;)+1)))')
E`'eval(m4br+1): [
Start: Here
m4pel
End: Here
C: 0.5 between Start and End
] ifelse(m4br,0,,`with .C at C`'m4br-vec_(0,m4Sep)')
define(`m4br',incr(m4br))dnl
Start`'m4br: E`'m4br.Start; End`'m4br: E`'m4br.End; C`'m4br: E`'m4br.C
pwid = max(pwid,distance(Start`'m4br,End`'m4br))
')
U: Vdiff_(End1,Start1)
d = vlength(U.x,U.y); if d==0 then { d=1 } else { d = 1/d }
Unit: Vsprod_(U,d)
line from C1-(Vsprod_(Unit,pwid/2)) to C`'m4br-(Vsprod_(Unit,pwid/2)) \
chop -lthick/2
Start: last line.c
line from C1+Vsprod_(Unit,pwid/2) to C`'m4br+Vsprod_(Unit,pwid/2) \
chop -lthick/2
End: last line.c; C: 0.5 between Start and End
for_(1,m4br,1,`
line from Start`'m4x to C`'m4x-Vsprod_(Unit,pwid/2)
line from End`'m4x to C`'m4x+Vsprod_(Unit,pwid/2)')
] with .Start at Here; move to last [].End
')
define(`m4sepdefault',`dimen_') `Default separation in the parallel_ macro'
define(`m4lendefault',`dimen_') `Default length in the series_ macro'
`series_(elementspec, elementspec, ... )
Series combination in a [] block of elements
with shortened default length
An elementspec is of the form
[Label:] element; [attributes]
where an attribute is of the form
[llabel(...);]|[rlabel(...);][b_current(...);]
Internal points Start, End, and C are defined
automatically.'
define(`series_',
`[ pushdef(`elen_',m4lendefault)dnl
stackargs_(`m4serR',$@) stackexec_(`m4serR',`m4serS')dnl
ifdef(`m4rp_ang',rp_ang = m4rp_ang;) Start: Here
stackdo_(`m4serS',`m4serS
') End: Here;
C: 0.5 between Start and End
popdef(`elen_')] with .Start at Here; move to last [].End
')
`reversed(`macro name in quotes', macro args)
reverse polarity of two-terminal element'
define(`reversed',`eleminit_(`$2')
$1(from last line.end to last line.start,shift(shift($@)))
rp_ht = -rp_ht; rp_wid = -rp_wid; rp_ang = rp_ang - pi_
line invis to last line.start ')
`resized(factor,`macro name in quotes',args)
multiply element body size by factor'
define(`resized',`pushdef(`dimen_',(dimen_)*(`$1'))dnl
$2(shift(shift($@))) popdef(`dimen_')')
`variable(`element', type, [+|-]angle,
length, at position)
overlaid arrow or line on two-terminal element
to show variablility:
type = [A|P|L|[u]N|[u]NN][C|S]
A=arrow; P=preset; L=linear; N=nonlinear;
NN=symmetric nonlinear, u changes direction;
C=continuous; S=setpwise.
If arg3 begins with + or -, then the argument
(typically -45) is relative to the current
drawing angle. If arg5 is blank the symbol
is placed over the last []'
define(`variable',`$1
{[ define(`dna_',ifelse($2,,A,$2)`')define(`m4sgn',regexp(`$3',^ *[+-]))dnl
ang = ifelse(m4sgn,-1,,rp_ang*rtod_) ifelse(`$3',,45,`$3')
define(`m4a2',`ifelse(m4sgn,0,rp_ang-pi_/2,0)') dnl
define(`m4a3',`ifelse(m4sgn,0,rp_ang,pi_/2)') dnl
define(`m4tip',`dimen_/8')dnl
T: (Rect_(ifelse(`$4',,`dimen_*0.8',`$4'),ang))
sc_draw(`dna_',P,`Line: line to T; C: Line.c
[line to (Rect_(m4tip,ang-90))] at Line.end')
sc_draw(`dna_',L,`Line: line to T; C: Line.c')
sc_draw(`dna_',NN,`C: 1/2 between Here and T
ifelse(m4a,u,`Line: line from Here+(rect_(-m4tip,m4a3)) to Here \
then to T then to T+(rect_( m4tip,m4a3))',
`Line: line from Here+(rect_(-m4tip,m4a2)) to Here \
then to T then to T+(rect_( m4tip,m4a2))')')
sc_draw(`dna_',N,`C: 1/2 between Here and T
ifelse(m4a,u,`Line: line to T then to T+(rect_(m4tip,m4a3))',
`Line: line from T to Here \
then to Here+(rect_(-m4tip,m4a2))')')
sc_draw(`dna_',A,`Line: arrow to T; C: Line.c')
sc_draw(`dna_',C,`move to T+(dimen_*0.10,-dimen_*0.06)
line to Here+(Rect_(m4tip,ang))')
sc_draw(`dna_',S,`move to T+(dimen_*0.10,-dimen_*0.12)
line up dimen_*0.06 then right dimen_*0.12 then up dimen_*0.06')
`$6'] with .C ifelse(`$5',,at last [].c,`$5') } ')
`Line hopping over named ordered lines,
diverting left or right:
crossover(linespec,
[L|R][:line attributes],
line_name,line_name,...)
attributes are outlined "color" dotted ...
#define(`hoprad_',`dimen_/12')'
define(`crossover',`eleminit_(`$1')
define(`m4attribs',ifinstr(`$2',:,`patsubst(`$2',^.*:)'))dnl
define(`m4divert',`patsubst(`$2',:.*)')dnl
define(`m4_lt2',`ifelse(ifpstricks(T)`'ifmpost(T)`'ifpgf(T)`'ifsvg(T),T,
`hlth',0)')dnl
M4Start: last line.start; M4End: last line.end
Loopover_(`M4',`line m4attribs to intersect_(M4Start,M4End,M4.start,M4.end) \
chop 0 chop hoprad_-m4_lt2
ifelse(`m4_lt2',0,,`move to rvec_(-m4_lt2,0)')
arc m4attribs ifelse(m4divert,R,c)cw to rvec_(2*hoprad_,0) \
with .c at rvec_(hoprad_,0)
ifelse(`m4_lt2',0,,`move to rvec_(-m4_lt2,0)')', shift(shift($@)))
line m4attribs to M4End ')
`NPDT(npoles,chars) Double throw switch
chars:
R = right orientation'
define(`NPDT',`[define(`m4np',`ifelse(`$1',,1,`$1')')dnl
define(`m4xR',ifinstr(`$2',R,R))define(`m4SR',ifelse(m4xR,R,-))dnl
for_(1,m4np,1,
`{ L`'ifelse(eval(m4np>1),1,m4x): dot(at rvec_(-dimen_/3,0),,1) }
{ X: Here
T`'ifelse(eval(m4np>1),1,m4x): circle invis rad dotrad_ at X
lswitch(from X to X+vec_(dimen_/3,0),m4xR,D)
R`'ifelse(eval(m4np>1),1,m4x): circle invis rad dotrad_ at Here }
ifelse(eval(m4x<m4np),1,`move to rvec_(0,m4SR`'dimen_/2)') ')
ifelse(eval(m4np>1),1,`move to vec_(dimen_/6,m4SR`'dimen_/10)
DL: line dashed to rvec_(0,m4SR`'(m4np-3/4)*dimen_/2)')
`$3']')
`relay(npoles,chars,attributes)
arg1: Number of poles (max 10)
chars:
any of the relaycoil options and:
O = normally open
C = normally closed
P = three-position
none of above = double-throw (default)
L = drawn left (default)
R = drawn to right of drawing direction
Th = thermal '
define(`relay',`[ define(`m4pm',`ifinstr(`$2',R,-)')dnl
Coil: relaycoil(`$2',,,,`$3') define(`m4rel',rcdna_)
V1: Coil.V1
V2: Coil.V2
sc_draw(m4rel,Th,
`{move to Coil #rvec_(-dimen_/8,0)
line from rvec_(-dimen_/20,dimen_/6) \
to rvec_(-dimen_/20,dimen_/20) \
then to rvec_(dimen_/20,dimen_/20) \
then to rvec_(dimen_/20,-dimen_/20) \
then to rvec_(-dimen_/20,-dimen_/20) \
then to rvec_(-dimen_/20,-dimen_/6)}')
Cs: contacts(ifelse(`$1',,1,`$1'),D`'m4rel) with .O1 at Coil.B2 + \
vec_(ifinstr(m4rel,P,-dimen_/5,0)+dimen_/4,m4pm`'(dimen_/4+dimen_/5))
for_(1,ifelse(`$1',,1,`$1'),1,
`P`'m4x: Cs.P`'m4x
C`'m4x: Cs.C`'m4x
O`'m4x: Cs.O`'m4x')
`$4'] ')
`contacts(npoles,chars)
chars:
P= three position
O|C= normally open, normally closed (default)
R= right orientation (default left)
I= open circles for contacts
T= T contacts
U= U contacts
D= dashed line across armatures'
`e.g. contacts(1,5,O)'
define(`contacts',`[
define(`m4np',`ifelse(`$1',,1,`$1')')dnl
ifelse(eval(m4np>10),1,`define(`m4np',10)')dnl
for_(1,m4np,1,
`K`'m4x: contact(`$2') with .O at Here
P`'m4x: circle invis rad dotrad_ at last [].P
C`'m4x: last [].C
O`'m4x: last [].O
ifelse(m4x,m4np,,`move to last[].C+vec_(0,m4pm dimen_/4)')')
ifelse(eval(m4np>1),1,`ifinstr(`$2',D,
`DL: line dashed from K1.A.c to K`'m4np.A.c chop -dimen_/10')')
`$3'] ')
`contact(chars [,R]) Relay contact switch
Arg 2 deprecated, kept for compatibility
chars:
O|C= normally open, normally closed (default)
I= open dots for contacts
X= filled dots
P= three position
R= right orientation (default left)
T= T contacts
U = line contact'
define(`contact',`[ dnl
define(`m4pm',`ifelse(ifinstr(`$1',R,R,`$2',R,R),R,-)')dnl
define(`m4dr',`dotrad_')define(`m4TL',dimen_/12)dnl
define(`m4fll',`ifinstr(`$1',X,,1)')dnl
P: dot(,m4dr,m4fll)
T: P+vec_(dimen_/2-dimen_/12,0)
ifinstr(`$1',P,`ifinstr(
`$1',I,
`{C: dot(at T+vec_(0,m4pm`'(dimen_/8+m4dr*2+lthick/2)),m4dr,m4fll)}
{O: dot(at T-vec_(0,m4pm`'(dimen_/8+m4dr*2+lthick/2)),m4dr,m4fll)}
A: line from P to ifinstr(
`$1',O,`(LCtangent(P,O,dotrad_+lthick/2)) chop m4dr chop -m4dr',
`$1',C,`(LCtangent(P,C,dotrad_+lthick/2,R)) chop m4dr chop -m4dr',
`P+vec_(dimen_/2,0) chop m4dr chop 0')',
`$1',U,
`{C: T+vec_(m4TL*2,m4pm`'(dimen_/6))
line from C to C-vec_(2*m4TL,0)}
{O: T+vec_(m4TL*2,m4pm`'(-dimen_/6))
line from O to O-vec_(2*m4TL,0)}
A: line from P to ifinstr(
`$1',O,`O-vec_(2*m4TL-dimen_/27,0) chop m4dr chop -m4dr',
`$1',C,`C-vec_(2*m4TL-dimen_/27,0) chop m4dr chop -m4dr',
`P+vec_(dimen_/2,0) chop m4dr chop 0')',
`$1',T,
`{CC: T+vec_(0,m4pm`'(dimen_/8+m4TL*2/3))
C: line from CC+vec_(0,-m4TL) to CC+vec_(0,m4TL) }
{OO: T-vec_(0,m4pm`'(dimen_/8+m4TL*2/3))
O: line from OO+vec_(0,-m4TL) to OO+vec_(0,m4TL) }
A: line from P to ifinstr(
`$1',O,`1/6 between O.end and O.start chop m4dr chop -m4dr',
`$1',C,`1/6 between C.start and C.end chop m4dr chop -m4dr',
`P+vec_(dimen_/2,0) chop m4dr chop 0')',
`{AC: arrow m4c_l <- ht dimen_/6 wid dimen_/6 \
from T+vec_(0,m4pm`'dimen_/8) to T+vec_(0,m4pm`'dimen_*3/8) \
then to T+vec_(dimen_/5,m4pm`'dimen_*3/8)
C: Here}
{AO: arrow m4c_l <- ht dimen_/6 wid dimen_/6 \
from T-vec_(0,m4pm`'dimen_/8) to T+vec_(0,-(m4pm`'dimen_*3/8)) \
then to T+vec_(dimen_/5,-(m4pm`'dimen_*3/8))
O: Here}
A: line from P to ifinstr(
`$1',O,`AO.start chop m4dr chop -m4dr',
`$1',C,`AC.start chop m4dr chop -m4dr',
`P+vec_(dimen_/2,0) chop m4dr chop 0')') ', # end of P
`A: line from P to P+vec_(dimen_/2,0) chop m4dr chop 0
define(`m4CO',
`ifinstr(`$1',C,`ifinstr(`$1',O,O)C',`ifinstr(`$1',O,O,OC)')')dnl
ifinstr(m4CO,C,
`move to T
ifinstr(
`$1',I,
`{ C: dot(at rvec_(0,m4pm`'(m4dr+lthick/2)),m4dr,m4fll) }
ifinstr(m4CO,O,,`O: Here')',
`$1',U,
`{C: T+vec_(m4TL*2,m4pm`'(dimen_/6))
line from C to C-vec_(2*m4TL,0)}
ifinstr(m4CO,O,,`O: Here')',
`$1',T,
`CC: rvec_(0,m4pm`'(m4TL*2/3))
{ C: line from CC+vec_(0,-m4TL) to CC+(0,m4TL) }
ifinstr(m4CO,O,,`O: T') ',
`{AC: arrow m4c_l <- ht dimen_/6 wid dimen_/6 \
to rvec_(0,m4pm`'dimen_/4) \
then to rvec_(dimen_/5,m4pm`'dimen_/4)
C: Here }
O:rvec_(dimen_/5,0)') ')
ifinstr(m4CO,O,
`move to T+vec_(0,-(m4pm`'dimen_/8))
ifinstr(
`$1',I,
`{O: dot(at rvec_(0,m4pm`'(-m4dr*2)),m4dr,m4fll) }
ifinstr(m4CO,C,,`C: T ')',
`$1',U,
`{O: T+vec_(m4TL*2,m4pm`'(-dimen_/6))
line from O to O-vec_(2*m4TL,0)}
ifinstr(m4CO,C,,`C: T ')',
`$1',T,
`{ OO: (rvec_(0,m4pm`'(-m4TL*2/3)))
O: line from OO+vec_(0,-m4TL) to OO+vec_(0,m4TL)}
ifinstr(m4CO,C,,`C: T ')',
`{AO: arrow m4c_l <- ht dimen_/6 wid dimen_/6 \
to rvec_(0,-(m4pm`'dimen_/4)) \
then to rvec_(dimen_/5,-(m4pm`'dimen_/4))
O: Here }
ifinstr(m4CO,C,,`C: T+vec_(dimen_/5,0)') ') ')
')
`$3'] ')
`relaycoil( chars, wid, ht, U|D|L|R|degrees,
attributes )
chars: (see IEC 60617 S00305 - S00319)
X or default: external lines from A2 and B2
AX external lines at positions A1,A3
BX external lines at positions B1,B3
NX no lines at positions A1,A2,A3,B1,B2,B3
SO slow operating
SOR slow operating and release
SR slow release
S diagonal slash
HS high speed
NAC unaffected by AC current
AC AC current
ML mechanically latched
MR mechanically resonant
PC pulse counter
PO polarized
RM remanent
RH remanent
TH thermal
EL electronic'
define(`relaycoil',`[ ifelse(`$4',,,`setdir_(`$4')')
define(`m4wd',ifelse(`$2',,`dimen_/4',`($2)'))dnl
define(`m4ht',ifelse(`$3',,`dimen_/2',`($3)'))dnl
define(`m4LL',`ifinstr(`$4',NX,0,dimen_/3)')dnl
define(`rcdna_',ifinstr(`$1',AX,,`$1',BX,,`$1',X,,X)`$1')dnl
{ lbox( m4wd, m4ht, `$5' ) }
{ A1: rvec_(0,m4ht/4)
A2: Here; V1: A2
A3: rvec_(0,-m4ht/4) }
{ B1: rvec_(m4wd,m4ht/4)
B2: rvec_(m4wd,0); V2: B2
B3: rvec_(m4wd,-m4ht/4) }
sc_draw(`rcdna_',AX,
`{ line from A1 to A1+vec_(-dimen_/3,0); V1: Here
line from A3 to A3+vec_(-dimen_/3,0); V2: Here }')
sc_draw(`rcdna_',BX,
`{ line from B1 to B1+vec_( dimen_/3,0); V1: Here
line from B3 to B3+vec_( dimen_/3,0); V2: Here }')
sc_draw(`rcdna_',NX)
sc_draw(`rcdna_',X,
`{ line to rvec_(-dimen_/3,0); V1: Here
move to B2; line to rvec_(dimen_/3,0); V2: Here }')
sc_draw(`rcdna_',SOR,
`{ move to rvec_(0,-(m4ht*5/8)); {lbox(m4wd,m4ht/4)}
{line from rvec_(0,-m4ht/8) to rvec_(m4wd, m4ht/8)}
{line from rvec_(0, m4ht/8) to rvec_(m4wd,-m4ht/8)}
{move to rvec_(0,-(m4ht)*3/8); m4fshade(0,lbox(m4wd,m4ht/4))}
{move to rvec_(0,-(m4ht)/8)
{line to rvec_(0,-m4ht/8)}
{line from rvec_(m4wd,0) to rvec_(m4wd,-m4ht/8)}} }')
sc_draw(`rcdna_',SO,
`{ move to rvec_(0,-(m4ht*5/8)); {lbox(m4wd,m4ht/4)}
{line from rvec_(0,-m4ht/8) to rvec_(m4wd, m4ht/8)}
{line from rvec_(0, m4ht/8) to rvec_(m4wd,-m4ht/8)} }')
sc_draw(`rcdna_',SR,
`{ move to rvec_(0,-(m4ht*5/8)); m4fshade(0,lbox(m4wd,m4ht/4)) }')
sc_draw(`rcdna_',HS,
`{ move to rvec_(0,-(m4ht*5/8)); lbox(m4wd,m4ht/4) }
{ move to rvec_(m4wd/2,-(m4ht/2)); line to rvec_(0,-m4ht/4)} ')
sc_draw(`rcdna_',S,
`{ line from rvec_(0,m4ht/2) to rvec_(m4wd,-m4ht/2)}')
sc_draw(`rcdna_',NAC,
`{ m4fshade(0,lbox(m4wd/4,m4ht)) }
{ move to rvec_(m4wd*3/4,0); m4fshade(0,lbox(m4wd/4,m4ht)) } ')
sc_draw(`rcdna_',AC,
`{ move to rvec_(0,-(m4ht*3/4)); { lbox(m4wd,m4ht/2) }
move to rvec_(m4wd/2,0)
ifgpic(
`arc rad m4wd/3 cw from Here-(m4wd*2/3,0) \
to Here with .c at Here-(m4wd/3,0)
arc rad m4wd/3 ccw from Here to Here+(m4wd*2/3,0) with .c \
at Here+(m4wd/3,0)',
` sinusoid(m4wd/3,twopi_/(m4wd*2/3),pi_/2,-m4wd/3,m4wd/3) \
with .Origin at Here ') }')
sc_draw(`rcdna_',ML,
`{ move to rvec_(0,-(m4ht*11/16)); { lbox(m4wd,m4ht*3/8) }
line from rvec_(0,m4ht*3/16) to rvec_(m4wd/2,-m4ht*3/16) \
then to rvec_(m4wd,m4ht*3/16) } ')
sc_draw(`rcdna_',MR,
`{ move to rvec_(m4wd/2,m4ht/2)
{ m4tmp = rp_ang; dashline(to rvec_(0,m4ht*3/4),,m4ht*3/16,m4ht*3/32)
point_(m4tmp)}
move to rvec_(0,m4ht*3/8)
ifgpic(
`arc rad m4wd/2 cw from rvec_(-m4wd/2,0) \
to Here with .c at rvec_(-m4wd/4,-m4wd/4)
arc rad m4wd/2 ccw from Here to rvec_(m4wd/2,0) with .c \
at rvec_(m4wd/4,m4wd/4)',
`sinusoid(m4wd/6,twopi_/(m4wd),pi_/2,-m4wd/2,m4wd/2) \
with .Origin at Here ') } ')
sc_draw(`rcdna_',PC,
`{ move to rvec_(0,m4ht/2+m4wd/2)
{ lbox(m4wd,m4wd) }
circle diam m4wd/2 at rvec_(m4wd/2,0) } ')
sc_draw(`rcdna_',PO,
`{ move to rvec_(0,-(m4ht*5/8)); { lbox(m4wd,m4ht/4) }
m4fshade(0, line to rvec_(0,m4ht/8) \
then to rvec_(m4wd,m4ht/8) \
then to rvec_(m4wd,-m4ht/8) \
then to rvec_(m4wd*3/4,-m4ht/8) \
then to rvec_(m4wd*3/4,0) \
then to rvec_(m4wd/4,0) \
then to rvec_(m4wd/4,-m4ht/8) \
then to rvec_(0,-m4ht/8) \
then to Here) } ')
sc_draw(`rcdna_',RM,
`{ move to rvec_(0,-(m4ht*5/8)); { lbox(m4wd,m4ht/4) }
line from rvec_(0,m4ht/8) to rvec_(m4wd,-m4ht/8) }')
sc_draw(`rcdna_',RH,
`{ move to rvec_(0,-(m4ht*11/16)); { lbox(m4wd,m4ht*3/8) }
line from rvec_(m4wd/4,m4ht/8) \
to rvec_(m4wd/4,m4ht/32) \
to rvec_(m4wd*3/4,-m4ht/32) \
to rvec_(m4wd*3/4,-m4ht/8) }')
sc_draw(`rcdna_',TH,
`{ line to rvec_(m4wd/4,0) then to rvec_(m4wd/4,m4ht/4) \
then to rvec_(m4wd*3/4,m4ht/4) \
then to rvec_(m4wd*3/4,0) \
then to rvec_(m4wd,0) }')
sc_draw(`rcdna_',EL,
`{ { line from rvec_(m4wd/4,0) to rvec_(m4wd*3/4,0) }
{ line from rvec_(m4wd*3/8,0) to rvec_(m4wd*3/16,m4ht*3/16) }
{ line from rvec_(m4wd*5/8,0) to rvec_(m4wd*13/16,m4ht*3/16) }
{ line from rvec_(m4wd/2,0) to rvec_(m4wd/2,-m4ht/4) } }')
`$6'] ')
`reed(linespec,wid,ht,box attributes,[R][C])
Enclosed two-terminal reed contact;
R=right orientation;
C=closed;
e.g. reed(,,dimen_/5,shaded "lightgreen"'
define(`reed',`eleminit_(`$1')
define(`m4wd',ifelse(`$2',,`dimen_*0.8',`($2)'))dnl
define(`m4ht',ifelse(`$3',,`dimen_*0.3',`($3)'))dnl
define(`m4ng',`ifinstr(`$5',R,-)')dnl
{line to rvec_(max(0,rp_len/2-m4wd/2),0)
{rotbox(m4wd,m4ht,$4,r=m4ht/2)}
{line to rvec_(m4wd*0.2,0) then to \
rvec_(m4wd*0.6,m4ng`'ifinstr(`$5',C,lthick,m4ht/3))}
line from rvec_(m4wd*0.5,0) to rvec_(m4wd,0)
line to rvec_(max(0,rp_len/2-m4wd/2),0)}
{[box invis ht_ m4ht wid_ m4wd] at rvec_(rp_len/2,0)}
line to rvec_(rp_len,0) invis ')
`ccoax(at location,M|F,diameter,attributes)'
define(`ccoax',`[define(`m4cd',ifelse(`$3',,`dimen_*0.4',`$3'))dnl
S: circle diam m4cd `$4'
C: circle diam m4cd/3 fill_(ifinstr(`$2',F,1,0)) at S
`$5'] with .c ifelse(`$1',,`at Here',`$1')')
`tconn( linespec, chars|keys, wid)
terminal connector with head in a [] block
chars:
O=node (circle); OF=filled circle
> (default) | >> | < | << | A | AA | M
A or AA signify arc or double arc
M signifies male bar contact
arg3 is head width or circle diam
keys:
type=chars as above;
wdth=expr; head width;
lgth=expr; type M head length;
sep=expr; double head separation
head=attributes; except lgth, wdth'
define(`tconn',
`pushkeys_(`$2',
`type:m4typ:N; lgth:m4nl; wdth:dimen_/6; sep:dimen_/8; head::N')
ifelse(m4type,m4typ,`poppushdef(`m4type',ifelse(`$2',,>,`$2'))')dnl
ifelse(m4lgth,(m4nl),`poppushdef(`m4lgth',ifelse(`$3',,(dimen_/2),`($3)/2'))')
eleminit_(`$1',dimen_*3/4)
M4Ss: last line.start; M4Se: last line.end
ifelse(ifinstr(m4type,0,O,`ifinstr(m4type,OF,O,m4type)'),O,
`{popdef(`m4wdth')pushdef(`m4wdth',ifelse(`$3',,dimen_/5,`$3'))dnl
line to last line.end chop 0 chop m4wdth
[circle diam m4wdth ifinstr(m4type,OF,`fill_(0)') m4head] \
at rvec_(m4wdth/2,0)}',
m4type,AA,
`{line to last line.end chop 0 chop m4sep+m4wdth
[{A: arc from rvec_(0,m4wdth) to rvec_(0,-m4wdth) with .c at Here m4head}
arc from rvec_(m4sep,m4wdth) to rvec_(m4sep,-m4wdth) \
with .c at rvec_(m4sep,0) m4head] with .A.c at rvec_(m4wdth,0) }',
m4type,A,
`{line to last line.end chop 0 chop m4wdth
[A:arc from rvec_(0,m4wdth) to rvec_(0,-m4wdth) with .c at Here m4head] \
with .A.c at rvec_(m4wdth,0) }',
m4type,<<,
`{line to last line.end chop 0 chop m4sep+m4wdth
[S: Here; {line from rvec_(m4wdth,m4wdth) to S \
then to rvec_(m4wdth,-m4wdth) m4head}; move to rvec_(m4sep,0)
line from rvec_(m4wdth,m4wdth) to Here then to rvec_(m4wdth,-m4wdth) \
m4head ] with .S at Here }',
m4type,<,
`{line to last line.end chop 0 chop m4wdth
[S: Here; line from rvec_(m4wdth,m4wdth) to S \
then to rvec_(m4wdth,-m4wdth) m4head] with .S at Here }',
m4type,>>,
`{line to last line.end chop 0 chop m4sep
[S: Here; {line from rvec_(-m4wdth,m4wdth) to S \
then to rvec_(-m4wdth,-m4wdth) m4head}; move to rvec_(m4sep,0)
line from rvec_(-m4wdth,m4wdth) to Here then to rvec_(-m4wdth,-m4wdth) \
m4head ] with .S at Here }',
m4type,M,
`{line to last line.end chop 0 chop m4lgth
[ S: Here; NW: rvec_(0,m4wdth/2); SW: rvec_(0,-m4wdth/2)
NE: rvec_(m4lgth,m4wdth/2); SE: rvec_(m4lgth,-m4wdth/2)
L: line thick 0 to NW then to NE then to SE then to SW then to Here \
ifelse(m4head,,fill_(0),m4head) ] with .S at Here}',
`{line to last line.end
[S: Here; line from rvec_(-m4wdth,m4wdth) to S \
then to rvec_(-m4wdth,-m4wdth) m4head ] with .S at Here }')
line invis to M4Se popdef(`m4type',`m4lgth',`m4wdth',`m4sep',`m4head') ')
`tbox( text,wid,ht,<|>|<>,attributes )
Pointed terminal box.
text is placed at centre of rectangle in math mode
unless it starts with a double quote or sprintf
arg4= > point on right end (default)
< point on left end; <> both ends
Defaults: wid dimen_*2/3 ht dimen_/3
type= eg dotted outlined "red"
eg tbox(`$V_2$', 30pt__, 15pt__,,fill_(0.9) )'
define(`tbox',`[ define(`m4td',`ifelse(`$4',,>,`$4')')
pushdef(`m4tw2',`ifelse(`$2',,(dimen_*0.4),`(($2)/2)')')dnl
pushdef(`m4th2',`ifelse(`$3',,(dimen_/6),`(($3)/2)')')dnl
N: vec_(0,m4th2)
NE: N+vec_(m4tw2 ifinstr(m4td,>,-m4th2),0)
E: vec_(m4tw2,0)
SE: NE+vec_(0,-m4th2*2)
NW: N-vec_(m4tw2 ifinstr(m4td,<,-m4th2),0)
W: vec_(-m4tw2,0)
SW: NW+vec_(0,-m4th2*2)
C: 0.5 between SW and NE
line from N to NE ifinstr(m4td,>,then to E) then to SE \
then to SW ifinstr(m4td,<,then to W) then to NW then to N `$5'
move to C
ifelse(`$1',,,`m4lstring(`$1',`"iflatex(`$ `$1'$',` $1')"')')
`$6' popdef(`m4th2') popdef(`m4tw2') ]')
`pconnex(R|L|U|D|degrees,chars,attributes)
arg1: drawing direction
chars:
R: right orientation
M|F: male, female
A[B]|AC: 115V 3-prong, B=box (default), C=circle
P: PC connector
D: 2-pin connector
G[B]|GC: 3-pin, B=default, C=circle
J: 110V 2-pin '
define(`pconnex',
`[ define(`m4sgn',ifinstr(`$2',F,,-))define(`m4R_',ifinstr(`$2',R,-))dnl
setdir_(`$1')
define(`m4na_',`ifelse(`$2',,A,`$2')')dnl
ifinstr(m4na_,A,`
Base: ifinstr(m4na_,AC,`circle diam dimen_ `$3'',
`[lbox(dimen_,dimen_,`$3') ]')
N: m4pconpin(dimen_/12,dimen_*0.3,m4na_) \
at Base+vec_(m4sgn`'(-dimen_*0.2),m4R_`'dimen_*0.15)
H: m4pconpin(dimen_/12,dimen_*0.25,m4na_) \
at Base+vec_(m4sgn`'(dimen_*0.2),m4R_`'dimen_*0.15)
gd = dimen_/12
G: [ifelse(ifgpic(T)`'ifinstr(m4na_,F,,T),TT,
`circle fill_(m4fill) rad gd at vec_(0,m4R_`'gd/2)
box fill_(m4fill) wid 2*gd ht gd at vec_(0,0)',
`arc ifinstr(m4na_,R,,c)cw rad gd from vec_(gd,m4R_`'gd/2) \
to vec_(-gd,m4R_`'gd/2) with .c \
at vec_(0,m4R_`'gd/2) ifinstr(m4na_,F,,
`ifdef(`r_',`shaded rgbstring(r_,g_,b_)',`fill_(m4fill)')')
line from vec_(-gd,m4R_`'gd/2) \
to vec_(-gd,m4R_`'(-gd/2)) \
then to vec_(gd,m4R_`'(-gd/2)) \
then to vec_(gd,m4R_`'gd/2) ifinstr(m4na_,F,,
`ifdef(`r_',`shaded rgbstring(r_,g_,b_)',`fill_(m4fill)')')')
] at Base+vec_(0,m4R_`'(-dimen_*0.25))',
m4na_,P,
`wd = dimen_; hd = wd*3/4
Base: [line to vec_(-wd/2,0) \
then to vec_(-wd/2,-hd*2/3) \
then to vec_(-wd/2+hd/3,-hd) \
then to vec_(wd/2-hd/3,-hd) \
then to vec_(wd/2,-hd*2/3) \
then to vec_(wd/2,0) \
then to Here `$3']
N: m4pconpin(dimen_/12,dimen_*0.25,m4na_) \
at Base+vec_(m4sgn`'(-dimen_*0.2),m4R_`'dimen_*0.15)
H: m4pconpin(dimen_/12,dimen_*0.25,m4na_) \
at Base+vec_(m4sgn`'(dimen_*0.2),m4R_`'dimen_*0.15)
G: m4pconpin(dimen_/12,dimen_*0.20,m4na_) \
at Base+vec_(0,m4R_`'(-dimen_*0.15))',
m4na_,D,
`wd = dimen_*1.2; hd = wd/2
Base: [rotbox(wd,hd,,r=hd/2,`$3')]
H: m4pcrpin(dimen_/6,m4na_) at Base.c+vec_( (wd-hd)/2,0)
N: m4pcrpin(dimen_/6,m4na_) at Base.c+vec_(-(wd-hd)/2,0)',
m4na_,G,
`wd = dimen_*1.3; hd = dimen_*1.2
Base: ifinstr(m4na_,GC,`circle diam wd',
`[line to vec_(wd/2,0) \
then to vec_(wd/2,-hd*0.3) \
then to vec_(hd*0.15,-hd) \
then to vec_(-hd*0.15,-hd)\
then to vec_(-wd/2,-hd*0.3) \
then to vec_(-wd/2,0) \
then to Here ]')
H: m4pconpin(dimen_*0.25,dimen_/8,m4na_) \
at Base.c+vec_(-dimen_/3,dimen_*0.3)
N: m4pconpin(dimen_*0.25,dimen_/8,m4na_) \
at Base.c+vec_( dimen_/3,dimen_*0.3)
G: m4pconpin(dimen_/8,dimen_*0.25,m4na_) \
at Base.c+vec_(0,-dimen_/3)',
m4na_,J,
`wd = dimen_; hd = wd/2
Base: [line to vec_(wd/2,0) \
then to vec_(wd/2,hd) \
then to vec_(-wd/2,hd) \
then to vec_(-wd/2,0) \
then to Here ]
H: m4pconpin(dimen_/12,dimen_*0.25,m4na_) at Base.c+vec_( wd/4,0)
N: m4pconpin(dimen_/12,dimen_*0.25,m4na_) at Base.c+vec_(-wd/4,0)
')
`$4' ; resetdir_ ]')
define(`m4pconpin',`[ifinstr(`$3',F,`lbox(`$1',`$2')',
`m4fshade(m4fill,lbox(`$1',`$2'))')]')
define(`m4pcrpin',`[ifinstr(`$2',F,`circle diam `$1'',
`m4fshade(m4fill,circle diam `$1')')]')
`Header(1|2,rows,wid,ht,type)
arg1: number of columns
arg2: pins per column
arg3,4: custom wid, ht
arg5: eg fill_(0.9)'
define(`Header',
`[define(`m4Hm',`ifelse(`$2',,2,`$2')')define(`m4Hn',`ifelse(`$1',,1,`$1')')dnl
define(`m4Hw',`ifelse(`$3',,`m4Hn*L_unit*3',`($3)')')dnl
define(`m4Hh',`ifelse(`$4',,`m4Hm*L_unit*3',`($4)')')dnl
Block: rotbox(m4Hw,m4Hh,`$5')
define(`m4Hct',1)dnl
for_(1,m4Hm,1,
`HeaderPin(Block.NW+vec_(L_unit*3/2,-(m4x-1/2)*m4Hh/m4Hm),
eval(m4Hct-1), P`'m4Hct,w) define(`m4Hct',incr(m4Hct))
ifelse(m4Hn,2,`HeaderPin(Block.NE+vec_(-L_unit*3/2,-(m4x-1/2)*m4Hh/m4Hm),
1, P`'m4Hct,e) define(`m4Hct',incr(m4Hct))') ')
`$6' ]')
`HeaderPin(location,type,Picname,
n|e|s|w,length)'
define(`HeaderPin',`define(`m4Hpl',`ifelse(`$5',,`lg_plen*L_unit',`$5')')dnl
move to `$1'
line to ifelse(`$4',n,`rvec_(0,m4Hpl)',
`$4',e,`rvec_(m4Hpl,0)',`$4',s,`rvec_(0,-m4Hpl)',`rvec_(-m4Hpl,0)')
ifelse(`$3',,,`$3': Here)
ifelse(`$3',,,Pin`$3':) ifelse(`$2',0,
`rotbox(L_unit,L_unit,fill_(1))',
`circle diam L_unit fill_(1)') at last line.start ')
`nport(box specs; other commands,
nw,nn,ne,ns,
space ratio,pin lgth,style,other commands)
Default is a standard-box twoport. Args 2 to 5 are
the number of ports to be drawn on w, n, e, s sides.
The port pins are named by side, number, and by a or b pin,
e.g. W1a, W1b, W2a, ... . Arg 6 specifies the ratio of
port width to interport space (default 2), and arg 7 is
the pin length. Set arg 8 to N to omit the dots on
the port pins. Arguments 1 and 9 allow customizations'
define(`nport',`[Box: box `$1'
r = ifelse(`$6',,2.0,`$6')
plg = ifelse(`$7',,`dimen_/4',`$7')
# `West side'
define(`m4n',`ifelse(`$2'`$3'`$4'`$5',,1,`$2',,0,`($2)')')
d = Box.ht/(m4n*(r+1)+1)
move to Box.nw+(0,-d); down_
m4portpins(-plg,d*r,d,W,`$8')
# `North side'
define(`m4n',`($3)')
ifelse(`$3',,,`d = Box.wid/(m4n*(r+1)+1)
move to Box.nw+(d,0); right_
m4portpins(plg,d*r,d,N,`$8')')
# `East side'
define(`m4n',`ifelse(`$2'`$3'`$4'`$5',,1,`$4',,0,`($4)')')
d = Box.ht/(m4n*(r+1)+1)
move to Box.ne+(0,-d); down_
m4portpins(plg,d*r,d,E,`$8')
# `South side'
define(`m4n',`($5)')
ifelse(`$5',,,`d = Box.wid/(m4n*(r+1)+1)
move to Box.sw+(d,0); right_
m4portpins(-plg,d*r,d,S,`$8')')
`$9' undefine(`m4n')]')
define(`m4portpins',`for_(1,m4n,1,
`{ if (`$1' != 0) then { line to rvec_(0,`$1') }
`$4'`'m4x`'a: ifelse(xtract(`$5',N),N,Here,`dot') }
move to rvec_(`$2',0)
{ if (`$1' != 0) then { line to rvec_(0,`$1') }
`$4'`'m4x`'b: ifelse(xtract(`$5',N),N,Here,`dot') }
ifelse(m4x,m4n,,`move to rvec_(`$3',0)')')')
`gyrator(box specs,space ratio,pin lgth,style)
Gyrator two-port wrapper for nport
e.g. gyrator(ht boxwid invis,,0,N)'
define(`gyrator',
`define(`m4dna_',ifelse(xtract(`$4',V)`'xtract(`$4',H),,H`$4',`$4')`')dnl
sc_draw(`m4dna_',H,
`nport(ifelse(`$1',,wid boxht,`$1'),1,,1,,`$2',`$3',`$4',
line from (Box,W1a)+(-Box.wid/2,0) \
left -Box.wid/4 then down W1a.y-W1b.y then right -Box.wid/4
arcd(Box+(-Box.wid/4,0),(W1a.y-W1b.y)/3,-90,-270)
line from (Box,W1a)+(Box.wid/2,0) \
left Box.wid/4 then down W1a.y-W1b.y then right Box.wid/4
arcd(Box+(Box.wid/4,0),(W1a.y-W1b.y)/3,90,270)
`$5')')dnl
sc_draw(`m4dna_',V,
`nport(ifelse(`$1',,wid boxht,`$1'),,1,,1,`$2',`$3',`$4',
line from (N1a,Box)+(0,-Box.ht/2) \
down -Box.ht/4 then right N1b.x-N1a.x then up -Box.ht/4
arcd(Box+(0,-Box.ht/4),(N1b.x-N1a.x)/3,-90+90,-90+270)
line from (N1a,Box)+(0,Box.ht/2) \
down Box.ht/4 then right N1b.x-N1a.x then up Box.ht/4
arcd(Box+(0,Box.ht/4),(N1b.x-N1a.x)/3,90+90,90+270)
`$5')') ')
`proximity(linespec)'
define(`proximity',`consource(`$1',P)')
`nullator(linespec, wid, ht, attributes)'
define(`nullator',`eleminit_(`$1')
pushdef(`m4wd',ifelse(`$2',,`dimen_/2',`($2)'))dnl
pushdef(`m4ht',ifelse(`$3',,`dimen_/4',`($3)'))dnl
{line to rvec_(max(0,rp_len/2-m4wd/2),0)
move to rvec_(m4wd/2,0)
{ spline ifdpic(0.58) from rvec_(ifdpic(0,-m4wd/20),m4ht/2) \
to rvec_(m4wd/20*3,m4ht/2) \
then to rvec_(m4wd/2,m4ht/4) \
then to rvec_(m4wd/2,-m4ht/4) \
then to rvec_(m4wd/20*3,-m4ht/2) \
then to rvec_(-m4wd/20*3,-m4ht/2) \
then to rvec_(-m4wd/2,-m4ht/4) \
then to rvec_(-m4wd/2,m4ht/4) \
then to rvec_(-m4wd/20*3,m4ht/2) \
then to rvec_(ifdpic(0,m4wd/20),m4ht/2) `$4'
}
line from rvec_(m4wd/2,0) \
to rvec_(max(0,rp_len/2),0)}
{[box invis ht_ m4ht wid_ m4wd] at rvec_(rp_len/2,0)}
line to rvec_(rp_len,0) invis popdef(`m4wd',`m4ht') ')
`norator(linespec, wid, ht, attributes)'
define(`norator',`eleminit_(`$1')
pushdef(`m4wd',ifelse(`$2',,`dimen_/2',`($2)'))dnl
pushdef(`m4ht',ifelse(`$3',,`dimen_/4',`($3)'))dnl
{line to rvec_(max(0,rp_len/2-m4wd/2),0)
move to rvec_(m4wd/2,0)
for i=-1 to 1 by 2 do { {
spline to rvec_(i*m4wd/4,m4ht/2) \
then to rvec_(i*m4wd/2,m4ht/2) \
then to rvec_(i*m4wd/2,-m4ht/2) \
then to rvec_(i*m4wd/4,-m4ht/2) \
then to Here `$4' } }
line from rvec_(m4wd/2,0) \
to rvec_(max(0,rp_len/2),0)}
{[box invis ht_ m4ht wid_ m4wd] at rvec_(rp_len/2,0)}
line to rvec_(rp_len,0) invis popdef(`m4wd',`m4ht') ')
`ACsymbol(at position, len, ht, [n:][A]U|D|L|R|degrees,
attributes)
Arg4: drawing direction (default: current direction)
Arg4 contains A: use arcs instead of sinusoid
A convenience for drawing a stack of n 1-cycle
sinusoids (default 1)
e.g. source; ACsymbol(at last [])'
define(`ACsymbol',`[ Origin: Here
pushdef(`m4range',`ifelse(`$2',,(dimen_/3),`($2)')')dnl
pushdef(`m4ACd',`patsubst(ifinstr(`$4',:,`patsubst(`$4',.*:)',`$4'),A)')dnl
setdir_(ifelse(m4ACd,,`ifdef(`m4a_',rp_ang*rtod_,0)',m4ACd))
Start: rvec_(-m4range/2,0)
End: rvec_( m4range/2,0)
pushdef(`m4n',`ifinstr(`$4',:,`eval(patsubst(`$4',:.*))',1)')dnl
pushdef(`m4amp',`ifelse(`$3',,`m4range/6',`($3)/2')')dnl
for_(1,m4n,1,`move to Origin+vec_(0,((m4n+1)/2-m4x)*m4range/3)
ifinstr(ifgpic(A,`$4'),A,
`{ S`'m4x: [ Origin: Here
{ arc ccw to rvec_(-m4range/2,0) \
with .c at rvec_(-m4range/4,-max(m4range/4-m4amp,0)) }
{ arc ccw to rvec_( m4range/2,0) \
with .c at rvec_( m4range/4, max(m4range/4-m4amp,0)) }] dnl
with .Origin at Here }',
`{ S`'m4x: sinusoid(m4amp,twopi_/m4range,pi_/2,
-m4range/2,m4range/2,`$5') with .Origin at Here } ')')
`$6'; resetdir_ popdef(`m4amp',`m4n',`m4ACd',`m4range')] dnl
with .Origin ifelse(`$1',,`at Here',`$1')')
`Deltasymbol(at position, keys, U|D|L|R|degrees,
attributes)
keys: size=expr;
type=C|O (default C for Closed, O means open);
Arg3: drawing direction (default: Up)
An O (not 0) in arg3 draws an open symbol'
define(`Deltasymbol',`[ sq3 = sqrt(3)
pushkeys_(`$2',size:dimen_/10; type:C:N )dnl
setdir_(`$3',U)
ifinstr(m4type,C,
`line `$4' from vec_(vscal_(m4size,-sq3,0)) to \
vec_(vscal_(m4size,-sq3,1)) then to Here \
then to vec_(vscal_(m4size,-sq3,-1)) \
then to vec_(vscal_(m4size,-sq3,0))',
`line `$4' from vec_(vscal_(m4size,-sq3/2,-1/2)) \
to vec_(vscal_(m4size,-sq3,-1)) \
then to vec_(vscal_(m4size,-sq3,1)) \
then to vec_(vscal_(m4size,-sq3/2,1/2)) ')
C: vec_(vscal_(m4size,-(sq3+1/sq3)/2,0)); N: C
`$4'; resetdir_ popdef(`m4size',`m4type') ] ifelse(`$1',,`at Here',`$1')')
`Ysymbol(at position, keys, U|D|L|R|degrees, attributes)
keys: size=expr; type=G[L] (grounded,
L puts the ground on the left);
Arg3: drawing direction (default: Up)'
define(`Ysymbol',`[ sq3 = sqrt(3)
pushkeys_(`$2',`size:dimen_/10:; type::N')dnl
setdir_(`$3',U)
C: Here; N: C
line from vec_(vscal_(m4size,-2/sq3,0)) to C
{ line `$4' from vec_(vscal_(m4size,1/sq3,1)) to C \
then to vec_(vscal_(m4size,1/sq3,-1)) }
ifelse(m4type,,,`line `$4' ifinstr(m4type,L,left_,right_) m4size*3/2
corner(,`$4'); pushdef(`dimen_',m4size*4) ground popdef(`dimen_') ')
`$5'; resetdir_ popdef(`m4size',`m4type') ] ifelse(`$1',,`at Here',`$1')')
`Wyesymbol(at position, keys, U|D|L|R|degrees)
Synonym for Ysymbol'
define(`Wyesymbol',`Ysymbol($@)')
`DCsymbol(at position, len, ht, U|D|L|R|degrees,
attributes)
Arg4: drawing direction (default: current direction)'
define(`DCsymbol',`[
pushdef(`m4wid',`ifelse(`$2',,(dimen_/3),`($2)')')dnl
pushdef(`m4ht',`ifelse(`$3',,`(m4wid/5)',`($3)')')
setdir_(ifelse(`$4',,`ifdef(`m4a_',rp_ang*rtod_,0)',`$4'))
Origin: rvec_(m4wid/2, m4ht/2)
{line `$5' to rvec_(m4wid,0)}
dashline(from rvec_(0, m4ht) to rvec_(m4wid, m4ht),`$5',m4wid/4,m4wid/8)
`$6'; resetdir_ popdef(`m4ht',`m4wid') ] \
with .Origin ifelse(`$1',,`at Here',`$1')')
`n-terminal box
nterm(box specs; other commands,
nw,nn,ne,ns,
pin lgth,style,other commands)
The default is three-terminal. Args 2 to 5 are
the number of pins to be drawn on W, N, E, S sides.
The pins are named by side and number, e.g. W1, W2, N1, ...
Arg 6 is the pin length. Set arg 7 to N to omit the dots
on the pins. Arguments 1 and 8 allow customizations, e.g.
nterm(,,,,,,N,
"$a$" at Box.w ljust
"$b$" at Box.e rjust
"$c$" at Box.s above) '
define(`nterm',`[Box: box ifelse(`$1',,wid dimen_ ht dimen_*2/3,`$1')
plg = ifelse(`$6',,`dimen_/4',`$6')
# `West side'
define(`m4n',`ifelse(`$2'`$3'`$4'`$5',,1,`$2',,0,`($2)')')
d = Box.ht/(m4n+1)
move to Box.nw+(0,-d); down_
m4termpins(-plg,d,W,`$7')
# `North side'
define(`m4n',`($3)') ifelse(`$3',,,
`d = Box.wid/(m4n+1)
move to Box.nw+(d,0); right_
m4termpins(plg,d,N,`$7')')
# `East side'
define(`m4n',`ifelse(`$2'`$3'`$4'`$5',,1,`$4',,0,`($4)')')
d = Box.ht/(m4n+1)
move to Box.ne+(0,-d); down_
m4termpins(plg,d,E,`$7')
# `South side'
define(`m4n',`ifelse(`$2'`$3'`$4'`$5',,1,`$5',,0,`($5)')')
d = Box.wid/(m4n+1)
move to Box.sw+(d,0); right_
m4termpins(-plg,d,S,`$7')
`$8' undefine(`m4n')]')
define(`m4termpins',`for_(1,m4n,1,
`{ if (`$1' != 0) then { line to rvec_(0,`$1') }
`$3'`'m4x: ifelse(xtract(`$4',N),N,Here,`dot') }
ifelse(m4x,m4n,,`move to rvec_(`$2',0)')')')
`speaker(U|D|L|R|degrees, vert size, type, attributes)
type=H horn'
define(`speaker',`[setdir_($1,R)
pushdef(`m4v',`ifelse(`$2',,`dimen_/3',`($2)/4')')dnl
pushdef(`m4h',`m4v*sqrt(2)')dnl
ifelse(`$3',H,
`{H1: line from rvec_(m4h,m4v/2) \
to rvec_(m4h*3/2,m4v*7/8) \
then to rvec_(m4h*3/2,-m4v*7/8) \
then to rvec_(m4h,-m4v/2) `$4'}',
`{H1: line from rvec_(m4h,m4v) \
to rvec_(m4h*2,m4v*2) \
then to rvec_(m4h*2,-m4v*2) \
then to rvec_(m4h,-m4v) `$4'}')
{lbox(m4h,m4v*2,`$4')}
{Box: box invis ht_ m4v*2 wid_ m4h at rvec_(m4h/2,0)}
In1: rvec_(0,m4v/2)
In2: Here
In3: rvec_(0,-m4v/2)
In4: rvec_(m4h/4,m4v)
In5: rvec_(m4h*3/4,m4v)
In6: rvec_(m4h/4,-m4v)
In7: rvec_(m4h*3/4,-m4v)
`$5'; resetdir_ popdef(`m4v',`m4h') ]')
`bell(U|D|L|R|degrees, vert size, attributes)'
define(`bell',`[setdir_($1,R)
pushdef(`m4h',`ifelse(`$2',,`dimen_/2',`($2)')')dnl
{lbox(m4h,m4h,`$3')}
{Box: box invis ht_ m4h wid_ m4h at rvec_(m4h/2,0)}
{Circle: circle diameter m4h at rvec_(m4h*3/2,0) `$3'}
In1: rvec_(0,m4h/4)
In2: Here
In3: rvec_(0,-m4h/4)
`$4'; resetdir_ popdef(`m4h') ]')
`microphone(A|U|D|L|R|degrees, vert size,
attributes)
Arg1= A, upright mic
Thanks to Arnold Knott'
define(`microphone',`ifinstr(`$1',A,
`[ pushdef(`m4sfact',`(ifelse(`$2',,dimen_,(`$2'))*8/5)')
circlerad = m4sfact/1000
cspace = m4sfact/100
bwd = m4sfact/10
bht = m4sfact/4+bwd
Stand: line up m4sfact/5
{ arc from Here+(-bwd,bwd) to Here+(bwd,bwd) with .c at Here+(0,bwd)
line up m4sfact/4-bwd from last arc.start
line up m4sfact/4-bwd from last arc.end }
Head: box rad bwd/2 ht bht wid bwd with .s at Here+(0,bwd/2) `$3'
Inner: box rad bwd/2 ht bht/2+bwd/2 wid bwd with .n at Head.n
move to Inner.s+(0,bwd/2)
for i=1 to 4 do {
for j=-1 to 1 do {
{ circle at Here+(3*j*cspace,(abs(j)-3)*cspace) }
if j != 0 then {{ circle at Here+(j*3/2*cspace,0) }} }
move up 5*cspace }; popdef(`m4sfact')]',
`[setdir_($1,R)
pushdef(`m4h',`ifelse(`$2',,`dimen_/2',`($2)')')dnl
{L1: line from rvec_(m4h,-m4h/2) \
to rvec_(m4h,m4h/2)}
{Circle: circle diameter m4h at rvec_(m4h/2,0) `$3'}
In1: rvec_(m4h*(2-sqrt(3))/4,m4h/4)
In2: Here
In3: rvec_(m4h*(2-sqrt(3))/4,-m4h/4)
`$4'; resetdir_ popdef(`m4h') ]')')
`buzzer(U|D|L|R|degrees, vert size,[C],
attributes)'
define(`buzzer',`[setdir_($1,R)
ifelse(`$3',,
`pushdef(`m4h',`ifelse(`$2',,`dimen_/2',`($2)')')dnl
{L1: line from rvec_(m4h,0) \
to rvec_(m4h,m4h/2) \
then to rvec_(0,m4h/2) \
then to rvec_(0,-m4h/2) \
then to rvec_(m4h,-m4h/2) \
then to rvec_(m4h,0) `$4'}
{Box: box invis ht_ m4h wid_ m4h at rvec_(m4h/2,0)}
{L2: line from rvec_(m4h,m4h/2) \
to rvec_(m4h,m4h/2)+vec_(Rect_(m4h,-75))}
In1: rvec_(0,m4h/4)
In2: Here
In3: rvec_(0,-m4h/4) popdef(`m4h')',
`$3',C,`pushdef(`m4h',`ifelse(`$2',,`(dimen_/3)',`(($2)/2)')')dnl
{Face: line from rvec_(m4h,-m4h) \
to rvec_(m4h,m4h)}
{arc ccw from Face.end to Face.start with .c at Face.c `$4'}
In1: rvec_(m4h-sqrt(m4h^2-(m4h/3)^2),m4h/3)
In2: Here
In3: rvec_(m4h-sqrt(m4h^2-(m4h/3)^2),-m4h/3) popdef(`m4h') ')
`$5'; resetdir_ ]')
`earphone(U|D|L|R|degrees, size, [C][R],
attributes)
earphone pair if arg3 contains C'
define(`earphone',`[ setdir_($1,R)
pushdef(`m4h',`ifelse(`$2',,`dimen_',`($2)')')dnl
ifinstr(`$3',C,
`L: circle diam m4h*0.4 `$4'
R: circle diam m4h*0.4 at L+vec_(m4h,0) `$4'
C: 0.5 between L and R
N: C+(vscal_(m4h/2,Vperp(L,R)))
Lx: Cintersect(L,L.rad,C,m4h/2,`$3')
Rx: Cintersect(C,m4h/2,R,R.rad,`$3')
arc ifinstr(`$3',R,c)cw rad m4h/2 from Lx to Rx with .c at C',
`{lbox(m4h/3,m4h/2,`$4')}
{Box: box invis ht_ m4h/2 wid_ m4h/3 at rvec_(m4h/6,0)}
{L1: line thick 2*linethick from rvec_(m4h/3+linethick pt__,-m4h/3) \
to rvec_(m4h/3+linethick pt__, m4h/3) }
In1: rvec_(0,m4h/8)
In2: Here
In3: rvec_(0,-m4h/8)')
`$5'; resetdir_ popdef(`m4h') ]')
`Signal-flow graph macros: labeled node,
directed labeled chopped straight line,
directed labeled chopped arc, and a self
loop. All are contained in [] blocks.'
`Signal-flow graph initialization macro
sfg_init(line len, node rad, arrowhd len, arrowhd wid)'
ifdef(`sfg_init',,
`define(`sfg_init',`cct_init
sfg_wid = ifelse(`$1',,`(linewid/0.75*(2.5+0.25)/4)',(`$1'))# default line len
sfg_rad = ifelse(`$2',,(0.25/4/2),(`$2')) # node radius
sfg_aht = ifelse(`$3',,(0.25/4),(`$3')) # arrow height (arrowhead length)
sfg_awid = ifelse(`$4',,`sfg_aht',(`$4')) # arrowhead width
')')
`sfgline(linespec,
text,sfgabove|sfgbelow|ljust|rjust,
attributes)
Draw a straight line with linespec, chopped by
node radius, with optional label'
define(`sfgline',`eleminit_(`$1',sfg_wid)
[ L1: line to rvec_(rp_len,0) chop sfg_rad `$4'
Start: last line.start
End: Here
move to last line.c
ifelse(ifinstr(`$4',->,T,`$4',<-,T),,
`{ arrow m4c_l ht sfg_aht wid sfg_awid from rvec_(-sfg_aht/2,0) \
to rvec_(sfg_aht/2,0) `$4' }')
ifelse(`$2',,,`m4lstring(`$2',"iflatex(`$ `$2'$',` $2')") \
ifelse(`$3',,`sfgabove',`$3')')
] with .Start at rvec_(sfg_rad,0)
move to last [].End
')
`Like above_ or below_ but adding extra space
to put text above or below arrowheads or nodes'
define(`sfgabove',`at Here+(0,sfg_awid/2) above')
define(`sfgbelow',`at Here+(0,-sfg_awid/2) below')
`sfgnode(at pos,text,above_,circle attributes)
Node: a white circle, possibly labelled. The
default label position is inside if the
diameter is bigger than textht and textwid'
define(`sfgnode',
`[C: circle fill_(1) rad sfg_rad ifelse(`$4',,`thick 0.5',`$4')] with .c \
ifelse(`$1',,`at rvec_(sfg_rad,0)',`$1')
move to last [].c
ifelse(`$2',,,`if 2*sfg_rad > Max(textwid,textht,10pt__) \
then { {m4lstring(`$2',`"iflatex(`$ `$2'$',` $2')"') `$3'} } \
else { { m4lstring(`$2',`"iflatex(`$ `$2'$',` $2')"') \
ifelse(`$3',,`sfgabove',`$3')} }')
')
`sfgarc(linespec,label,above_,cw|ccw,sfact,
attributes)
An arc between nodes at the endpoints of the
linespec. The resulting positions Start, End,
C (arc center) and M (arc midpoint) are defined.
The fifth argument scales the arc height above
its chord.'
define(`sfgarc',`eleminit_(`$1',sfg_wid)
[ Start: Here
End: Start + vec_(rp_len,0)
chordht = (rp_len/sqrt(2)-rp_len/2)ifelse(`$5',,,`*($5)')
arcrd = (chordht^2+(rp_len)^2/4)/chordht/2
C: 0.5 between Start and End; C: C+vec_(0,ifelse(`$4',ccw,,-)(arcrd-chordht))
M: C + vec_( 0,ifelse(`$4',ccw,-)arcrd)
ifelse(ifinstr(`$1',->,T,`$1',<-,T),,
`arc `$6' -> m4c_l ifelse(`$4',ccw,ccw,cw) \
from Cintersect(Start,sfg_rad,C,arcrd,ifelse(`$4',ccw,R)) \
to Cintersect(C,arcrd,M,sfg_aht/2,ifelse(`$4',ccw,,R)) \
ht sfg_aht wid sfg_awid with .c at C `$6'
arc m4c_l ifelse(`$4',ccw,ccw,cw) from M \
to Cintersect(C,arcrd,End,sfg_rad,ifelse(`$4',ccw,R)) with .c at C `$6'',
`arc m4c_l patsubst(patsubst(`$1',.*<-,<-),->.*$,->) ifelse(`$4',ccw,ccw,cw)\
from Cintersect(Start,sfg_rad,C,arcrd,ifelse(`$4',ccw,R)) \
to Cintersect(C,arcrd,End,sfg_rad,ifelse(`$4',ccw,R)) with .c at C `$6'')
ifelse(`$2',,,`move to M; m4lstring(`$2',"iflatex(`$ `$2'$',` $2')") \
ifelse(`$3',,`sfgabove',`$3')')
] with .Start at last line.start
move to last line.end
')
`sfgself(at position,U|D|L|R|degrees,label,above_,cw|ccw,sfact,
[-> | <- | <->], attributes)
A teardrop-shaped self-loop drawn at "angle"
degrees from "positon". The resulting Origin
and M (arc midpoint) are defined. The sixth
argument scales the loop. The seventh puts
the arrowhead at the beginning, end, or both'
define(`sfgself',`[ Origin: Here
setdir_(`$2',U)
d = ifelse(`$6',,,`($6)*') sfg_wid/2; d = d * max(1,sfg_rad/(0.3605*d))
{ m4sfgselfcurve(-, `$8' \
ifelse(`$5',ccw,`ifinstr(`$7',<-,<-)',`ifinstr(`$7',->,<-)'))
M: Here
ifelse(`$7',,`{ arrow `$8' m4c_l from rvec_(0,ifelse(`$5',cw,,-)sfg_aht/2) \
to rvec_(0,ifelse(`$5',cw,-)sfg_aht/2) ht sfg_aht wid sfg_awid }')
ifelse(`$3',,,`{m4lstring(`$3',`"iflatex(`$ `$3'$',` $3')"') \
ifelse(`$4',,`sfgabove',`$4')}') }
m4sfgselfcurve(, `$8' \
ifelse(`$5',ccw,`ifinstr(`$7',->,<-)',`ifinstr(`$7',<-,<-)'))
resetdir_ ] with .Origin ifelse(`$1',,at Here,`$1')
move to last [].Origin
')
define(`m4sfgselfcurve',`spline `$2' m4c_l from rvec_(Rect_(sfg_rad,`$1'30)) \
to rvec_(0.3*d,`$1'0.2*d) \
then to rvec_(0.6*d,`$1'0.35*d) \
then to rvec_(0.9*d,`$1'0.35*d) \
then to rvec_(d,`$1'0.2*d) \
then to rvec_(d,0)')
`winding(L|R,diam, pitch, nturns, core wid, core color )
The complete spline is drawn, then parts of it are
overwritten with the background color (default
white). Arg 1 contains R for right-handed winding.
Arg 4 must be an integer.
Arg 6 must be compatible with the postprocessor.'
define(`winding',`[ define(`m4rt',`ifinstr(`$1',R,-)')
d = ifelse(`$2',,`dimen_',`$2')
p = ifelse(`$3',,d/4,`$3')
define(`m4n0',`ifelse(`$4',,1,`eval(`$4'-1)')')dnl
w = ifelse(`$5',,d*3/4,`$5')
W: spline from (0,0) to (0,0) dnl
for_(0,m4n0,1,
`then to vec_(m4rt`'(m4x*p),d) \
then to vec_(m4rt`'(m4x*p+p/2),d) \
then to vec_(m4rt`'(m4x*p+p/2),0)`'ifelse(m4x,m4n0,,` \
then to vec_(m4rt`'(m4x*p+p),0) \')')
if w > 0 then {
dx = sign(p)*(linethick+0.5)/2 bp__
vx = p*min(w/d/8+dx/p,0.25)
for i=0 to m4n0 do {
line color ifelse(`$6',,rgbstring(1,1,1),m4lstring(`$6',"`$6'")) \
thick max(w/(1bp__)-linethick,0) \
from vec_(m4rt`'(i*p-dx),d/2) \
to vec_(m4rt`'(i*p+vx),d/2)
dx = vx }
}
T1: W.ifinstr(`$1',R,end,start)
T2: W.ifinstr(`$1',R,start,end)
`$7']')
`tstrip(U|D|L|R|degrees, n, chars)
Terminal strip
n=integer number of terminals (default 4)
chars:
I invisible terminals
C circle terminals (default)
D dot terminals
O omitted internal lines
box=attributes;
wid=val; total strip width
ht=val; strip height '
define(`tstrip',`[ setdir_(`$1')
define(`m4n',`ifelse(`$2',,4,`eval($2)')')dnl
ifelse(eval(m4n<1),1,`define(`m4n',1)')dnl
pushkeys_(`$3',`ht:dimen_/2; wid:m4n*m4`'ht*0.6; box::N;')
{Box: [shade(1,lbox(m4wid,m4ht,m4box))] }
bw = m4wid/(m4n)
ifinstr(`$3',O,,`for i=1 to m4n-1 do {
{move to rvec_(i*bw,-m4ht/2); line to rvec_(0,m4ht)}}')
for_(1,m4n,1,`{T`'m4x: ifinstr(`$3',I,`rvec_((m4x-0.5)*bw,0)',
`dot(at rvec_((m4x-0.5)*bw,0),,ifinstr(`$3',D,0,1))')
{L`'m4x: T`'m4x+vec_(0,m4ht/2)}; {R`'m4x: T`'m4x+vec_(0,-m4ht/2)} }')
`$4' popdef(`m4wid',`m4ht',`m4box')
resetdir_ ]')
`jack(U|D|L|R|degrees, chars [;keys])
Phone jack; arg1 sets drawing direction
chars: A sequence of letters L, S, C, each
possibly followed by M, B, MB, or BM, e.g. LLMSBM
L draws a long contac arm, M adds a Make contact,
B a Break contact, and MB or BM adds both
S similarly draws a short contact
C adds a central medium contact
also:
X=bring aux contacts to external dots
R=right jack orientation wrt to drawing direction
keys: dots=dot keys; (default circle=fill_(1))
arrowht=expr; (dimen_/8)
sleeve=attributes; e.g. shaded "red"
sleeveht=expr; (4.5*arrowht)
sleevewid=expr; (sleeveht/6)
armlen=expr; len of long armature (dimen_*.75) '
define(`jack',`[ setdir_(`$1')
pushkeys_(`$2',`dots:circle=fill_(1):N;
arm::N; armlen:dimen_*0.75; arrowht:dimen_/8;
sleeve::N; sleeveht:m4`'arrowht*4.5; sleevewid:m4`'sleeveht/6; ')dnl
pushdef(`dna_',`$2') pushdef(`rght',sc_draw(`dna_',R,-)1)dnl
pushdef(`m4extrn',sc_draw(`dna_',X,X)) pushdef(`m4vd',`dimen_/16')dnl
ifelse(dna_,,`define(`dna_',L)')
Sleeve: [lbox(m4sleevewid,m4sleeveht,m4sleeve)]
F: Sleeve+vec_(m4sleevewid/2,0)
Ctr: (2 between F and Sleeve)+vec_(-(m4armlen+m4vd), 0);
G: Sleeve+vec_(0,-m4sleeveht/2*(rght)); Sx: G+(Ctr-Sleeve)
H: 2 between G and Sleeve; Lx: H+(Ctr-Sleeve)
Q: Ctr; m4jcontacts(dna_,L,rght,,m4armlen)
Q: Ctr; m4jcontacts(dna_,C,rght,,m4armlen)
Q: Ctr; m4jcontacts(dna_,S,neg_(rght),,m4armlen)
ifelse(m4extrn,X,`ifelse(rght,-1,
`T: Sleeve + (Lx-Ctr)+((Between_(G,H,dimen_/6))-G)
line from H to T then to T+(Ctr-Sleeve); H: dot(,m4dots); ',
`T: Sleeve + (Sx-Ctr)+((Between_(H,G,dimen_/6))-H)
line from G to T then to T+(Ctr-Sleeve); G: dot(,m4dots); ')')
`$3'; resetdir_ popdef(`m4dots',`m4arm', `m4armlen', `m4arrowht',
`m4sleeve', `m4sleeveht', `m4sleevewid',`dna_', `rght', `m4extrn', `m4vd')
] ')
`m4jcontacts(dna_, L|S|C, 1|-1, blank|n, armlen)'
define(`m4jcontacts',`ifinstr(`$1',`$2',
`pushdef(`dna_',$1) pushdef(`m4code',regexp(dna_,$2\(M\|B\|MB\|BM\)?,\&))dnl
sc_draw(`dna_',m4code,
`pushdef(`armln',`ifelse(`$2',S,0.55/0.75*,`$2',C,0.65/0.75*)'`$5')dnl
pushdef(`connht',`ifelse($4,,3,ifelse(m4code,$2`'B,4.5,3))')dnl
$2`'x: Q ifelse(`$2',C,,
`+vec_(0,$3*ifelse(`$4',,m4sleeveht/2,connht*m4arrowht)); Q: $2`'x')
$2`'$4: dot(at Q,m4dots)
Armature: line chop last [].wid/2 chop 0 to rvec_(armln-2*m4vd,0) dnl
ifelse($4,,`then to rvec_(armln-m4vd,neg_(`$3')*m4vd) \
then to rvec_(armln,0)')
Contact: Q+vec_(m4arrowht*2,0)
ifelse($4,,,`Connector: [lbox(m4vd,connht*m4arrowht,m4sleeve)] \
at last []+vec_(armln-3*m4vd,neg_(`$3')*connht*m4arrowht/2)')
ifinstr(m4code,M,`$2`'M`'$4: Contact+vec_(0,`$3'*m4arrowht*1.9)
$2`'M`'$4`'A: arrow m4c_l <- ht m4arrowht wid m4arrowht \
from Contact+vec_(0,`$3'*m4arrowht*0.4) \
to $2`'M`'$4 ifelse(m4extrn,X,`then to $2`'$4+vec_(0,`$3'*m4arrowht*1.9)
$2`'M`'$4: dot(,m4dots)'); $2`'x: $2`'M`'$4')
ifinstr(m4code,B,`$2`'B`'$4: Contact+vec_(0,neg_(`$3')*m4arrowht*1.5)
$2`'B`'$4`'A: arrow m4c_l <- ht m4arrowht wid m4arrowht from Contact \
to $2`'B`'$4 dnl
ifelse(m4extrn,X,`then to $2`'$4+vec_(0,neg_(`$3')*m4arrowht*1.5)
$2`'B`'$4:dot(,m4dots)')')
m4jcontacts(dna_,$2,$3,ifelse($4,,1,`incr($4)'),`$5')
popdef(`armln',`connht')')
popdef(`m4code',`dna_')')')
`plug(U|D|L|R|degrees, chars)
Phone plug; arg1 sets drawing direction
chars:
2|3= two|three conductor
R= right orientation wrt drawing direction '
define(`plug',`[ setdir_(`$1')
s=ifinstr(`$2',R,-1,1)
ght = ifinstr(`$2',3,`dimen_*0.5',`dimen_*0.4')
A: Here
AA: line to rvec_(dimen_*0.3,0) \
then to rvec_(dimen_*0.3,s*ght/3) \
then to rvec_(dimen_*0.7,s*ght/3); TA: dot(,,1)
ifinstr(`$2',3,`
C: A+vec_(0,s*ght/2)
TC: line from C to C+vec_(dimen_*0.6,0); TC: Here
B: 2 between A and C',`B: A+vec_(0,s*ght)')
BB: line from B to B+vec_(dimen_*0.3,0) \
then to B+vec_(dimen_*0.3,-s*ght/3) \
then to B+vec_(dimen_*0.6,-s*ght/3); TB: Here
`$3'; resetdir_ ]')
`A dabble in quantum circuits:
SQUID(n,diameter,initial angle,cw|ccw)
Superconducting quantum interface device with
n junctions labeled J1, ... Jn placed around a
circle with initial angle -90 deg (by default)
with respect to the current drawing direction. The
default diameter is dimen_'
define(`SQUID',
`[ pushdef(`m4sqn',`ifelse(`$1',,2,`$1')')dnl
pushdef(`m4ssz',`ifelse(`$2',,`dimen_',`$2')')dnl
pushdef(`m4sof',`ifelse(`$3',,-90,`$3')')dnl
pushdef(`m4ssg',`ifelse(`$4',,+,`$4',ccw,+,-)(m4x-1)/(m4sqn)*360')dnl
pushdef(`m4sxlen',C.rad/4)dnl
C: circle diam m4ssz
for_(1,m4sqn,1,
`move to C+vec_(Rect_(C.rad,m4sof`'m4ssg))
J`'m4x: Here
{ line from rvec_(Rect_(m4sxlen,m4sof`'m4ssg+45)) \
to rvec_(Rect_(m4sxlen,m4sof`'m4ssg+225)) }
{ line from rvec_(Rect_(m4sxlen,m4sof`'m4ssg-45)) \
to rvec_(Rect_(m4sxlen,m4sof`'m4ssg-225)) }')
`$5' popdef(`m4sqn',`m4ssz',`m4sof',`m4ssg',`m4sxlen') ]')
`==============================================================================
Customizations:
The size and style parameters below can be
tweaked, and the cct_init macro modified.'
Size and style parameters:
define(`dimen_',`linewid') `Default element body size unit'
define(`sourcerad_',`(0.25*dimen_)') `Source element default radius'
define(`csdim_',`(0.3*dimen_)') `Controlled Source width/2'
define(`elen_',`(1.5*dimen_)') `Default element length'
define(`delay_rad_',`(0.35*dimen_)') `Delay elements'
define(`dotrad_',`(0.04*dimen_)') `Redefine dot size for circuits'
define(`m4fill',0) `Default fill for diode, fuse, ...'
define(`em_arrowwid',`(dimen_/9)') `em_arrows arrowhead width'
define(`em_arrowht',`(dimen_/7)') `em_arrows arrowhead ht'
define(`em_arrowhead',1) `em_arrows arrowhead style'
define(`hoprad_',`dimen_/12') `arc radius for crossover macro'