Official Asymptote example – xstitch

Category: Asymptote,Official Gallery One-PagerPh. Ivaldi @ 7 h 13 min

Figure 0264
(Compiled with Asymptote version 2.14svn-r5318)
/* This code comes from The Official Asymptote Gallery */
    
pair c=(0,0.8);

int iters(pair z, int max=160) {
  int n=0;
  while(abs(z) < 2 && n < max) {
    z=z*z+c;
    ++n;
  }
  return n;
}

int[] cutoffs={12,15,20,30,40,60,200};
int key(pair z) {
  int i=iters(z);
  int j=0;
  while(cutoffs[j] < i)
    ++j;
  return j;
}


int width=210;
int height=190;

real zoom=2.5/200;

int[][] values=new int[width][height];
int[] histogram;  for(int v=0; v < 10; ++v) histogram.push(0);
for(int i=0; i < width; ++i) {
  real x=zoom*(i-width/2);
  for(int j=0; j < height; ++j) {
    real y=zoom*(j-height/2);
    int v=key((x,y));
    values[i][j]=v;
    ++histogram[v];
  }
}

// Print out a histogram.
write("histogram: ");
write(histogram);


pen linepen(int i, int max) {
  real w=i == -1 || i == max+1   ? 2.0 : 
    i % 10 == 0 || i == max ? 1.0 : 
    i % 5 == 0              ? 0.8 : 
    0.25;
  return linewidth(w);
}

pen xpen(int i) {
  return linepen(i,width)+(i == width/2 ? red : 
                           i == 75 || i == width-75 ? dashed : 
                           black);
}

pen ypen(int i) {
  return linepen(i,height)+(i == height/2 ? red : 
                            i == 75 || i == height-75 ? dashed : 
                            black);
}

// The length of the side of a cross stitch cell.
real cell=2.3mm;
transform t=scale(cell);


picture tick;
draw(tick,(0,0)--(1,1));

picture ell;
draw(ell,(0,1)--(0,0)--(0.7,0));

picture cross;
draw(cross,(0,0)--(1,1));
draw(cross,(1,0)--(0,1));

picture star;
draw(star,(0.15,0.15)--(0.85,0.85));
draw(star,(0.85,0.15)--(0.15,0.85));
draw(star,(.5,0)--(.5,1));
draw(star,(0,.5)--(1,.5));

picture triangle;
draw(triangle,(0,0)--(2,0)--(1,1.5)--cycle);

picture circle;
fill(circle,shift(1,1)*unitcircle);

picture ocircle;
draw(ocircle,shift(1,1)*unitcircle);

picture spare;
fill(spare,(0,0)--(1,1)--(0,1)--cycle);

picture[] pics={tick,ell,cross,star,triangle,circle};
pen[] colors={black,0.2purple,0.4purple,0.6purple,0.8purple,purple,
              0.8purple+0.2white};

frame[] icons;
icons.push(newframe);
for(picture pic : pics) {
  // Scaling factor, so that we don't need weird line widths.
  real X=1.0;
  frame f=pic.fit(.8X*cell,.8X*cell,Aspect);
  f=scale(1/X)*f;

  // Center the icon in the cell.
  f=shift((cell/2,cell/2)-0.5(max(f)-min(f)))*f;

  icons.push(f);
}

void drawSection(int xmin, int xmax, int ymin, int ymax) {
  static int shipoutNumber=0;

  // Draw directly to a frame for speed reasons.
  frame pic;

  for(int i=xmin; i <= xmax; ++i) {
    draw(pic,t*((i,ymin)--(i,ymax)),xpen(i));
    if(i%10 == 0) {
      label(pic,string(i),t*(i,ymin),align=S);
      label(pic,string(i),t*(i,ymax),align=N);
    }
  }
  for(int j=ymin; j <= ymax; ++j) {
    draw(pic,t*((xmin,j)--(xmax,j)),ypen(j));
    if(j%10 == 0) {
      label(pic,string(j),t*(xmin,j),align=W);
      label(pic,string(j),t*(xmax,j),align=E);
    }
  }

  if(xmin < 0)
    xmin=0;
  if(xmax >= width)
    xmax=width-1;
  if(ymin < 0)
    ymin=0;
  if(ymax >= height)
    ymax=height-1;

  int stitchCount=0;
  path box=scale(cell) *((0,0)--(1,0)--(1,1)--(0,1)--cycle);
  for(int i=xmin; i < xmax; ++i)
    for(int j=ymin; j < ymax; ++j) {
      int v=values[i][j];
      add(pic,icons[v],(i*cell,j*cell));
      //fill(pic,shift(i*cell,j*cell)*box,colors[v]);
      if(v != 0)
        ++stitchCount;
    }

  write("stitch count: ",stitchCount);

  //  shipout("xstitch"+string(shipoutNumber),pic);
  shipout(pic);
  ++shipoutNumber;
}

