From 239982b9b8ae90418f6ae62de99aa437edd76baa Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 11 Apr 2012 20:26:58 -0400 Subject: [PATCH] Add Ring structure to Mechanics.asy. Also pull path labeling out into label_path(). --- asymptote/Makefile | 7 +- asymptote/Mechanics-test.asy | 9 ++ asymptote/Mechanics.asy | 160 +++++++++++++++++++++++------------ 3 files changed, 119 insertions(+), 57 deletions(-) diff --git a/asymptote/Makefile b/asymptote/Makefile index bd9c7da..bd7bba4 100644 --- a/asymptote/Makefile +++ b/asymptote/Makefile @@ -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 $< diff --git a/asymptote/Mechanics-test.asy b/asymptote/Mechanics-test.asy index 7dd1264..105ce5f 100644 --- a/asymptote/Mechanics-test.asy +++ b/asymptote/Mechanics-test.asy @@ -17,8 +17,11 @@ * 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; diff --git a/asymptote/Mechanics.asy b/asymptote/Mechanics.asy index a98bcd2..d974c02 100644 --- a/asymptote/Mechanics.asy +++ b/asymptote/Mechanics.asy @@ -18,9 +18,48 @@ */ 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 -- 2.26.2