From 311505710404f8c1af48b975dad6d51a958dcb5c Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 14 Jun 2013 07:22:53 -0400 Subject: [PATCH] figures/asy/Circ.asy: Add the circuit library from my course project For drawing a Peltier. --- src/figures/asy/Circ-test.asy | 137 +++++ src/figures/asy/Circ.asy | 1084 +++++++++++++++++++++++++++++++++ 2 files changed, 1221 insertions(+) create mode 100644 src/figures/asy/Circ-test.asy create mode 100644 src/figures/asy/Circ.asy diff --git a/src/figures/asy/Circ-test.asy b/src/figures/asy/Circ-test.asy new file mode 100644 index 0000000..b57a643 --- /dev/null +++ b/src/figures/asy/Circ-test.asy @@ -0,0 +1,137 @@ +/* Test suite for Circ.asy. + * + * Copyright (C) 2008-2012 W. Trevor King + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +import Circ; + +real u = 2cm, v=0; + +write("resistor"); +MultiTerminal Rn = resistor(beg=(0,v), dir=0, type=normal, + label=Label("$R_{normal}$", align=N), value=Label("$30\ohm$", align=S)); +dot("beg", Rn.terminal[0], NW, red); +dot("end", Rn.terminal[1], NE, red); +dot("center", Rn.center, S, red); + +MultiTerminal Rvb = resistor(beg=(2u,v), dir=0, type=variable, + label=Label("$R_{variable}$", align=NW), + value=Label("$30\kohm$", align=SE)); +v -= u; + +write("capacitor"); +MultiTerminal Cn = capacitor((0,v), type=normal, "$C_{normal}$", + "30 $\mu$F"); +MultiTerminal Ce = capacitor((u,v), type=electrolytic, "$C_{electrolytic}$", + "30 $\mu$F"); +MultiTerminal Cvb = capacitor((2u,v), type=variable, "$C_{variable}$", + "30 $\mu$F"); +MultiTerminal Cvt = capacitor((3u,v), type=variant, "$C_{variant}$", + "30 $\mu$F"); +v -= u; + +write("inductor"); +MultiTerminal Lup = inductor((0,v), type=Up, "$L_{Up}$", "30 H"); +MultiTerminal Ldown = inductor((u,v), type=Down, "$L_{Down}$", "30 H"); +v -= u; + +write("diode"); +MultiTerminal Dn = diode((0,v), type=normal, "$D_{normal}$", "1.3 V"); +MultiTerminal Dz = diode((u,v), type=zener, "$D_{zener}$", "1.3 V"); +MultiTerminal Dled = diode((2u,v), type=LED, "$D_{LED}$", "1.7 V"); +v -= u; + +write("battery"); +MultiTerminal B = battery((0,v), "Battery", "1.5 V"); +v -= u; + +write("switch"); +MultiTerminal So = switchSPST((0,v), type=open, "$S$", "Open"); +MultiTerminal Sc = switchSPST((u,v), type=closed, "$S$", "Closed"); +MultiTerminal SPDT_o = switchSPDT((2u,v), type=open, "$S$", "Open"); +MultiTerminal SPDT_a = switchSPDT((3u,v), type=closed_a, "$S$", "Closed-A"); +MultiTerminal SPDT_b = switchSPDT((4u,v), type=closed_b, "$S$", "Closed-B"); +v -= u; + +write("current"); +MultiTerminal Icurr = current((0,v), "I", "10 A"); +v -= u; + +write("source"); +MultiTerminal Sdc = source((0,v), type=DC, "DC", "5 V"); +MultiTerminal Sac = source((u,v), type=AC, "AC", "5 V$_{pp}$"); +MultiTerminal Si = source((2u,v), type=I, "I", "5 A"); +MultiTerminal Sv = source((3u,v), type=V, "V", "5 V"); +v -= u; + +write("lamp"); +MultiTerminal Ln = lamp((0,v), 0, normal, "indicator", "5\ohm"); +MultiTerminal Li = lamp((u,v), 0, illuminating, "illuminator", "5\ohm"); +v -= 1.5u; + +write("positioning"); +MultiTerminal Spos = source((u,v), dir=90, type=DC, "DC", "5 V"); +MultiTerminal Rpos = resistor(type=normal, + label=rotate(90)*Label("+offset", align=W), + value=rotate(90)*Label("5 \ohm", align=E), draw=false); +Rpos.centerto(Spos.terminal[0], Spos.terminal[1], offset=u); +Rpos.draw(); +dot("Sa", Spos.terminal[0], S); +dot("Sb", Spos.terminal[1], N); +dot("Ra", Rpos.terminal[0], S); +dot("Rb", Rpos.terminal[1], N); +MultiTerminal Cpos = capacitor(type=normal, "-2offset", "4 F",draw=false); +Cpos.centerto(Spos.terminal[0], Spos.terminal[1], offset=-2u); +Cpos.draw(); +v -= u; + +write("wires"); +dot("nsq", (0,v), N); +dot("b", (u/2,v-u/2), S); +wire((0,v), (u/2,v-u/2), nsq); +dot("udsq", (u,v), N); +dot("b", (3u/2,v-u/2), S); +wire((u,v), (3u/2,v-u/2), udsq); +dot("rlsq", (2u,v), N); +dot("b", (5u/2,v-u/2), S); +wire((2u,v), (5u/2,v-u/2), rlsq); +dot("udsq w/d", (3u,v), N); +dot("b", (7u/2,v-u/2), S); +wire((3u,v), (7u/2,v-u/2), udsq, -u/4); +dot("rlsq w/d", (4u,v), N); +dot("b", (9u/2,v-u/2), S); +wire((4u,v), (9u/2,v-u/2), rlsq, u/4); +v -= u; + +write("circuit"); +v -= u/2; // this circuit takes up more height than the previous lines. +MultiTerminal Ccirc = capacitor((0,v), dir=90); +MultiTerminal Rcirc = resistor(draw=false); +two_terminal_centerto(Ccirc, Rcirc); +Rcirc.shift((u,0)); // gratuitous use of shift, but whatever... +Rcirc.draw(); +// In the following, we assume the resistor is longer than the +// capacitor. If that is not true, you can find the corners of the +// circuit programatically and use those corners. +wire(Rcirc.terminal[1], Ccirc.terminal[1], rlsq); +wire(Rcirc.terminal[0], Ccirc.terminal[0], rlsq); +pair Pcirc[] = { + (Ccirc.terminal[0].x,Rcirc.terminal[0].y), + (Ccirc.terminal[1].x,Rcirc.terminal[1].y), + Rcirc.terminal[1], Rcirc.terminal[0]}; +kirchhoff_loop(Pcirc); +v -= u; diff --git a/src/figures/asy/Circ.asy b/src/figures/asy/Circ.asy new file mode 100644 index 0000000..9d202bb --- /dev/null +++ b/src/figures/asy/Circ.asy @@ -0,0 +1,1084 @@ +/* Useful functions for drawing circuit diagrams. + * Version 0.2 + * + * Copyright (C) 2003 GS Bustamante Argañaraz + * 2008-2012 W. Trevor King + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * + * Based on MetaPost's MakeCirc by Gustavo Sebastian Bustamante Argañaraz. + * http://www.ctan.org/tex-archive/help/Catalogue/entries/makecirc.html + */ + +// Command definitions for easier labeling + +texpreamble("\def\ohm{\ensuremath{\,\Omega}}"); +texpreamble("\def\kohm{\,k\ensuremath{\Omega}}"); +texpreamble("\def\modarg#1#2{\setbox0=\hbox{$\mkern-1mu/#2^\circ$}\dp0=.21ex $#1\underline{\box0}$}"); + +int rotatelabel = 0; +int norotatelabel = 1; +int labeling = rotatelabel; + +// Macros for the pens, I define them as such so when they expand, +// look for the last value assigned to linewd and use it +// (thanks to JLD). The linewd value assigns it as newinternal to +// be able to change it «from out». + +real linewd = 0.25mm; + +pen line = linewidth(linewd); +pen misc = linewidth(0.8*linewd); +pen kirchhoff_pen = linewidth(10*linewd)+gray(0.7); + +// Arrowhead definitions + +real ahlength = 4bp; // Arrowhead length +real ahangle = 30; // Arrowhead angle + +path miscahead (path p) +{ + real t = reltime(p, 1.0); + pair A = point(p,t); + pair u = -dir(p,t); + path a = shift(A)*((0,0)--(scale(ahlength)*rotate(15)*u)); + path b = shift(A)*((0,0)--(scale(ahlength)*rotate(-15)*u)); + return (a & reverse(a) & b & reverse(b))--cycle; +} + +path fullhead (path p, real length=ahlength, real angle=ahangle) +{ + real t = reltime(p, 1.0); + pair A = point(p,t); + pair u = -dir(p,t); + path a = shift(A)*((0,0)--(scale(length)*rotate(angle/2)*u)); + path b = shift(A)*((0,0)--(scale(length)*rotate(-angle/2)*u)); + return (A -- a -- reverse(b) --cycle); +} + +path bjtahead (path p) +{ + pair A = point(p,reltime(p,0.7)); + pair u = -dir(p,reltime(p,0.5)); + path a = shift(A)*((0,0)--(scale(ahlength)*rotate(20)*u)); + path b = shift(A)*((0,0)--(scale(ahlength)*rotate(-20)*u)); + return (a & reverse(a) & b & reverse(b))--cycle; +} + +// function to wire the symbols together + +int nsq=0, udsq=2, rlsq=3; + +void wire(pair pin_beg, pair pin_end, int type=nsq, real dist=0) +{ + if (dist == 0) { + if (type==nsq) { + draw(pin_beg--pin_end, line); + } else if (type==udsq) { + draw(pin_beg--(pin_beg.x,pin_end.y)--pin_end, line); + } else if (type==rlsq) { + draw(pin_beg--(pin_end.x,pin_beg.y)--pin_end, line); + } else { + write("Error, unrecognized wire type ",type); + } + } else { + if (type==udsq) { + draw(pin_beg--(pin_beg+(0,dist))--(pin_end.x,pin_beg.y + dist) + --pin_end, line); + } else if (type==rlsq) { + draw(pin_beg--(pin_beg+(dist,0))--(pin_beg.x + dist,pin_end.y) + --pin_end, line); + } else { + write("Error, unrecognized wire type ",type); + } + } +} + +// ----- Here the symbols begin -------- + +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[]; + pen line; + pen misc; + + 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]; + } + } + + 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.center += a; + this.set_terminals(); + } + + 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.dir = degrees(b-a); + this.center = (a+b)/2 + offset*dir(this.dir+90); + this.set_terminals(); + } + + void draw(picture pic=currentpicture) { + for (int i=0; i< pLine.length; i+=1) { + 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) { + 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); + } + 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); + } +} + +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.terminal[0], reference.terminal[1], offset); + else + target.centerto(reference.terminal[1], reference.terminal[0], offset); +} + +// --- Resistor (Resistencia) --- + +real rstlth=2mm; +int normal=0, variable=2; + +MultiTerminal resistor(pair beg=(0,0), real dir=0, int type=normal, + Label label="", Label value="", bool draw=true) +{ + 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--((-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((-1.5rstlth,-rstlth)--(1.5rstlth,rstlth)); + pMisc.push(miscahead((-1.5rstlth,-rstlth)--(1.5rstlth,rstlth))); + } else { + write("Error, unrecognized resistor type ",type); + } + 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; +} + +// --- Inductor (bobina) --- + +real coil=2mm; +int Up=0, Down=1; + +MultiTerminal inductor(pair beg=(0,0), real dir=0, int type=Up, + Label label="", Label value="", bool draw=true) +{ + path pLine; + 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) { + for (int i=-1; i<=2; i+=1) + pLine = pLine{N}..{S}(i*coil,0); + } else if (type==Down) { + for (int i=-1; i<=2; i+=1) + pLine = pLine{S}..{N}(i*coil,0); + } else { + write("Error, unrecognized inductor type ",type); + } + 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; +} + +// --- Capacitor (condensador) --- + +real platsep=1mm; +int normal=0, electrolytic=1, variable=2, variant=3; + +MultiTerminal capacitor(pair beg=(0,0), real dir=0, int type=normal, + Label label="", Label value="", bool draw=true) +{ + path pLine[]={}, pMisc[]={}; + 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((-len/2,0)--(-platsep/2,0)); + pLine.push((platsep/2,0)--(len/2,0)); + + if (type==normal) { + 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((-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((-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((-2.5platsep,-2.5platsep)--(2.5platsep,2.5platsep))); + } else if (type==variant) { + 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 = 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 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. + +MultiTerminal diode(pair beg=(0,0), real dir=0, int type=normal, + Label label="", Label value="", bool draw=true) +{ + path pLine[]={}, pMisc[]={}; + 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)); + + if (type==normal) { + pLine.push((r,-r)--(r,r)); + } else if (type==zener) { + pLine.push((2r,-r)--(r,-r)--(r,r)--(0,r)); + } else if (type==LED) { + 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 diode type ",type); + } + 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 battery_size = 6mm; + +MultiTerminal battery(pair beg=(0,0), real dir=0, + Label label="", Label value="", bool draw=true) +{ + path pLine[]={}, pMisc[]={}; + 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((-r+x*i, -y)--(-r+x*i, y)); + pLine.push((-r+x*(i+0.5), -Y)--(-r+x*(i+0.5), 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, pMisc=pMisc); + if (draw == true) + term.draw(); + return term; +} + +//--- Switches (Llaves) --- + +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. + */ +MultiTerminal switchSPST(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/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; +} + +int closed_a=1, closed_b=2; + +/* 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); + } + 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 current_size = 2mm; + +MultiTerminal current(pair beg=(0,0), real dir=0, + Label label="", Label value="", bool draw=true) +{ + path 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; + +MultiTerminal _circle_symbol(pair beg=(0,0), real dir=0, + Label label="", Label value="") +{ + 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; +} + +//--- Sources (fuentes de alimentaci'on) --- + +int AC=0,DC=1,I=2,V=3; + +MultiTerminal source(pair beg=(0,0), real dir=0, int type=AC, + Label label="", Label value="", bool draw=true) +{ + MultiTerminal term; + + if (type == AC || type == I || type == V) { + real r = circle_size/2; + term = _circle_symbol(beg=beg, dir=dir, label=label, value=value); + if (type == AC) { + 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((-2r/3,0)--(2r/3,0)); + term.pLine.push(fullhead(term.pLine[3], 8r/15, 30)); + } else if (type == V) { + 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 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(); + return term; +} + +/* + +//%%<--- Transistor --->%%% +newinternal npn, pnp, cnpn, cpnp, bjtlth; +npn=1; pnp=-1; cnpn=0; cpnp=2; bjtlth=7mm; + +vardef transistor@#(expr z,type,ang)= + save BJT; + pair T@#.B,T@#.E,T@#.C; % pines: Base, Emisor, Colector % + T@#.B=z; + T@#.E=(z+(bjtlth,-.75bjtlth)) rotatedaround(z,ang); + T@#.C=(z+(bjtlth,.75bjtlth)) rotatedaround(z,ang); + picture BJT; + BJT=nullpicture; + + addto BJT doublepath z--(z+(.5bjtlth,0)) withpen line; + addto BJT doublepath (z+(.5bjtlth,-.5bjtlth))--(z+(.5bjtlth,.5bjtlth)) withpen line; + addto BJT doublepath (z+(.5bjtlth,.2bjtlth))--(z+(bjtlth,.5bjtlth)) + --(z+(bjtlth,.75bjtlth)) withpen line; + + if type=npn: + addto BJT doublepath (z+(.5bjtlth,-.2bjtlth))--(z+(bjtlth,-.5bjtlth)) + --(z+(bjtlth,-.75bjtlth)) withpen line; + addto BJT contour bjtahead (z+(.5bjtlth,-.2bjtlth)) + --(z+(bjtlth,-.5bjtlth)) withpen line; + elseif type=cnpn: + addto BJT doublepath (z+(.5bjtlth,-.2bjtlth))--(z+(bjtlth,-.5bjtlth)) + --(z+(bjtlth,-.75bjtlth)) withpen line; + addto BJT contour bjtahead (z+(.5bjtlth,-.2bjtlth)) + --(z+(bjtlth,-.5bjtlth)) withpen line; + addto BJT doublepath fullcircle scaled 1.3bjtlth shifted (z+(.65bjtlth,0)) + withpen line; + elseif type=pnp: + addto BJT doublepath (z+(bjtlth,-.75bjtlth))--(z+(bjtlth,-.5bjtlth)) + --(z+(.5bjtlth,-.2bjtlth)) withpen line; + addto BJT contour bjtahead (z+(bjtlth,-.5bjtlth)) + --(z+(.5bjtlth,-.2bjtlth)) withpen line; + elseif type=cpnp: + addto BJT doublepath (z+(bjtlth,-.75bjtlth))--(z+(bjtlth,-.5bjtlth)) + --(z+(.5bjtlth,-.2bjtlth)) withpen line; + addto BJT contour bjtahead (z+(bjtlth,-.5bjtlth)) + --(z+(.5bjtlth,-.2bjtlth)) withpen line; + addto BJT doublepath fullcircle scaled 1.3bjtlth shifted (z+(.65bjtlth,0)) withpen line; + fi; + + draw BJT rotatedaround(z,ang); +enddef; + +//%%<--- Measurement instruments (Intrumentos de medicion)--->%%% +newinternal volt, ampere, watt; +volt=0; ampere=1; watt=2; + +vardef meains@#(expr z,type,ang,name)= + save meter; + pair mi@#.l, mi@#.r, mi@#.p; % pines % + mi@#.l=z; mi@#.r=(z+(2ssize,0)) rotatedaround(z,ang); + + picture meter; meter=nullpicture; + addto meter doublepath z--(z+(.5ssize,0)); + addto meter doublepath (z+(1.5ssize,0))--(z+(2ssize,0)); + if (type=volt) || (type=ampere): + addto meter doublepath fullcircle scaled ssize shifted (z+(ssize,0)); + if type=volt: + addto meter also thelabel(latex("\textsf{V}") scaled (ssize/6mm) + rotated (-ang), (z+(ssize,0))); + elseif type=ampere: + addto meter also thelabel(latex("\textsf{A}") scaled (ssize/6mm) + rotated (-ang), (z+(ssize,0))); + fi; + elseif (type=watt): + mi@#.p=(z+(ssize,-ssize)) rotatedaround(z,ang); + addto meter doublepath (z+(.5ssize,-.5ssize))--(z+(.5ssize,.5ssize)) + --(z+(1.5ssize,.5ssize))--(z+(1.5ssize,-.5ssize))--cycle; + addto meter doublepath (z+(ssize,-.5ssize))--(z+(ssize,-ssize)); + addto meter also thelabel(latex("\textsf{W}") scaled (ssize/6mm) + rotated (-ang), (z+(ssize,0))); + fi; + + draw meter rotatedaround(z,ang) withpen line; + + if labeling=rotatelabel: + if ((ang > (-90)) && (ang <= 90)) || ((ang > 270) && (ang <= 450)): + label(latex(name) rotatedaround (.5[mi@#.l,mi@#.r],ang), + (.5ssize+lbsep)*dir (90+ang) shifted .5[mi@#.l,mi@#.r]); + elseif ((ang > 90) && (ang <= 270)) || ((ang > (-270)) && (ang <= (-90))): + label(latex(name) rotatedaround (.5[mi@#.l,mi@#.r],180+ang), + (.5ssize+lbsep)*dir (90+ang) shifted .5[mi@#.l,mi@#.r]); + fi; + elseif labeling=norotatelabel: + if (ang = 0): + label.top(latex(name), (.5ssize+.25lbsep)*dir (90+ang) + shifted .5[mi@#.l,mi@#.r]); + elseif (ang > 0) && (ang < 90): + label.ulft(latex(name), (.5ssize)*dir (90+ang) + shifted .5[mi@#.l,mi@#.r]); + elseif (ang = 90): + label.lft(latex(name),(.5ssize+.25lbsep)*dir (90+ang) + shifted .5[mi@#.l,mi@#.r]); + elseif (90 < ang) && (ang < 180): + label.llft(latex(name),(.5ssize)*dir (90+ang) + shifted .5[mi@#.l,mi@#.r]); + elseif (ang = 180) || (ang = (-180)): + label.bot(latex(name), (.5ssize+.25lbsep)*dir (90+ang) + shifted .5[mi@#.l,mi@#.r]); + elseif ((ang > 180) && (ang < 270)) || ((ang > (-180)) && (ang < (-90))): + label.lrt(latex(name),(.5ssize)*dir (90+ang) + shifted .5[mi@#.l,mi@#.r]); + elseif (ang = 270) || (ang = (-90)): + label.rt(latex(name), (.5ssize+.25lbsep)*dir (90+ang) + shifted .5[mi@#.l,mi@#.r]); + elseif ((270 < ang) && (ang < 360)) || ((ang < 0) && (ang > (-90))): + label.urt(latex(name),(.5ssize)*dir (90+ang) + shifted .5[mi@#.l,mi@#.r]); + fi; + fi; +enddef; + +// --- Electrical machines (maquinas electricas) --- + +TwoTerminal motor(pair beg, real ang, string name, string val) +{ + path pLine; + TwoTerminal term; + + if (type==Up) { + pLine = (0,0)--(coil,0); + for (int i=2; i<=4; 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) + pLine = pLine{S}..{N}(i*coil,0); + pLine = pLine{S}..{N}(5coil,0)--(6coil,0); + // original makecirc changed labelangle to ang-180 + } + term = TwoTerminal(beg, 6coil, ang, coil, coil, name, val, pLine); + // original makecirc used .5coil for lcharv + term.draw(); + return term; +} + M@#.D=z; M@#.B=(z+(2ssize,0)) rotatedaround(z,ang); + picture mot; mot=nullpicture; + + addto mot doublepath z--(z+(.4ssize,0)); + addto mot doublepath (z+(1.6ssize,0))--(z+(2ssize,0)); + addto mot doublepath fullcircle scaled ssize shifted (z+(ssize,0)); + addto mot also thelabel(latex("\textsf{M}") scaled (ssize/6mm) + rotated (-ang), (z+(ssize,0))); + + path p,q,r,s,ca,cb,c,hc; + p=(z+(.6ssize,.075ssize))--(z+(.4ssize,.075ssize)); + q=(z+(.4ssize,.075ssize))--(z+(.4ssize,-.075ssize)); + ca=(z+(.4ssize,-.075ssize))--(z+(.6ssize,-.075ssize)); + + + r=(z+(1.4ssize,.075ssize))--(z+(1.6ssize,.075ssize)); + s=(z+(1.6ssize,.075ssize))--(z+(1.6ssize,-.075ssize)); + cb=(z+(1.6ssize,-.075ssize))--(z+(1.4ssize,-.075ssize)); + + c=fullcircle scaled ssize shifted (z+(ssize,0)); + hc=halfcircle scaled ssize rotated 270 shifted (z+(ssize,0)); + + addto mot contour buildcycle(p,q,ca,c); + addto mot doublepath buildcycle(p,q,ca,c); + + addto mot contour buildcycle(cb,s,r,hc); + addto mot doublepath buildcycle(cb,s,r,hc); + + draw mot rotatedaround(z,ang) withpen line; + + putlabel(M@#.D,M@#.B,.5ssize,.5ssize,ang,name,val); +enddef; + +vardef generator@#(expr z,ang,name,val)= + save gen; + pair G@#.D, G@#.B; % pines % + G@#.D=z; G@#.B=(z+(2ssize,0)) rotatedaround(z,ang); + picture gen; gen=nullpicture; + + addto gen doublepath z--(z+(.5ssize,0)); + addto gen doublepath (z+(1.5ssize,0))--(z+(2ssize,0)); + addto gen doublepath fullcircle scaled ssize shifted (z+(ssize,0)); + addto gen also thelabel(latex("\textsf{G}") scaled (ssize/6mm) + rotated (-ang), (z+(ssize,0))); + + draw gen rotatedaround(z,ang) withpen line; + + putlabel(G@#.D,G@#.B,.5ssize,.5ssize,ang,name,val); +enddef; + +newinternal mid, Fe, auto; +mid=1; Fe=2; auto=3; + +vardef transformer@#(expr z,type,ang)= + save trafo; + pair tf@#.pi, tf@#.ps, tf@#.si, tf@#.ss, tf@#.m; + tf@#.pi=z; tf@#.ps=(z+(0,8coil)) rotatedaround(z,ang); + tf@#.si=(z+(2.4coil,0)) rotatedaround(z,ang); + tf@#.ss=(z+(2.4coil,8coil)) rotatedaround(z,ang); + tf@#.m=(z+(3.4coil,4coil)) rotatedaround(z,ang); + + picture trafo; trafo=nullpicture; + + if type=normal: + tf@#.pi=z; tf@#.ps=(z+(0,8coil)) rotatedaround(z,ang); + tf@#.si=(z+(2.4coil,0)) rotatedaround(z,ang); + tf@#.ss=(z+(2.4coil,8coil)) rotatedaround(z,ang); + addto trafo doublepath z--(z+(0,coil)){right}.. + for i=2 upto 6: {left}(z+(0,i*coil)){right}.. endfor + {left}(z+(0,7coil))--(z+(0,8coil)); + addto trafo doublepath (z+(coil,coil))--(z+(coil,7coil)); + addto trafo doublepath (z+(1.4coil,coil))--(z+(1.4coil,7coil)); + addto trafo doublepath (z+(2.4coil,0))--(z+(2.4coil,coil)){left}.. + for i=2 upto 6: {right}(z+(2.4coil,i*coil)){left}.. endfor + {right}(z+(2.4coil,7coil))--(z+(2.4coil,8coil)); + elseif type=mid: + tf@#.pi=z; tf@#.ps=(z+(0,8coil)) rotatedaround(z,ang); + tf@#.si=(z+(2.4coil,0)) rotatedaround(z,ang); + tf@#.ss=(z+(2.4coil,8coil)) rotatedaround(z,ang); + tf@#.m=(z+(3.4coil,4coil)) rotatedaround(z,ang); + addto trafo doublepath z--(z+(0,coil)){right}.. + for i=2 upto 6: {left}(z+(0,i*coil)){right}.. endfor + {left}(z+(0,7coil))--(z+(0,8coil)); + addto trafo doublepath (z+(coil,coil))--(z+(coil,7coil)); + addto trafo doublepath (z+(1.4coil,coil))--(z+(1.4coil,7coil)); + addto trafo doublepath (z+(2.4coil,0))--(z+(2.4coil,coil)){left}.. + for i=2 upto 6: {right}(z+(2.4coil,i*coil)){left}.. endfor + {right}(z+(2.4coil,7coil))--(z+(2.4coil,8coil)); + addto trafo doublepath (z+(2.4coil,4coil))--(z+(3.4coil,4coil)); + elseif type=Fe: + tf@#.pi=z rotatedaround(z,ang); tf@#.ps=(z+(0,5.3coil)) rotatedaround(z,ang); + tf@#.si=(z+(14coil,0)) rotatedaround(z,ang); + tf@#.ss=(z+(14coil,5.228coil)) rotatedaround(z,ang); + addto trafo doublepath z+(2coil,-2.5coil)--z+(12coil,-2.5coil) + --z+(12coil,7.5coil)--z+(2coil,7.5coil)--cycle; + addto trafo doublepath z+(4coil,-.5coil)--z+(10coil,-.5coil) + --z+(10coil,5.5coil)--z+(4coil,5.5coil)--cycle; + addto trafo doublepath z--z+(2coil,0)--z+(4coil,0.728coil) + {right}..{left}z+(4coil,1.3*coil); + for i=1 upto 4: + addto trafo doublepath z+(2coil,(i+.5)*coil){left}.. + {right}z+(2coil,i*coil)--z+(4coil,(i+0.728)*coil) + {right}..{left}z+(4coil,(i+1.3)*coil); + endfor; + addto trafo doublepath z+(2coil,5.3coil)--z+(0,5.3coil); + for i=0 upto 3: + addto trafo doublepath z+(10coil,i*coil){left}.. + {right}z+(10coil,(i+.5)*coil)--z+(12coil,(i+.5+0.728)*coil) + {right}..{left}z+(12coil,(i+.656)*coil); + endfor; + addto trafo doublepath z+(10coil,4coil){left}..{right} + z+(10coil,4.5coil)--z+(12coil,5.228coil)--z+(14coil,5.228coil); + addto trafo doublepath z+(12coil,0)--z+(14coil,0); + elseif type=auto: + tf@#.pi=z rotatedaround(z,ang); tf@#.ps=(z+(0,4coil)) rotatedaround(z,ang); + tf@#.si=(z+(4coil,-6coil)) rotatedaround(z,ang); + tf@#.ss=(z+(4coil,4coil)) rotatedaround(z,ang); + addto trafo doublepath z--z+(2coil,0); + addto trafo doublepath z+(2coil,-6coil)--z+(2coil,-5coil){right}.. + for i=2 upto 10: {left}(z+(2coil,(i-6)*coil)){right}.. endfor + {left}(z+(2coil,5coil))--z+(2coil,6coil)--z+(0,6coil); + addto trafo doublepath z+(2coil,6coil)--z+(4coil,6coil); + addto trafo doublepath z+(2coil,-6coil)--z+(4coil,-6coil); + fi; + + draw trafo rotatedaround(z,ang) withpen line; +enddef; + +//%%<--- Miscellaneous symbols --->%%% + +newinternal gndlth, implth, simple, shield; +gndlth=5mm; implth=7mm; simple=1; shield=2; + +vardef ground@#(expr z,type,ang)= + save GND; + pair gnd@#; % unico pin % + gnd@#=z; + picture GND; GND=nullpicture; + addto GND doublepath z--(z+(0,-.5gndlth)) withpen line; + if type=shield: + addto GND doublepath (z+(-.5gndlth,-.5gndlth))--(z+(.5gndlth,-.5gndlth)) withpen line; + addto GND doublepath (z+(-.35gndlth,-.6gndlth))--(z+(.35gndlth,-.6gndlth)) withpen line; + addto GND doublepath (z+(-.2gndlth,-.7gndlth))--(z+(.2gndlth,-.7gndlth)) withpen line; + elseif type=simple: + addto GND doublepath (z+(-.5gndlth,-.5gndlth))--(z+(.5gndlth,-.5gndlth)) + withpen pencircle scaled 2linewd; + fi; + draw GND rotatedaround(z,ang); +enddef; + +newinternal junctiondiam; +junctiondiam=1.25mm; + +vardef junction@#(expr z,name)(suffix $)= + pair J@#; J@#=z; + draw z withpen pencircle scaled junctiondiam; + label.$(latex(name),z); +enddef; + +vardef impedance@#(expr z,ang,name,val)= + save imp; + pair Z@#.l, Z@#.r; % pines % + Z@#.l=z; + Z@#.r=(z+(1.5implth,0)) rotatedaround(z,ang); + picture imp; imp=nullpicture; + + addto imp doublepath z--(z+(.25implth,0)); + addto imp doublepath (z+(.25implth,-.18implth))--(z+(.25implth,.18implth)) + --(z+(1.25implth,.18implth))--(z+(1.25implth,-.18implth))--cycle; + addto imp doublepath (z+(1.25implth,0))--(z+(1.5implth,0)); + + draw imp rotatedaround(z,ang) withpen line; + + putlabel(Z@#.l,Z@#.r,.2implth,.2implth,ang,name,val); +enddef; + +*/ + +int illuminating = 1; + +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; + MultiTerminal term; + + term = _circle_symbol(beg=beg, dir=dir, label=label, value=value); + if (type==normal) { + 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((-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(); + return term; +} + +/* + +//%%<--- Mesh current (corriente de malla) --->%%% + +newinternal cw, ccw; +cw=0; ccw=1; + +def imesh(expr c,wd,ht,dire,ang,name)= + save im,r; picture im; numeric r; + ahlength=3platsep; ahangle=20; + if ht > wd: r=.2wd elseif ht < wd: r=.2ht fi; + im=nullpicture; + if dire=cw: + addto im doublepath (xpart c - .5wd, ypart c - .5ht) + --(xpart c - .5wd, ypart c + .5ht-r){up} + ..{right}(xpart c - .5wd + r, ypart c + .5ht) + --(xpart c + .5wd - r, ypart c + .5ht){right} + ..{down}(xpart c + .5wd,ypart c + .5ht - r) + --(xpart c + .5wd,ypart c - .5ht + r){down} + ..{left}(xpart c + .5wd - r,ypart c - .5ht) + --(xpart c - .25wd, ypart c - .5ht); + addto im contour arrowhead (xpart c - .5wd, ypart c - .5ht) + --(xpart c - .5wd, ypart c + .5ht-r){up} + ..{right}(xpart c - .5wd + r, ypart c + .5ht) + --(xpart c + .5wd - r, ypart c + .5ht){right} + ..{down}(xpart c + .5wd,ypart c + .5ht - r) + --(xpart c + .5wd,ypart c - .5ht + r){down} + ..{left}(xpart c + .5wd - r,ypart c - .5ht) + --(xpart c - .25wd, ypart c - .5ht); + elseif dire=ccw: + addto im doublepath (xpart c + .5wd, ypart c - .5ht) + --(xpart c + .5wd, ypart c + .5ht-r){up} + ..{left}(xpart c + .5wd - r, ypart c + .5ht) + --(xpart c - .5wd + r, ypart c + .5ht){left} + ..{down}(xpart c - .5wd,ypart c + .5ht - r) + --(xpart c - .5wd,ypart c - .5ht + r){down} + ..{right}(xpart c - .5wd + r,ypart c - .5ht) + --(xpart c + .25wd, ypart c - .5ht); + addto im contour arrowhead (xpart c + .5wd, ypart c - .5ht) + --(xpart c + .5wd, ypart c + .5ht-r){up} + ..{left}(xpart c + .5wd - r, ypart c + .5ht) + --(xpart c - .5wd + r, ypart c + .5ht){left} + ..{down}(xpart c + .5wd,ypart c + .5ht - r) + --(xpart c - .5wd,ypart c - .5ht + r){down} + ..{right}(xpart c - .5wd + r,ypart c - .5ht) + --(xpart c + .25wd, ypart c - .5ht); + fi; + + if labeling=rotatelabel: + addto im also thelabel(latex("$" & name & "$"),c); + elseif labeling=norotatelabel: + addto im also thelabel(latex("$" & name & "$") rotatedaround(c,-ang),c); + fi; + + draw im rotatedaround (c,ang) withpen line; +enddef; + +//%%<--- Reostatos --->%%% + +newinternal rheolth, Rrheo, Lrheo; +rheolth=2mm; Rrheo=1; Lrheo=2; + +vardef rheostat@#(expr z,type,ang)= + save reo; picture reo; reo=nullpicture; + pair rh@#.i, rh@#.s, rh@#.r; + rh@#.i=z; rh@#.s=(z+(0,6rheolth)) rotatedaround(z,ang); + rh@#.r=(z+(3rheolth,6rheolth)) rotatedaround(z,ang); + + ahangle=20; ahlength=rheolth; + + if type=Lrheo: + addto reo doublepath (z+(6rheolth,-3rheolth))--(z+(4rheolth,-3rheolth)) + --(z+(4rheolth,-.7rheolth)); + addto reo contour arrowhead (z+(6rheolth,-3rheolth))--(z+(4rheolth,-3rheolth)) + --(z+(4rheolth,-.9rheolth)); + + addto reo doublepath z--(z+(rheolth,0)){down}.. for i=2 upto 4: + {up}(z+(i*rheolth,0)){down}.. endfor {up}(z+(5rheolth,0))--(z+(6rheolth,0)); + + reo=reo rotatedaround(z,90); + elseif type=Rrheo: + addto reo doublepath (z+(6rheolth,-3rheolth))--(z+(4rheolth,-3rheolth)) + --(z+(4rheolth,-.7rheolth)); + addto reo contour arrowhead (z+(6rheolth,-3rheolth))--(z+(4rheolth,-3rheolth)) + --(z+(4rheolth,-.9rheolth)); + + addto reo doublepath z--(z+(1.5rheolth,0))--(z+(1.75rheolth,.75rheolth))-- + for i=.5 step .5 until 2.5: (z+((1.75+i)*rheolth,((-1)**(2i))*.75rheolth))-- + endfor (z+(4.5rheolth,0))--(z+(6rheolth,0)) withpen line; + + reo=reo rotatedaround(z,90); + fi; + draw reo rotatedaround(z,ang) withpen line; +enddef; + +*/ + +// Loop symbols for Kirchhoff's rules. + +void kirchhoff_loop(picture pic=currentpicture, pair points[], + pen outline=kirchhoff_pen, real aspace=-1) { + // draw kirchhoff loop underneath currentpicture + picture newpic; + int i; + guide g; + pair a = points[0] - points[points.length-1]; // arrow distance + if (aspace < 0) + aspace = 3*linewidth(outline); // one dot diameter + real alength = max(0.5*length(a), length(a) - aspace - linewidth(outline)/2); + a = alength*unit(a); + pair astop = points[points.length-1] + a; + dot(newpic, points[0], scale(3)*outline); + for (int i=0; i < points.length; ++i) + g = g--points[i]; + g = g -- astop; + draw(newpic, g, outline, Arrow(size=3*linewidth(outline))); + add(pic, newpic, above=false); +} -- 2.26.2