//drawSection(-1,width+1,-1,height+1);


//drawSection(-1,80,height-80,height+1);
//drawSection(70,150,height-80,height+1);
drawSection(quotient(width,2)-40,quotient(width,2)+40,quotient(height,2)-40,quotient(height,2)+40);
//drawSection(width-150,width-70,-1,80);
//drawSection(width-80,width+1,-1,80);


Official Asymptote example – worksheet

Category: Asymptote,Official Gallery One-PagerPh. Ivaldi @ 6 h 13 min

Figure 0253
(Compiled with Asymptote version 1.92svn-r4817)
/* This code comes from The Official Asymptote Gallery */
    
import fontsize;

defaultpen(Helvetica());

picture pic;
unitsize(pic,mm);

pair z=(0,0);
real length=88;
real height=8;
pair step=height*S;

label(pic,"Word Wall Spelling",z,Align);
z += step;
frame f;
label(f,"Name:");
pair z0=(max(f).x,min(f).y);
draw(f,z0--z0+50mm);
add(pic,f,z,Align);
z += step;

for(int i=1; i <= 14; ++i) {
  draw(pic,z--z+length);
  z += step;
  draw(pic,z--z+length,dashed+gray);
  z += step;
  void label(int i) {
    label(pic,string(i)+".",z,0.2NE,fontsize(0.8*1.5*2*height*mm)+gray);
  }
  if(i <= 10) label(i);
  else if(i == 11) {
    pair z0=z+length/2;
    pen p=fontsize(20pt);
    label(pic,"Challenge Word",z0+N*height,I*Align.y,p+basealign);
    label(pic,"(optional)",z0,I*Align.y,p);
  }
  else if(i == 12) label(1);
  else if(i == 13) label(2);
}
draw(pic,z--z+length);

add(pic.fit(),(0,0),W);
add(pic.fit(),(0,0),E);
newpage();
add(pic.fit(),(0,0),W);
add(pic.fit(),(0,0),E);




Official Asymptote example – washer

Category: Asymptote,Official Gallery One-PagerPh. Ivaldi @ 5 h 13 min

Figure 0257
(Compiled with Asymptote version 2.14svn-r5318)
/* This code comes from The Official Asymptote Gallery */
    
import three;
size(10cm);

path3[] p=reverse(unitcircle3)^^scale3(0.5)*unitcircle3;
path[] g=reverse(unitcircle)^^scale(0.5)*unitcircle;
triple H=-0.4Z;

render render=render(merge=true);
draw(surface(p,planar=true),render);
draw(surface(shift(H)*p,planar=true),render);
material m=material(lightgray,shininess=1.0);
for(path pp : g)
  draw(extrude(pp,H),m);



Official Asymptote example – venn3

Category: Asymptote,Official Gallery One-PagerPh. Ivaldi @ 4 h 13 min

Figure 0254
(Compiled with Asymptote version 2.14svn-r5318)
/* This code comes from The Official Asymptote Gallery */
    
size(0,150);

pen colour1=red;
pen colour2=green;
pen colour3=blue;

real r=sqrt(3);

pair z0=(0,0);
pair z1=(-1,0);
pair z2=(1,0);
pair z3=(0,r);

path c1=circle(z1,r);
path c2=circle(z2,r);
path c3=circle(z3,r);

fill(c1,colour1);
fill(c2,colour2);
fill(c3,colour3);

picture intersection12;
fill(intersection12,c1,colour1+colour2);
clip(intersection12,c2);

picture intersection13;
fill(intersection13,c1,colour1+colour3);
clip(intersection13,c3);

picture intersection23;
fill(intersection23,c2,colour2+colour3);
clip(intersection23,c3);

picture intersection123;
fill(intersection123,c1,colour1+colour2+colour3);
clip(intersection123,c2);
clip(intersection123,c3);

add(intersection12);
add(intersection13);
add(intersection23);
add(intersection123);

draw(c1);
draw(c2);
draw(c3);

