Add TwoTerminal.shift() and kirchhoff_loop() to Circ.asy.
[course.git] / asymptote / Circ.asy
index 42c889eaaa707aa7fc0b19aec5f7abd0189bd603..6a9c2db303ac464517470ac11de393c58d2dbb60 100644 (file)
@@ -40,8 +40,9 @@ int labeling = rotatelabel;
 
 real linewd = 0.25mm;
 
-pen line = makepen(scale(0.5*linewd)*unitcircle);
-pen misc = makepen(scale(0.4*linewd)*unitcircle);
+pen line = linewidth(linewd);
+pen misc = linewidth(0.8*linewd);
+pen kirchhoff_pen = linewidth(10*linewd)+gray(0.7);
 
 // Arrowhead definitions
 
@@ -238,6 +239,13 @@ struct TwoTerminal {
     add(pic, picL, (end-beg)/2);
   }
 
+  /* Shift position by a */
+  void shift(pair a) {
+    this.beg += a;
+    this.end += a;
+    this.mid += a;
+  }
+
   /* Rather than placing the element with a point and direction (beg,
    * ang), center an element between the pairs a and b.  The optional
    * offset shifts the element in the direction rotated(90)*(b-a)
@@ -983,3 +991,25 @@ vardef rheostat@#(expr z,type,ang)=
 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);
+}