Add Ring structure to Mechanics.asy.
authorW. Trevor King <wking@drexel.edu>
Thu, 12 Apr 2012 00:26:58 +0000 (20:26 -0400)
committerW. Trevor King <wking@drexel.edu>
Thu, 12 Apr 2012 00:28:30 +0000 (20:28 -0400)
Also pull path labeling out into label_path().

asymptote/Makefile
asymptote/Mechanics-test.asy
asymptote/Mechanics.asy

index bd9c7da44f9b44b7c1b2d1c2a60bb7780d634c71..bd7bba4b78ed100d85e923398a1ed0490ed2b205 100644 (file)
@@ -17,6 +17,7 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 MODULES = Circ ElectroMag Mechanics stickfigure
+ASY = asy -noprc -render=0
 
 all : svgs pdfs pngs
 
@@ -35,10 +36,10 @@ clean :
        xpdf $< &
 
 %-test.svg : %-test.asy $(MODULES:%=%.asy)
-       asy -f svg $<
+       $(ASY) -f svg $<
 
 %-test.pdf : %-test.asy $(MODULES:%=%.asy)
-       asy -f pdf $<
+       $(ASY) -f pdf $<
 
 %-test.png : %-test.asy $(MODULES:%=%.asy)
-       asy -f png $<
+       $(ASY) -f png $<
index 7dd126496b35e42e3b304372741514fb06b96b87..105ce5f3b5027890b0b0076dd40b8e6a2a6c9c20 100644 (file)
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+import three;
 import Mechanics;
 
+currentprojection = TopView;
+
 real u = 1cm;
 
 LabeledCircle lc = LabeledCircle(center=(-2u, 1u));
@@ -107,6 +110,12 @@ Vector v4 = v1 - v2;
 v4.label = Label("$v_4 = v_1 - v_2$", align=S, position=EndPoint);
 v4.draw();
 
+Ring rg = Ring(
+    (0, -9u, 0), normal=(1, 1, 1), radius=5mm, axis_pre=5mm, axis_post=5mm,
+    outline=red, fill=blue, axis=black, L="ring",
+    axis_label=Label("$x$", position=EndPoint, align=RightSide));
+rg.draw();
+
 Vector v = Velocity();
 pair vfc = (5u,0);  // vector field center
 real vfwidth = 2u;
index a98bcd276a423f884ca5da3a07d0d3bb463224a4..d974c02a10462d8219c3dcc73d8d2687eb1486e4 100644 (file)
  */
 
 import geometry;
+import three;
 
 // ----------------- Labeled circle --------------------
 