label("$A$",z1);
label("$B$",z2);
label("$C$",z3);


Official Asymptote example – truncatedIcosahedron

Category: Asymptote,Official Gallery One-PagerPh. Ivaldi @ 3 h 13 min

Figure 0244
(Compiled with Asymptote version 2.14svn-r5318)
/* This code comes from The Official Asymptote Gallery */
    
import graph3;

size(200);

defaultrender.merge=true;

real c=(1+sqrt(5))/2;

triple[] z={(c,1,0),(-c,1,0),(-c,-1,0),(c,-1,0)};
triple[] x={(0,c,1),(0,-c,1),(0,-c,-1),(0,c,-1)};
triple[] y={(1,0,c),(1,0,-c),(-1,0,-c),(-1,0,c)};

triple[][] Q={
  {(c,1,0),(1,0,-c),(0,c,-1),(0,c,1),(1,0,c),(c,-1,0)},
  {(-c,1,0),(0,c,1),(0,c,-1),(-1,0,-c),(-c,-1,0),(-1,0,c)},
  {(-c,-1,0),(-c,1,0),(-1,0,-c),(0,-c,-1),(0,-c,1),(-1,0,c)},
  {(c,-1,0),(c,1,0),(1,0,c),(0,-c,1),(0,-c,-1),(1,0,-c)},
  {(0,c,1),(0,c,-1),(-c,1,0),(-1,0,c),(1,0,c),(c,1,0)},
  {(0,-c,1),(0,-c,-1),(-c,-1,0),(-1,0,c),(1,0,c),(c,-1,0)},
  {(0,-c,-1),(0,-c,1),(c,-1,0),(1,0,-c),(-1,0,-c),(-c,-1,0)},
  {(0,c,-1),(0,c,1),(c,1,0),(1,0,-c),(-1,0,-c),(-c,1,0)},
  {(1,0,c),(-1,0,c),(0,-c,1),(c,-1,0),(c,1,0),(0,c,1)},
  {(1,0,-c),(-1,0,-c),(0,-c,-1),(c,-1,0),(c,1,0),(0,c,-1)},
  {(-1,0,-c),(1,0,-c),(0,c,-1),(-c,1,0),(-c,-1,0),(0,-c,-1)},
  {(-1,0,c),(1,0,c),(0,c,1),(-c,1,0),(-c,-1,0),(0,-c,1)}
};

real R=abs(interp(Q[0][0],Q[0][1],1/3));

triple[][] P;
for(int i=0; i < Q.length; ++i) {
  P[i]=new triple[] ;
  for(int j=0; j < Q[i].length; ++j) {
    P[i][j]=Q[i][j]/R;
  }
}

for(int i=0; i < P.length; ++i) {
  for(int j=1; j < P[i].length; ++j) {
    triple C=P[i][0];
    triple A=P[i][j];
    triple B=P[i][j % 5+1];
    triple[] sixout=new
      triple[] {interp(C,A,1/3),interp(C,A,2/3),interp(A,B,1/3),interp(A,B,2/3),
                interp(B,C,1/3),interp(B,C,2/3)};
    triple M=(sum(sixout))/6;
    triple[] sixin=sequence(new triple(int k) {
        return interp(sixout[k],M,0.1);
      },6);
    draw(surface(reverse(operator--(...sixout)--cycle)^^
                 operator--(...sixin)--cycle,planar=true),magenta);
  }
}

for(int i=0; i < P.length; ++i) {
  triple[] fiveout=sequence(new triple(int k) {
      return interp(P[i][0],P[i][k+1],1/3);
    },5);
  triple M=(sum(fiveout))/5;
  triple[] fivein=sequence(new triple(int k) {
      return interp(fiveout[k],M,0.1);
    },5);
  draw(surface(reverse(operator--(...fiveout)--cycle)^^
               operator--(...fivein)--cycle,planar=true),cyan);
}





Official Asymptote example – stereoscopic

Category: Asymptote,Official Gallery One-PagerPh. Ivaldi @ 2 h 13 min

Figure 0224
(Compiled with Asymptote version 2.14svn-r5318)
/* This code comes from The Official Asymptote Gallery */
    
import three;
    
currentprojection=perspective(50*dir(70,15));

picture pic;
unitsize(pic,1cm);

draw(pic,xscale3(10)*unitcube,yellow,blue);
    
addStereoViews(pic);



Official Asymptote example – sin3

