/* Useful functions for drawing circuit diagrams.
- * Version 0.1
+ * Version 0.2
*
* Copyright (C) 2003 GS Bustamante ArgaƱaraz
- * 2008-2011 W. Trevor King <wking@drexel.edu>
+ * 2008-2012 W. Trevor King <wking@drexel.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
return (a & reverse(a) & b & reverse(b))--cycle;
}
-path txtahead (path p)
-{
- pair A = point(p,reltime(p,1.0));
- pair B = point(p,reltime(p,0.97));
- pair u = dirtime(p,reltime(p,1.0));
- return A{-u}..(A - scale(7)*rotate(15)*u)--B
- --(A - scale(7)*rotate(-15)*u)..A{u}--cycle;
-}
-
// function to wire the symbols together
int nsq=0, udsq=2, rlsq=3;
} else {
if (type==udsq) {
draw(pin_beg--(pin_beg+(0,dist))--(pin_end.x,pin_beg.y + dist)
- --pin_end, line);
+ --pin_end, line);
} else if (type==rlsq) {
draw(pin_beg--(pin_beg+(dist,0))--(pin_beg.x + dist,pin_end.y)
- --pin_end, line);
+ --pin_end, line);
} else {
write("Error, unrecognized wire type ",type);
}
}
}
-// Macro to center text among two pins
-
-bool witharrow=false, noarrow=true;
-
-void ctext(pair pin_beg, pair pin_end, string txt, bool type)
-{
- picture ctxt;
- if (type==noarrow) {
- ; // pass
- } else if (type==witharrow) {
- draw(ctxt, pin_beg--pin_end);
- draw(ctxt, txtahead(pin_beg--pin_end));
- draw(ctxt, txtahead(reverse(pin_beg--pin_end)));
- } else {
- write("Error, unrecognized ctext type ",type);
- }
- label(ctxt, txt, 0.5(pin_beg+pin_end));
- add(currentpicture, ctxt);
-}
-
-// Definition of lbsep (label separation), distance among symbol and label.
-
-real lbsep=3mm;
-
-
// ----- Here the symbols begin --------
-struct TwoTerminal {
- pair beg;
- pair end;
- pair mid;
- real len;
- real ang;
- real lchar;
- real lcharv;
- string name;
- string val;
+transform _shift_transform(pair z) = shift;
+
+struct MultiTerminal {
+ pair center;
+ real dir;
+ pair terminal[];
+ pair terminal_offset[];
+ Label label;
+ Label value;
+ real label_offset;
+ real value_offset;
path pLine[]; // cyclic paths are filled in
path pMisc[];
-
- void operator init(pair beg, real len, real ang, real lchar, real lcharv, string name, string val, path pLine[]={}, path pMisc[]={}) {
- this.beg = beg;
- this.end = beg+rotate(ang)*(len,0);
- this.mid = (this.beg + this.end)/2;
- this.len = len;
- this.ang = ang % 360;
- this.lchar = lchar;
- this.lcharv = lcharv;
- this.name = name;
- this.val = val;
- this.pLine = pLine;
- this.pMisc = pMisc;
- }
+ pen line;
+ pen misc;
- void putlabel(picture pic=currentpicture) {
- picture picL;
- pair pName, pVal; // point
- real rName, rVal; // rotated by
- align aName, aVal;
- if (labeling==rotatelabel) {
- pName = (lchar+lbsep)*dir (90+ang);
- pVal = (lcharv+lbsep)*dir (270+ang);
- aName = NoAlign;
- aVal = NoAlign;
- if (ang <= 90 || ang > 270) {
- rName = ang;
- rVal = ang;
- } else if (ang > 90 && ang <= 270) {
- rName = 180+ang;
- rVal = 180+ang;
- }
- } else if (labeling==norotatelabel) {
- rName = 0;
- rVal = 0;
- if (ang == 0) {
- pName = (lchar+.25lbsep)*dir (90+ang);
- pVal = (lcharv+.25lbsep)*dir (270+ang);
- aName = N;
- aVal = S;
- } else if (ang < 90) {
- pName = (lchar)*dir (90+ang);
- pVal = (lcharv)*dir (270+ang);
- aName = NW;
- aVal = SE;
- } else if (ang == 90) {
- pName = (lchar+.25lbsep)*dir (90+ang);
- pVal = (lcharv+.25lbsep)*dir (270+ang);
- aName = W;
- aVal = E;
- } else if (90 < ang && ang < 180) {
- pName = (lchar)*dir (90+ang);
- pVal = (lcharv)*dir (270+ang);
- aName = SW;
- aVal = NE;
- } else if (ang == 180) {
- pName = (lchar+.25lbsep)*dir (90+ang);
- pVal = (lcharv+.25lbsep)*dir (270+ang);
- aName = S;
- aVal = N;
- } else if (ang > 180 && ang < 270) {
- pName = (lchar)*dir (90+ang);
- pVal = (lcharv)*dir (270+ang);
- aName = SE;
- aVal = NW;
- } else if (ang == 270) {
- pName = (lchar+.25lbsep)*dir (90+ang);
- pVal = (lcharv+.25lbsep)*dir (270+ang);
- aName = E;
- aVal = W;
- } else if (270 < ang && ang < 360) {
- pName = (lchar)*dir (90+ang);
- pVal = (lcharv)*dir (270+ang);
- aName = NE;
- aVal = SW;
- }
+ void set_terminals() {
+ for (int i=0; i < this.terminal_offset.length; i+=1) {
+ this.terminal[i] = this.center +
+ rotate(this.dir)*this.terminal_offset[i];
}
- Label lName = rotate(rName)*Label(name);
- label(picL, lName, pName, aName);
- Label lVal = rotate(rVal)*Label(val);
- label(picL, lVal, pVal, aVal);
- add(pic, picL, (end-beg)/2);
+ }
+
+ void operator init(pair center=(0,0), real dir=0,
+ pair terminal[]={}, pair terminal_offset[]={},
+ Label label="", Label value="",
+ real label_offset=0, real value_offset=0,
+ path pLine[]={}, path pMisc[]={},
+ pen line=line, pen misc=misc) {
+ this.center = center;
+ this.dir = dir % 360;
+ this.terminal = terminal;
+ this.terminal_offset = terminal_offset;
+ this.set_terminals();
+ this.label = label;
+ this.value = value;
+ this.label_offset = label_offset;
+ this.value_offset = value_offset;
+ this.pLine = pLine;
+ this.pMisc = pMisc;
+ this.line = line;
+ this.misc = misc;
}
/* Shift position by a */
void shift(pair a) {
- this.beg += a;
- this.end += a;
- this.mid += a;
+ this.center += a;
+ this.set_terminals();
}
- /* Rather than placing the element with a point and direction (beg,
- * ang), center an element between the pairs a and b. The optional
+ void draw_label(picture pic=currentpicture, Label L=null, real offset=0,
+ pair default_direction=(0,0)) {
+ align a;
+ if (L == null) {
+ L = this.label;
+ }
+ a = L.align;
+ if ((L.align == NoAlign || L.align.dir == (0,0)) &&
+ default_direction != (0,0)) {
+ L.align = rotate(this.dir)*default_direction;
+ }
+ if (L.align != NoAlign && L.align != Align) {
+ real m = labelmargin(L.p);
+ real scale = (m + offset)/m;
+ if (L.align.is3D) {
+ L.align.dir3 *= scale;
+ } else {
+ L.align.dir *= scale;
+ }
+ }
+ label(pic=pic, L=L, position=this.center);
+ L.align = a;
+ }
+
+ /* Rather than placing the element with a point and direction (mid,
+ * dir), center an element between the pairs a and b. The optional
* offset shifts the element in the direction rotated(90)*(b-a)
* (i.e. up for offset > 0 if b is directly right of a).
*/
void centerto(pair a, pair b, real offset=0) {
- this.ang = degrees(b-a);
- this.beg = (a+b)/2
- - unit(b-a)*this.len/2 + offset*dir(this.ang+90);
- this.end = this.beg+rotate(ang)*(this.len,0);
- this.mid = (this.beg + this.end)/2;
+ this.dir = degrees(b-a);
+ this.center = (a+b)/2 + offset*dir(this.dir+90);
+ this.set_terminals();
}
void draw(picture pic=currentpicture) {
- picture picT;
for (int i=0; i< pLine.length; i+=1) {
- draw(picT, rotate(ang)*pLine[i], line);
- if (cyclic(pLine[i]))
- fill(picT, rotate(ang)*pLine[i], line);
+ path p = _shift_transform(this.center)*rotate(this.dir)*pLine[i];
+ if (cyclic(p))
+ filldraw(pic, p, this.line, this.line);
+ else
+ draw(pic, p, this.line);
}
for (int i=0; i< pMisc.length; i+=1) {
- draw(picT, rotate(ang)*pMisc[i], misc);
- if (cyclic(pMisc[i]))
- fill(picT, rotate(ang)*pMisc[i], misc);
+ path p = _shift_transform(this.center)*rotate(this.dir)*pMisc[i];
+ if (cyclic(p))
+ filldraw(pic, p, this.misc, this.misc);
+ else
+ draw(pic, p, this.misc);
}
- putlabel(picT);
- add(pic, picT, beg);
+ this.draw_label(pic=pic, L=this.label, offset=this.label_offset,
+ default_direction=N);
+ this.draw_label(pic=pic, L=this.value, offset=this.value_offset,
+ default_direction=S);
}
}
-void centerto(TwoTerminal reference, TwoTerminal target, real offset=0,
- bool reverse=false)
+pair _offset(pair beg=(0,0), real length=1, real dir=0) {
+ return beg + rotate(dir)*(length, 0);
+}
+
+void two_terminal_centerto(MultiTerminal reference, MultiTerminal target,
+ real offset=0, bool reverse=false)
{
if (reverse == false)
- target.centerto(reference.beg, reference.end, offset);
+ target.centerto(reference.terminal[0], reference.terminal[1], offset);
else
- target.centerto(reference.end, reference.beg, offset);
+ target.centerto(reference.terminal[1], reference.terminal[0], offset);
}
// --- Resistor (Resistencia) ---
real rstlth=2mm;
int normal=0, variable=2;
-TwoTerminal resistor(pair beg=(0,0), real ang=0, int type=normal,
- string name="", string val="", bool draw=true)
+MultiTerminal resistor(pair beg=(0,0), real dir=0, int type=normal,
+ Label label="", Label value="", bool draw=true)
{
- path pLine, pMisc[]={};
- TwoTerminal term;
-
- pLine = (0,0)--(2rstlth,0)--(2.25rstlth,.75rstlth);
+ path pLine, pLines[]={}, pMisc[]={};
+ real len = 7rstlth;
+ MultiTerminal term;
+ pair center = _offset(beg=beg, length=len/2, dir=dir);
+ pair terminal_offset[] = {
+ (-len/2, 0),
+ (len/2, 0)};
+
+ pLine = (-len/2,0)--(-1.5rstlth,0)--(-1.25rstlth,.75rstlth);
for (real i=.5; i<=2.5; i+=0.5)
- pLine = pLine--((2.25+i)*rstlth,((-1)**(2i))*.75rstlth);
- pLine = pLine -- (5rstlth,0)--(7rstlth,0);
+ pLine = pLine--((-1.25+i)*rstlth,((-1)**(2i))*.75rstlth);
+ pLine = pLine -- (1.5rstlth,0)--(len/2,0);
if (type==normal) {
; //pass
} else if (type==variable) {
ahlength=.8rstlth;
- pMisc.push((2rstlth,-rstlth)--(5.5rstlth,rstlth));
- pMisc.push(miscahead((2rstlth,-rstlth)--(5.5rstlth,rstlth)));
+ pMisc.push((-1.5rstlth,-rstlth)--(1.5rstlth,rstlth));
+ pMisc.push(miscahead((-1.5rstlth,-rstlth)--(1.5rstlth,rstlth)));
} else {
- write("Error, unrecognized resistor type ",type);
+ write("Error, unrecognized resistor type ",type);
}
- term = TwoTerminal(beg, 7rstlth, ang, .8rstlth, .8rstlth, name, val, pLine, pMisc);
+ pLines.push(pLine);
+ term = MultiTerminal(center=center, dir=dir, terminal_offset=terminal_offset,
+ label=label, value=value, label_offset=.8rstlth, value_offset=.8rstlth,
+ pLine=pLines, pMisc=pMisc);
if (draw == true)
term.draw();
return term;
real coil=2mm;
int Up=0, Down=1;
-TwoTerminal inductor(pair beg=(0,0), real ang=0, int type=Up, string name="",
- string val="", bool draw=true)
+MultiTerminal inductor(pair beg=(0,0), real dir=0, int type=Up,
+ Label label="", Label value="", bool draw=true)
{
path pLine;
- TwoTerminal term;
-
+ real len = 6coil;
+ MultiTerminal term;
+ pair center = _offset(beg=beg, length=len/2, dir=dir);
+ pair terminal_offset[] = {
+ (-len/2, 0),
+ (len/2, 0)};
+
+ pLine = (-len/2,0) -- (-2coil,0);
+
if (type==Up) {
- pLine = (0,0)--(coil,0);
- for (int i=2; i<=4; i+=1)
+ for (int i=-1; i<=2; i+=1)
pLine = pLine{N}..{S}(i*coil,0);
- pLine = pLine{N}..{S}(5coil,0)--(6coil,0);
} else if (type==Down) {
- pLine = (0,0)--(coil,0);
- for (int i=2; i<=4; i+=1)
+ for (int i=-1; i<=2; i+=1)
pLine = pLine{S}..{N}(i*coil,0);
- pLine = pLine{S}..{N}(5coil,0)--(6coil,0);
- // the original makecirc changed labelangle to ang-180
} else {
write("Error, unrecognized inductor type ",type);
}
- term = TwoTerminal(beg, 6coil, ang, coil, coil, name, val, pLine);
- // the original makecirc used .5coil for lcharv
+ pLine = pLine -- (len/2,0);
+
+ term = MultiTerminal(center=center, dir=dir, terminal_offset=terminal_offset,
+ label=label, value=value, label_offset=.8rstlth, value_offset=.8rstlth,
+ pLine=pLine);
if (draw == true)
term.draw();
return term;
real platsep=1mm;
int normal=0, electrolytic=1, variable=2, variant=3;
-TwoTerminal capacitor(pair beg=(0,0), real ang=0, int type=normal,
- string name="", string val="", bool draw=true)
+MultiTerminal capacitor(pair beg=(0,0), real dir=0, int type=normal,
+ Label label="", Label value="", bool draw=true)
{
path pLine[]={}, pMisc[]={};
- TwoTerminal term;
+ real len = 7platsep;
+ MultiTerminal term;
+ pair center = _offset(beg=beg, length=len/2, dir=dir);
+ pair terminal_offset[] = {
+ (-len/2, 0),
+ (len/2, 0)};
- pLine.push((0,0)--(3platsep,0));
- pLine.push((4platsep,0)--(7platsep,0));
+ pLine.push((-len/2,0)--(-platsep/2,0));
+ pLine.push((platsep/2,0)--(len/2,0));
if (type==normal) {
- pLine.push((3platsep,-2.5platsep)--(3platsep,2.5platsep));
- pLine.push((4platsep,-2.5platsep)--(4platsep,2.5platsep));
+ pLine.push((-platsep/2,-2.5platsep)--(-platsep/2,2.5platsep));
+ pLine.push((platsep/2,-2.5platsep)--(platsep/2,2.5platsep));
} else if (type==electrolytic) {
- pLine.push((3platsep,-1.8platsep)--(3platsep,1.8platsep));
- pLine.push((2platsep,-2.5platsep)--(4platsep,-2.5platsep)
- --(4platsep,+2.5platsep)--(2platsep,2.5platsep));
+ pLine.push((-platsep/2,-1.8platsep)--(-platsep/2,1.8platsep));
+ pLine.push((-1.5platsep,-2.5platsep)--(platsep/2,-2.5platsep)
+ --(platsep/2,+2.5platsep)--(-1.5platsep,2.5platsep));
} else if (type==variable) {
- pLine.push((3platsep,-2.5platsep)--(3platsep,2.5platsep));
- pLine.push((4platsep,-2.5platsep)--(4platsep,2.5platsep));
- pMisc.push((platsep,-2.5platsep)--(6platsep,2.5platsep));
+ pLine.push((-platsep/2,-2.5platsep)--(-platsep/2,2.5platsep));
+ pLine.push((platsep/2,-2.5platsep)--(platsep/2,2.5platsep));
+ pMisc.push((-2.5platsep,-2.5platsep)--(2.5platsep,2.5platsep));
ahlength=1.7platsep;
- pMisc.push(miscahead((platsep,-2.5platsep)--(6platsep,2.5platsep)));
+ pMisc.push(miscahead((-2.5platsep,-2.5platsep)--(2.5platsep,2.5platsep)));
} else if (type==variant) {
- pLine.push((3platsep,-2.5platsep)--(3platsep,2.5platsep));
- pLine.push((4.5platsep,-2.5platsep)..(4platsep,0)..(4.5platsep,2.5platsep));
+ pLine.push((-platsep/2,-2.5platsep)--(-platsep/2,2.5platsep));
+ pLine.push((platsep,-2.5platsep)..(platsep/2,0)..(platsep,2.5platsep));
} else {
write("Error, unrecognized capacitor type ",type);
}
- term = TwoTerminal(beg, 7platsep, ang, 2.5platsep, 2.5platsep, name, val, pLine, pMisc);
+ term = MultiTerminal(center=center, dir=dir, terminal_offset=terminal_offset,
+ label=label, value=value, label_offset=2.5platsep,
+ value_offset=2.5platsep, pLine=pLine, pMisc=pMisc);
if (draw == true)
term.draw();
return term;
// --- Diode (diodo) ---
-real diodeht=3.5mm;
+real diode_height = 3.5mm;
int zener=1, LED=2;
// I droped the pin parameters, since other device (e.g. electrolytic
// capacitors) are also polarized. The positioning method centerto(),
// provides enough flexibility.
-TwoTerminal diode(pair beg=(0,0), real ang=0, int type=normal, string name="",
- string val="", bool draw=true)
+MultiTerminal diode(pair beg=(0,0), real dir=0, int type=normal,
+ Label label="", Label value="", bool draw=true)
{
path pLine[]={}, pMisc[]={};
- real lchar, lcharv;
- TwoTerminal term;
+ real len = 3*diode_height;
+ real r = diode_height/2;
+ real label_offset, value_offset;
+ MultiTerminal term;
+ pair center = _offset(beg=beg, length=len/2, dir=dir);
+ pair terminal_offset[] = {
+ (-len/2, 0),
+ (len/2, 0)};
+
+ label_offset = value_offset = r;
+ pLine.push((-len/2,0)--(-r,0)--(-r,r)--(r,0)--(-r,-r)--(-r,0));
+ pLine.push((r,0)--(len/2,0));
- pLine.push((0,0)--(diodeht,0)--(diodeht,.5diodeht)--(2diodeht,0)--(diodeht,-.5diodeht)--(diodeht,0));
- pLine.push((2diodeht,0)--(3diodeht,0));
- lchar = 0.6diodeht; lcharv = 0.6diodeht;
-
if (type==normal) {
- pLine.push((2diodeht,-.5diodeht)--(2diodeht,.5diodeht));
+ pLine.push((r,-r)--(r,r));
} else if (type==zener) {
- pLine.push((2.5diodeht,-.5diodeht)--(2diodeht,-.5diodeht)--(2diodeht,.5diodeht)--(1.5diodeht,.5diodeht));
+ pLine.push((2r,-r)--(r,-r)--(r,r)--(0,r));
} else if (type==LED) {
- path a = (diodeht,.5diodeht)--(2diodeht,0);
- pair u = unit((.5,1)); // perpendicular to a
- path b = (0,0)--diodeht*u;
- pLine.push((2diodeht,-.5diodeht)--(2diodeht,.5diodeht));
- lchar = 1.5diodeht;
- pMisc.push(shift(point(a,reltime(a,0.25))+point(b,0.33))*((0,0)--diodeht*u));
- pMisc.push(shift(point(a,reltime(a,0.60))+point(b,0.33))*((0,0)--diodeht*u));
- pMisc.push(fullhead(pMisc[0], 0.4diodeht, 30));
- pMisc.push(fullhead(pMisc[1], 0.4diodeht, 30));
+ path a = (-r,r)--(r,0);
+ pair u = unit((0.5, 1)); // perpendicular to a
+ path b = (0,0)--diode_height*u;
+ pLine.push((r,-r)--(r,r));
+ label_offset = 1.5*diode_height;
+ pMisc.push(shift(point(a,reltime(a,0.25))+point(b,0.33))*((0,0)--diode_height*u));
+ pMisc.push(shift(point(a,reltime(a,0.60))+point(b,0.33))*((0,0)--diode_height*u));
+ pMisc.push(fullhead(pMisc[0], 0.4*diode_height, 30));
+ pMisc.push(fullhead(pMisc[1], 0.4*diode_height, 30));
} else {
- write("Error, unrecognized capacitor type ",type);
+ write("Error, unrecognized diode type ",type);
}
- term = TwoTerminal(beg, 3diodeht, ang, lchar, lcharv, name, val,pLine,pMisc);
+ term = MultiTerminal(center=center, dir=dir, terminal_offset=terminal_offset,
+ label=label, value=value, label_offset=label_offset,
+ value_offset=value_offset, pLine=pLine, pMisc=pMisc);
if (draw == true)
term.draw();
return term;
//--- Battery (bater'ia) ---
-real bsize = 6mm;
+real battery_size = 6mm;
-TwoTerminal battery(pair beg=(0,0), real ang=0, string name="", string val="",
- bool draw=true)
+MultiTerminal battery(pair beg=(0,0), real dir=0,
+ Label label="", Label value="", bool draw=true)
{
path pLine[]={}, pMisc[]={};
- real lchar, lcharv;
- TwoTerminal term;
-
- pLine.push((0,0)--(0.4bsize,0));
- pLine.push((1.4bsize,0)--(1.8bsize,0));
-
+ real len = 1.8*battery_size;
+ real r = battery_size/2;
+ real x = 0.4*battery_size;
+ real Y = 0.6*battery_size;
+ real y = 0.2*battery_size;
+ real label_offset, value_offset;
+ MultiTerminal term;
+ pair center = _offset(beg=beg, length=len/2, dir=dir);
+ pair terminal_offset[] = {
+ (-len/2, 0),
+ (len/2, 0)};
+
+ label_offset = value_offset = Y;
+ pLine.push((-len/2,0)--(-r,0));
+ pLine.push((r,0)--(len/2,0));
for (int i=0; i<3; i+=1) {
- pLine.push(((0.4+0.4i)*bsize, -0.2bsize)--((0.4+0.4i)*bsize, 0.2bsize));
- pLine.push(((0.6+0.4i)*bsize, -0.6bsize)--((0.6+0.4i)*bsize, 0.6bsize));
+ pLine.push((-r+x*i, -y)--(-r+x*i, y));
+ pLine.push((-r+x*(i+0.5), -Y)--(-r+x*(i+0.5), Y));
}
- lchar = 0.6bsize; lcharv = 0.6bsize;
-
- term = TwoTerminal(beg, 1.8bsize, ang, lchar, lcharv, name, val,pLine,pMisc);
+ term = MultiTerminal(center=center, dir=dir, terminal_offset=terminal_offset,
+ label=label, value=value, label_offset=label_offset,
+ value_offset=value_offset, pLine=pLine, pMisc=pMisc);
if (draw == true)
term.draw();
return term;
//--- Switches (Llaves) ---
-int NO=0, NC=1;
-real ssep=3mm, swt=1.2ssep; // TODO remove swt?
+int open=0, closed=1;
+real switch_size = 3mm;
+
+/* Helper function for constructing switch paths. */
+path[] _switch_lines(pair terminal_offset[], real theta)
+{
+ path pLine[] = {};
+ real r = switch_size/2;
+ real dy = switch_size/6; // little nub where the switch closes
+ pLine.push((-r,0)--((-r,0)+switch_size*dir(theta)));
+ for (int i=0; i < terminal_offset.length; i+=1) {
+ pLine.push(shift(terminal_offset[i])*scale(dy)*unitcircle);
+ }
+ return pLine;
+}
/* `switch' is a Asymptote keyword (or it should be), so append SPST
* for Single Pole Single Throw.
*/
-TwoTerminal switchSPST(pair beg=(0,0), real ang=0, int type=NO, string name="",
- string val="", bool draw=true)
+MultiTerminal switchSPST(pair beg=(0,0), real dir=0, int type=closed,
+ Label label="", Label value="", bool draw=true)
{
- path pLine[]={}, pMisc[]={};
- real lchar, lcharv;
- TwoTerminal term;
+ path pLine[] = {};
+ real theta, label_offset, value_offset;
+ MultiTerminal term;
+ pair center = _offset(beg=beg, length=switch_size/2, dir=dir);
+ pair terminal_offset[] = {
+ (-switch_size/2, 0),
+ (switch_size/2, 0)};
+
+ value_offset = 0;
+ if (type==open) {
+ theta = 35;
+ } else if (type==closed) {
+ theta = 10;
+ } else {
+ write("Error, unrecognized switchSPST type ",type);
+ }
+ pLine = _switch_lines(terminal_offset=terminal_offset, theta=theta);
+ label_offset = switch_size*Sin(theta);
+ term = MultiTerminal(center=center, dir=dir, terminal_offset=terminal_offset,
+ label=label, value=value, label_offset=label_offset,
+ value_offset=value_offset, pLine=pLine);
+ if (draw == true)
+ term.draw();
+ return term;
+}
- pLine.push((0,0)--(0.7ssep,0));
- pLine.push((1.7ssep,ssep/3)--(1.7ssep,0)--(2.4ssep,0));
- lchar = 0.6ssep; lcharv = 0.6ssep;
+int closed_a=1, closed_b=2;
- if (type==NO) {
- pLine.push((0.7ssep,0)--(1.8ssep,0.7ssep));
- } else if (type==NC) {
- pLine.push((0.7ssep,0)--(2ssep,ssep/3));
+/* A Single Pole Double Throw switch. */
+MultiTerminal switchSPDT(pair beg=(0,0), real dir=0, int type=open,
+ Label label="", Label value="", bool draw=true)
+{
+ path pLine[] = {};
+ real theta, label_offset, value_offset;
+ MultiTerminal term;
+ pair center = _offset(beg=beg, length=switch_size/2, dir=dir);
+ pair terminal_offset[] = {
+ (-switch_size/2, 0),
+ (switch_size*sqrt(3)/4, switch_size/2),
+ (switch_size*sqrt(3)/4, -switch_size/2)};
+
+ label_offset = value_offset = switch_size/2;
+ if (type==open) {
+ theta = 0;
+ } else if (type==closed_a) {
+ theta = 20;
+ } else if (type==closed_b) {
+ theta = -20;
} else {
write("Error, unrecognized switchSPST type ",type);
}
- term = TwoTerminal(beg, 2.4ssep, ang, lchar, lcharv, name, val, pLine,pMisc);
+ pLine = _switch_lines(terminal_offset=terminal_offset, theta=theta);
+ term = MultiTerminal(center=center, dir=dir, terminal_offset=terminal_offset,
+ label=label, value=value, label_offset=label_offset,
+ value_offset=value_offset, pLine=pLine);
if (draw == true)
term.draw();
return term;
//--- Current (Corriente) ---
-real isize=2mm;
+real current_size = 2mm;
-// adjusted from makecirc original to center arrowhead under text
-TwoTerminal current(pair beg=(0,0), real ang=0, string name="", string val="",
- bool draw=true)
+MultiTerminal current(pair beg=(0,0), real dir=0,
+ Label label="", Label value="", bool draw=true)
{
path pLine[]={}, pMisc[]={};
- real lchar, lcharv;
- TwoTerminal term;
- lchar = 0.4isize; lcharv = 0.4isize;
- pLine.push((0,0)--(1.5isize,0));
- pLine.push((1.5isize,0)--(2isize,0));
- pMisc.push(fullhead(pLine[0], isize, 45));
- term = TwoTerminal(beg, 2isize, ang, lchar, lcharv, name, val, pLine, pMisc);
+ real label_offset, value_offset;
+ real len = 2*current_size;
+ MultiTerminal term;
+ pair center = _offset(beg=beg, length=len/2, dir=dir);
+ pair terminal_offset[] = {
+ (-len/2, 0),
+ (len/2, 0)};
+
+ label_offset = value_offset = 0.4*current_size;
+ pLine.push((-len/2, 0) -- (current_size/2, 0));
+ pLine.push((current_size/2, 0) -- (len/2, 0));
+ pMisc.push(fullhead(pLine[0], current_size, 45));
+ term = MultiTerminal(center=center, dir=dir, terminal_offset=terminal_offset,
+ label=label, value=value, label_offset=label_offset,
+ value_offset=value_offset, pLine=pLine, pMisc=pMisc);
if (draw == true)
term.draw();
return term;
//--- Circle-based symbols (for internal use) --
-real circle_size=6mm;
+real circle_size = 6mm;
-TwoTerminal _two_terminal_circle(pair beg=(0,0), real ang=0, string name="",
- string val="")
+MultiTerminal _circle_symbol(pair beg=(0,0), real dir=0,
+ Label label="", Label value="")
{
- path pLine[]={}, pMisc[]={};
- real len, lchar, lcharv, r = circle_size/2;
- pair c = (2r,0);
- TwoTerminal term;
-
- len = 2*circle_size;
- lchar = lcharv = r;
- c = (circle_size, 0);
- pLine.push((0,0)--(r,0));
- pLine.push(shift(c)*scale(r)*(E..N..W..S..E));
- pLine.push((3r,0)--(4r,0));
- term = TwoTerminal(beg, len, ang, lchar, lcharv, name, val, pLine, pMisc);
+ path pLine[]={};
+ real label_offset, value_offset;
+ real len = 2*circle_size;
+ real r = circle_size/2;
+ MultiTerminal term;
+ pair center = _offset(beg=beg, length=r, dir=dir);
+ pair terminal_offset[] = {
+ (-len/2, 0),
+ (len/2, 0)};
+
+ label_offset = value_offset = r;
+ pLine.push((-len/2, 0) -- (-r, 0));
+ pLine.push((r, 0) -- (len/2, 0));
+ pLine.push(scale(r)*(E..N..W..S..E));
+ term = MultiTerminal(center=center, dir=dir, terminal_offset=terminal_offset,
+ label=label, value=value, label_offset=label_offset,
+ value_offset=value_offset, pLine=pLine);
return term;
}
int AC=0,DC=1,I=2,V=3;
-TwoTerminal source(pair beg=(0,0), real ang=0, int type=AC, string name="",
- string val="", bool draw=true)
+MultiTerminal source(pair beg=(0,0), real dir=0, int type=AC,
+ Label label="", Label value="", bool draw=true)
{
- TwoTerminal term;
+ MultiTerminal term;
if (type == AC || type == I || type == V) {
- real s = circle_size;
- term = _two_terminal_circle(beg=beg, ang=ang, name=name, val=val);
+ real r = circle_size/2;
+ term = _circle_symbol(beg=beg, dir=dir, label=label, value=value);
if (type == AC) {
- term.pLine.push((2s/3,0){NE}..{E}((1/3+.5)*s,.2s)..{SE}(s,0)..{E}((2/3+.5)*s,-.2s)..{NE}(4s/3,0));
+ term.pLine.push((-2r/3,0){NE}..{E}(-r/3,.4r)..{SE}(0,0)..{E}(r/3,-.4r)..{NE}(2r/3,0));
} else if (type == I) {
- term.pLine.push((2s/3,0)--(4s/3,0));
- term.pLine.push(fullhead(term.pLine[3], 4s/15, 30));
+ term.pLine.push((-2r/3,0)--(2r/3,0));
+ term.pLine.push(fullhead(term.pLine[3], 8r/15, 30));
} else if (type == V) {
- term.pLine.push((1.05s,0)--(1.45s,0));
- term.pLine.push((1.25s,-.2s)--(1.25s,.2s));
- term.pLine.push((.95s,0)--(.55s,0));
+ term.pLine.push((-0.9r,0)--(-0.1r,0));
+ term.pLine.push((0.5r,-.4r)--(0.5r,.4r));
+ term.pLine.push((0.1r,0)--(0.9r,0));
}
} else if (type == DC) {
- path pLine[] = {};
- real len, lchar, lcharv;
- len = circle_size;
- lchar = 0.6len; lcharv = .6len;
- pLine.push((0,0)--(0.4len,0));
- pLine.push((.6len,0)--(len,0));
- pLine.push((.4len,-.2len)--(.4len,.2len));
- pLine.push((.6len,-.6len)--(.6len,.6len));
- term = TwoTerminal(beg, len, ang, lchar, lcharv, name, val, pLine);
+ path pLine[]={};
+ real label_offset, value_offset;
+ real len = battery_size;
+ real x = 0.2*battery_size;
+ real Y = 0.6*battery_size;
+ real y = 0.2*battery_size;
+ pair center = _offset(beg=beg, length=len/2, dir=dir);
+ pair terminal_offset[] = {
+ (-len/2, 0),
+ (len/2, 0)};
+
+ label_offset = value_offset = Y;
+ pLine.push((-len/2,0)--(-x/2,0));
+ pLine.push((x/2,0)--(len/2,0));
+ pLine.push((-x/2, -y)--(-x/2, y));
+ pLine.push((x/2, -Y)--(x/2, Y));
+ term = MultiTerminal(center=center, dir=dir,
+ terminal_offset=terminal_offset,
+ label=label, value=value, label_offset=label_offset,
+ value_offset=value_offset, pLine=pLine);
}
if (draw == true)
term.draw();
{
path pLine;
TwoTerminal term;
-
+
if (type==Up) {
pLine = (0,0)--(coil,0);
for (int i=2; i<=4; i+=1)
int illuminating = 1;
-TwoTerminal lamp(pair beg=(0,0), real ang=0, int type=normal,
- string name="", string val="", bool draw=true)
+MultiTerminal lamp(pair beg=(0,0), real dir=0, int type=normal,
+ Label label="", Label value="", bool draw=true)
{
real r = 0.5*circle_size;
- pair c;
- TwoTerminal term;
+ MultiTerminal term;
- term = _two_terminal_circle(beg=beg, ang=ang, name=name, val=val);
- pair c = (2r, 0);
+ term = _circle_symbol(beg=beg, dir=dir, label=label, value=value);
if (type==normal) {
- term.pLine.push((c - r*dir(45)) -- (c + r*dir(45)));
- term.pLine.push((c - r*dir(-45)) -- (c + r*dir(-45)));
+ term.pLine.push(-r*dir(45) -- r*dir(45));
+ term.pLine.push(-r*dir(-45) -- r*dir(-45));
} else if (type==illuminating) {
- term.pLine.push((c - (r,0)) -- (c - (r/2,0)));
- term.pLine.push((c + (r/2,0)) -- (c + (r,0)));
- term.pLine.push(shift(c)*scale(r/2)*(E..N..W));
+ term.pLine.push((-r,0) -- (-r/2,0));
+ term.pLine.push((r/2,0) -- (r,0));
+ term.pLine.push(scale(r/2)*(E..N..W));
}
if (draw == true)
term.draw();
// Loop symbols for Kirchhoff's rules.
void kirchhoff_loop(picture pic=currentpicture, pair points[],
- pen outline=kirchhoff_pen, real aspace=-1) {
+ pen outline=kirchhoff_pen, real aspace=-1) {
// draw kirchhoff loop underneath currentpicture
picture newpic;
int i;