+void label_path(picture pic=currentpicture, Label L, path g, real margin=0,
+                pair rdir=0) {
+  align a = L.align;
+  embed e = L.embed;
+  real m = labelmargin(L.p);
+  real scale = (m + margin)/m;
+  if (L.align.is3D) {
+    L.align.dir3 *= scale;
+  } else {
+    L.align.dir *= scale;
+  }
+  if (L.embed == Rotate) {
+    L.embed = Rotate(rdir);
+  }
+  label(pic=pic, L=L, g=g);
+  L.align = a;
+  L.embed = e;
+}
+
+void label_path(picture pic=currentpicture, Label L, path3 g, real margin=0,
+                pair rdir=0) {
+  align a = L.align;
+  embed e = L.embed;
+  real m = labelmargin(L.p);
+  real scale = (m + margin)/m;
+  if (L.align.is3D) {
+    L.align.dir3 *= scale;
+  } else {
+    L.align.dir *= scale;
+  }
+  if (L.embed == Rotate) {
+    L.embed = Rotate(rdir);
+  }
+  label(pic=pic, L=L, g=g);
+  L.align = a;
+  L.embed = e;
+}
+
 struct LabeledCircle {
   pair center;
   real radius;
@@ -159,7 +198,6 @@ struct Vector {
   }
 
   void draw(picture pic=currentpicture) {
-    picture picF;
     pair p = this.dTip();
     path P;
     real phi_e = this.phi % 360; // effective phi
@@ -167,23 +205,24 @@ struct Vector {
     if (Tan(phi_e) == 0 || abs(1.0/Tan(phi_e)) > this.out_of_plane_tolerance) {
       // draw arrow in the plane of the drawing
       // TODO: thickening for phi?
-      P = (0,0)--p;
-      draw(picF, P, outline, Arrow);
+      P = shift(this.center)*((0,0)--p);
+      draw(pic, P, this.outline, Arrow);
     } else if (phi_e > 0 && phi_e < 180) {
       // draw a circled dot for out-of-the-page
-      P = scale(this.out_of_plane_radius)*unitcircle;
-      draw(picF, P, outline);
-      dot(picF, (0,0), outline);
+      P = shift(this.center)*scale(this.out_of_plane_radius)*unitcircle;
+      draw(pic, P, outline);
+      dot(pic, this.center, this.outline);
     } else {
       // draw a circled cross for into-the-page
       real a = 0.8*sqrt(2.0)/2.0;
-      P = scale(this.out_of_plane_radius)*unitcircle;
-      draw(picF, P, outline);
-      draw(picF, scale(this.out_of_plane_radius)*((-a,-a)--(a,a)), outline);
-      draw(picF, scale(this.out_of_plane_radius)*((-a,a)--(a,-a)), outline);
+      P = shift(this.center)*scale(this.out_of_plane_radius)*unitcircle;
+      draw(pic, P, this.outline);
+      draw(pic, shift(this.center)*scale(this.out_of_plane_radius
+                                         )*((-a,-a)--(a,a)), this.outline);
+      draw(pic, shift(this.center)*scale(this.out_of_plane_radius
+                                         )*((-a,a)--(a,-a)), this.outline);
     }
-    label(pic=picF, L=this.label, g=P);
-    add(pic, picF, center);
+    label_path(pic=pic, L=this.label, g=P);
   }
 }
 
@@ -336,12 +375,7 @@ struct Distance {
     pair o = this.offset*unit(rotate(-90)*(this.pTo - this.pFrom));
     path p = (this.pFrom+o) -- (this.pTo+o);
     draw(pic, p, outline, Arrows);
-    embed e = this.label.embed;
-    if (this.label.embed == Rotate) {
-      this.label.embed = Rotate(this.pTo - this.pFrom);
-    }
-    label(pic=pic, L=this.label, g=p);
-    this.label.embed = e;
+    label_path(pic=pic, L=this.label, g=p, rdir=this.pTo - this.pFrom);
   }
 }
 
@@ -365,7 +399,6 @@ struct Angle {
   }
 
   void draw(picture pic=currentpicture) {
-    picture picF;
     bool direction;
 
     real ccw_angle = degrees(C-A)-degrees(B-A);
@@ -375,17 +408,16 @@ struct Angle {
       direction = CW;
     if (radius < 0)
       direction = !direction;
-    path p = arc((0,0), fabs(radius), degrees(B-A), degrees(C-A), direction);
+    path p = arc(this.A, fabs(radius), degrees(B-A), degrees(C-A), direction);
     if (this.fill != invisible) {
-      path pcycle = (0,0) -- p -- cycle;
-      fill(picF, pcycle, this.fill);
+      path pcycle = this.A -- p -- cycle;
+      fill(pic, pcycle, this.fill);
     }
-    draw(picF, p, this.outline);
+    draw(pic, p, this.outline);
     if (direction == CW) {
       p = reverse(p);
     }
-    label(pic=picF, L=this.label, g=p);
-    add(pic, picF, A);
+    label_path(pic=pic, L=this.label, g=p);
   }
 }
 