Category: Asymptote,Official Gallery One-PagerPh. Ivaldi @ 1 h 13 min

Figure 0203
(Compiled with Asymptote version 2.14svn-r5318)
/* This code comes from The Official Asymptote Gallery */
    
import graph3;
import palette;

size(12cm,IgnoreAspect);
currentprojection=orthographic(1,-2,1);

real f(pair z) {return abs(sin(z));}

real Arg(triple v) {return degrees(cos((v.x,v.y)),warn=false);}

surface s=surface(f,(-pi,-2),(pi,2),20,Spline);

s.colors(palette(s.map(Arg),Wheel()));
draw(s,render(compression=Low,merge=true));

real xmin=point((-1,-1,-1)).x;
real xmax=point((1,1,1)).x;
draw((xmin,0,0)--(xmax,0,0),dashed);

xaxis3("$\mathop{\rm Re} z$",Bounds,InTicks);
yaxis3("$\mathop{\rm Im} z$",Bounds,InTicks(beginlabel=false));
zaxis3("$|\sin(z)|$",Bounds,InTicks);


Official Asymptote example – quilt

Category: Asymptote,Official Gallery One-PagerPh. Ivaldi @ 12 h 13 min

Figure 0179
(Compiled with Asymptote version 2.14svn-r5318)
/* This code comes from The Official Asymptote Gallery */
    
import math;

int n=8, skip=3;

pair r(int k) { return unityroot(n,k); }

pen col=blue, col2=purple;

guide square=box((1,1),(-1,-1));

guide step(int mult)
{
  guide g;
  for(int k=0; k<n; ++k)
    g=g--r(mult*k);
  g=g--cycle;
  return g;
}

guide oct=step(1), star=step(skip);

guide wedge(pair z, pair v, real r, real a)
{
  pair w=expi(a/2.0);
  v=unit(v)*r;
  return shift(z)*((0,0)--v*w--v*conj(w)--cycle);
}

filldraw(square, col);
filldraw(oct, yellow);

// The interior angle of the points of the star.
real intang=pi*(1-((real)2skip)/((real)n));

for(int k=0; k<n; ++k) {
  pair z=midpoint(r(k)--r(k+1));
  guide g=wedge(z,-z,1,intang);
  filldraw(g,col2);
}

fill(star,yellow);
filldraw(star,evenodd+col);

size(5inch,0);


Official Asymptote example – polardatagraph

Category: Asymptote,Official Gallery One-PagerPh. Ivaldi @ 11 h 13 min

Figure 0171
(Compiled with Asymptote version 2.14svn-r5318)
/* This code comes from The Official Asymptote Gallery */
    
import graph;

size(100);

int n=30;
real minRadius=0.2;
real angles[]=uniform(0,2pi,n);
angles.delete(angles.length-1);

real[] r=new real[n];
for(int i=0; i < n; ++i)
  r[i]=unitrand()*(1-minRadius)+minRadius;

interpolate join=operator ..(operator tension(10,true));
draw(join(polargraph(r,angles,join),cycle),dot(red));




Official Asymptote example – pipes

Category: Asymptote,Official Gallery One-PagerPh. Ivaldi @ 10 h 13 min

Figure 0166
(Compiled with Asymptote version 2.14svn-r5318)
/* This code comes from The Official Asymptote Gallery */
    
import solids;
import tube;
import graph3;
import palette;
size(8cm);

currentprojection=perspective(
camera=(13.3596389245356,8.01038090435314,14.4864483364785),
up=(-0.0207054323419367,-0.00472438375047319,0.0236460907598947),
target=(-1.06042550499095,2.68154529985845,0.795007562120261));

defaultpen(fontsize(6pt));

