Asymptote FAQ - Section 8
Questions about differences between Asymptote and MetaPost


Question 8.1. What is the equivalent of the MetaPost c[a,b] interpolation operator?

interp(a,b,c);

Question 8.2. How does picture scaling differ in Asymptote and MetaPost?

Asymptote includes an optional facility to do automatic scaling of pictures to achieve a given overall picture size, whereas Metapost only supports manual scaling. Asymptote defers drawing of objects drawn to pictures and distinguishes between true-size objects and objects that should scale with the picture size. The resulting linear programming problem is solved via the Simplex method.

See the https://asymptote.sourceforge.io/gallery/dimension.asy example for an example of how deferred drawing is used to accomodate both user and true-size (PostScript) coordinates.

Question 8.3. How can I avoid automatic scaling of a picture?

If you really like Metapost-style manual (hard-wired) scaling either:

(i) use the default size(0,0) for the entire picture and do all of the scaling by hand, just like in MetaPost;

(ii) draw to a separate picture pic and add(pic.fit());

(iii) use frames.

Question 8.4. What is the equivalent of MetaPost ... command?

The connector :: is a macro for tension atleast 1:
size(100);
pair z0=(0,0);
pair z1=(1,0.25);
pair z2=(2,0);
draw(z0{up}::z1{right}::z2{down});

Question 8.5. What is the equivalent of the MetaPost pickup command?

Just say, for example:
currentpen=red;

Question 8.6. What is the equivalent of the MetaPost whatever command?

Asymptote does not implicitly solve linear equations and therefore does not have the notion of a whatever unknown. Such a facility could certainly be added (perhaps using the notation ?= since = means assignment). However, the most common uses of whatever in MetaPost are covered by functions like extension in math.asy:
pair extension(pair P, pair Q, pair p, pair q);
this returns the intersection point of the extensions of the line segments PQ and pq. We find using routines like extension more explicit and less confusing to new users. But we could be persuaded to add something similar if someone can justify the need. In the meantime, one can always use the explicit built-in linear solver solve (see https://asymptote.sourceforge.io/doc/solve.html), which uses LU decomposition.

Question 8.7. What is the equivalent for the MetaPost command for lray - horiz*v - verti*u = whatever*(LightSource - R), a system of three linear equations for three unknowns: horiz, verti, whatever?

Since horiz*v+verti*u spans a plane, you could use
real intersect(vector P, vector Q, vector n, vector Z);
to find the intersection time for the line lray-whatever*(LightSource - R) and then extract the three desired values from there. (You'll still need to use the built-in explicit linear solver to solve a 2x2 system to get horiz and verti.)

Question 8.8. In MetaPost, it is possible to have a drawing remain the same size in different pictures by defining a unit u and explicitly multiply all the coordinates by u. Is there a better way to do this in Asymptote?

Yes, Asymptote has a better way: you definitely don't want to manually scale all of your coordinates. To make the user coordinates represent multiples of exactly 1cm:
unitsize(1cm);
draw(unitsquare);
One can also specify different x and y unit sizes:
unitsize(x=1cm,y=2cm);
draw(unitsquare);
Another way is to draw your fixed size object to a frame and add it to currentpicture like this:
path p=(0,0)--(1,0);
frame object;
draw(object,scale(100)*p);
 
add(object);
add(object,(0,-10));
To understand the difference between frames and pictures, try this:
size(300,300);
 
path p=(0,0)--(1,0);
picture object;
draw(object,scale(100)*p);
 
add(object);
add(object,(0,-10)); // Adds truesize object to currentpicture 

Question 8.9. In MetaPost, one could produce tiling pictures by generating a picture, and then clipping the picture to a rectangle of fixed dimensions around the center of the picture. How is that done in Asymptote?

If you are using currentpicture the way one would in MetaPost (drawing in raw PostScript coordinates), you can simply do something like:
fill((0,0)--(100,100)--(200,0)--cycle);
 
pair center(picture pic=currentpicture) {return 0.5*(pic.min()+pic.max());} 
 
real height=100;
real width=100;
pair delta=0.5(width,height);
pair c=center();
clip(box(c-delta,c+delta));
However, drawing in PostScript coordinates is often inconvenient. Here's the Asymptote way of doing the same thing, using deferred drawing:
size(200,100);
fill((0,0)--(1,1)--(2,0)--cycle);
 
void clip(picture pic=currentpicture, real width, real height) 
{
  pic.clip(new void (frame f, transform) { 
    pair center=0.5(min(f)+max(f));
    pair delta=0.5(width,height);
    clip(f,box(center-delta,center+delta));
  });
} 
 
clip(100,100);
See also the discussion of tilings in the documentation: https://asymptote.sourceforge.io/doc/Pens.html.
Next: Questions about output.
Back: Questions about programming.
Return to contents.

Asymptote - 2024-03-24

Extracted from Asymptote Frequently Asked Questions, Copyright © 2024 .