@@ -432,12 +464,7 @@ struct Wire {
   void draw(picture pic=currentpicture) {
     path p = this.pFrom--this.pTo;
     draw(pic, p, outline);
-    embed e = this.label.embed;
-    if (this.label.embed == Rotate) {
-      this.label.embed = Rotate(this.pTo - this.pFrom);
-    }
-    label(pic=pic, L=this.label, g=p);
-    this.label.embed = e;
+    label_path(pic=pic, L=this.label, g=p, rdir=this.pTo - this.pFrom);
   }
 }
 
@@ -469,13 +496,8 @@ struct Surface {
         pic=pic, g=p, pena=filla, a=this.pFrom,
         penb=fillb, b=this.pFrom+pDepth);
     draw(pic, p, outline);
-    embed e = this.label.embed;
-    if (this.label.embed == Rotate) {
-      this.label.embed = Rotate(this.pTo - this.pFrom);
-    }
-    label(pic=pic, L=this.label,
-        g=(this.pFrom+pDepth/2) -- (this.pTo+pDepth/2));
-    this.label.embed = e;
+    label_path(pic=pic, L=this.label,
+        g=shift(pDepth/2)*(this.pFrom -- this.pTo), rdir=this.pTo - this.pFrom);
   }
 }
 
@@ -525,21 +547,8 @@ struct Spring {
     p = p--(loopStart+(deadLength,0));
     p = shift(this.pFrom)*rotate(degrees(pDiff)) * p;
     draw(pic, p, outline);
-    align a = this.label.align;
-    embed e = this.label.embed;
-    real m = labelmargin(this.label.p);
-    real scale = (m + this.width/2)/m;
-    if (this.label.align.is3D) {
-      this.label.align.dir3 *= scale;
-    } else {
-      this.label.align.dir *= scale;
-    }
-    if (this.label.embed == Rotate) {
-      this.label.embed = Rotate(this.pTo - this.pFrom);
-    }
-    label(pic=pic, L=this.label, g=this.pFrom -- this.pTo);
-    this.label.align = a;
-    this.label.embed = e;
+    label_path(pic=pic, L=this.label, g=this.pFrom--this.pTo,
+        margin=this.width/2, rdir=this.pTo - this.pFrom);
   }
 }
 
@@ -577,5 +586,48 @@ Pendulum makePendulum(pair pivot=(0,0), Mass mass=Mass(), real length=15mm, real
   return p;
 }
 
+struct Ring {
+  triple center;
+  triple normal;
+  real radius;
+  real width;
+  real axis_pre;
+  real axis_post;
+  pen outline;
+  pen fill;
+  pen axis;
+  Label label;
+  Label axis_label;
+
+  void operator init(triple center=(0,0,0), triple normal=(0,0,1),
+                     real radius=5mm, real width=1mm, real axis_pre=0,
+                     real axis_post=0, pen outline=currentpen,
+                     pen fill=invisible, pen axis=invisible, Label L="",
+                     Label axis_label="") {
+    this.center = center;
+    this.normal = normal;
+    this.radius = radius;
+    this.width = width;
+    this.axis_pre = axis_pre;
+    this.axis_post = axis_post;
+    this.outline = outline;
+    this.fill = fill;
+    this.axis = axis;
+    this.label = L;
+    this.axis_label = axis_label;
+  }
+
+  void draw(picture pic=currentpicture) {
+    path3 a = shift(this.center)*(
+        (-this.axis_pre*this.normal)--(this.axis_post*this.normal));
+    draw(pic, a, this.axis, Arrow3);
+    path3 c = circle(c=this.center, r=this.radius, normal=this.normal);
+    //tube t = tube(c, width=this.width);  // slow and ugly!
+    //draw(t.s, this.fill);
+    draw(pic, c, this.outline);
+    label_path(pic=pic, L=this.label, g=c);
+    label_path(pic=pic, L=this.axis_label, g=a);
+  }
+}
 
-// TODO: ring, plate, cylinder, table
+// TODO: plate, cylinder, table