// draw coordinates and frames 
// axis1 is defined by z axis of TBase
// axis2 is defined by z axis of TEnd
void DrawFrame(transform3 TBase, transform3 TEnd, string s)
{
  triple p1,v1,p2,v2;
  p1=TBase*O;
  v1=TBase*Z-p1;
  p2=TEnd*O;
  v2=TEnd*Z-p2;
  triple n=cross(v1,v2);

  real[][] A=
    {
      {v1.x,-v2.x,-n.x},
      {v1.y,-v2.y,-n.y},
      {v1.z,-v2.z,-n.z}
    };

  triple vb=p2-p1;

  real[] b={vb.x,vb.y,vb.z};
    
  // Get the extention along vector v1 and v2, 
  // so, we can get the common normal between two axis
  real[] x=solve(A,b);

  real s1=x[0];
  real s2=x[1];
    
  // get foot of a perpendicular on both axies
  triple foot1=p1+s1*v1;
  triple foot2=p2+s2*v2;
        
  // draw two axis
  triple axis_a,axis_b;
  axis_a=p1+s1*v1*1.5;
  axis_b=p1-s1*v1*1.5;
  draw(axis_a--axis_b);
        
  axis_a=p2+s2*v2*1.5;
  axis_b=p2-s2*v2*1.5;
  draw(axis_a--axis_b);
 
  // draw "a"(common normal) 
  draw(Label("$a_{"+s+"}$"),foot1--foot2,linewidth(1pt)); 

  // draw the coordinates frame
  triple dx,dy,dz,org;
  real length=0.8;
    
  org=foot1;
  dx =length*unit(foot2-foot1); // define the x axis of the frame on "a"
  dz =length*unit(v1);          // define the z axis which is along axis1
  dy =length*unit(cross(dz,dx));
        
  draw(Label("$X_{"+s+"}$",1,align=-dy-dz),org--(org+dx),red+linewidth(1.5pt),
       Arrow3(8));
  draw(Label("$Y_{"+s+"}$",1,align=2dy-dz-dx),org--(org+dy), 
       green+linewidth(1.5pt),  Arrow3(8));
  draw(Label("$Z_{"+s+"}$",1,align=-2dx-dy),org--(org+dz),
       blue+linewidth(1.5pt),   Arrow3(8));
    
  dot(Label("$O_{"+s+"}$",align =-dx-dz,black),org,black); // origin
           
}

void DrawLink(transform3 TBase, transform3 TEnd, pen objStyle,string s)
{
  real h=1;
  real r=0.5;
  path3 generator=(0.5*r,0,h)--(r,0,h)--(r,0,0)--(0.5*r,0,0);
  revolution vase=revolution(O,generator,0,360);
  surface objSurface=surface(vase);
    
  render render=render(merge=true);

  // draw two cylinders
  draw(TBase*objSurface,objStyle,render);
  draw(TEnd*shift((0,0,-h))*objSurface,objStyle,render);
        
  // draw the link between two cylinders
  triple pStart=TBase*(0.5*h*Z);
  triple pEnd  =TEnd*(-0.5*h*Z);
  triple pControl1=0.25*(pEnd-pStart)+TBase*(0,0,h);
  triple pControl2=-0.25*(pEnd-pStart)+TEnd*(0,0,-h);
  path3 p=pStart..controls pControl1 and pControl2..pEnd;
  draw(tube(p,scale(0.2)*unitsquare),objStyle,render);   
}

// t1 and t2 define the starting frame and ending frame of the first link(i-1)
transform3 t1=shift((0,0,1));
transform3 t2=shift((0,0,-1))*rotate(-20,Y)*shift((0,3,2));
// as, the two links were connected, so t2 is also the starting frame of link(i)
// t3 defines the ending frame of link(i) 
transform3 t3=t2*rotate(40,Z)*shift((0,3,1.5))*rotate(-15,Y)*shift(-1.5*Z);

// draw link(i-1)
DrawLink(t1,t2,palegreen,"i-1");
DrawFrame(t1,t2,"i-1");
// draw link(i)
DrawLink(t2,t3,lightmagenta,"i");
DrawFrame(t2,t3,"i");


// draw angle alpha, which is the angle between axis(i-1) and axis(i)
triple p0=(0,0,-1);
triple p1=(0,0,2.3);
triple p2=shift((0,0,-1))*rotate(-20,Y)*(0,0,4);
draw(p0--p2,cyan);
draw("$\alpha_{i-1}$",arc(p0,p1,p2,Y,CW),ArcArrow3(3));


// draw angle theta, which is the angle between a_i and a_{i-1}
transform3 tx=shift((0,0,-1))*rotate(-20,Y)*shift((0,3,0));
p0=tx*O;
p1=tx*(0,3,0);
p2=tx*rotate(40,Z)*(0,3,0);
draw(p0--p1,cyan);
draw(p0--p2,cyan);

triple p1a=tx*(0,1.5,0);
draw("$\theta_{i}$",arc(p0,p1a,p2),ArcArrow3(3));

// draw d_{i-1}
triple org_i   =t2*shift((0,0,1.5))*O;
draw(Label("$d_{i}$",0.13),p0--org_i,linewidth(1pt));