This is a follow up to an older question of mine which solved my issue of arrows in 3d plots with asymptote looking ugly.

Now I would like to add a semi-transparent bottom layer to the box in my plot. Here, the approach of projecting everything to 2d seems to reach its limit, as there is no projection of a surface available.

So, is there any other way to get the bottom surface of by box to be colored semi-transparently while preserving the beauty of the red arrow?

settings.outformat = "png";
settings.render = 10;
settings.prc = false;
import three;
real width = 2.7;
real height = 1.6;
real depth = 1.2;
real lw = 2; //linewidth

currentprojection = obliqueX;

//define matplotlib default colors
pen C0 = RGB(31,119,180);
pen C3 = RGB(214,39,40);

//draw box
draw(project((0,0,0) -- (0,0,-height)            ), C0+dashed+linewidth(lw));
draw(project((0,0,-height) -- (0,4*width,-height)), C0+dashed+linewidth(lw));
draw(project((0,0,-height) -- (depth,0,-height)  ), C0+dashed+linewidth(lw));
draw(project((0,0,0) -- (0,4*width,0)            ), C0+linewidth(lw));
draw(project((depth,0,0) -- (0,0,0)              ), C0+linewidth(lw));
draw(project((depth,0,-height) -- (depth,4*width,-height) -- (depth,4*width,0) -- (depth,0,0) -- (depth,0,-height)), C0+linewidth(lw));
draw(project((depth,4*width,-height) -- (0,4*width,-height) -- (0,4*width,0) -- (depth,4*width,0)), C0+linewidth(lw));
label("Box", project((depth, 2*width, -0.40*height)),C0);

//draw axis arrows
real axisZshift = -2.4;
real axisXshift = 0.2;
real axisLength = 1.0;
draw(project((0,axisZshift,axisXshift)--(-axisLength,axisZshift,axisXshift )), arrow=Arrow(TeXHead), L=Label("$z$", position=EndPoint, align=N+E));
draw(project((0,axisZshift,axisXshift)--(0,axisZshift,axisXshift+axisLength)), arrow=Arrow(TeXHead), L=Label("$x$", position=EndPoint, align=N));
draw(project((0,axisZshift,axisXshift)--(0,axisZshift+axisLength,axisXshift)), arrow=Arrow(TeXHead), L=Label("$y$", position=EndPoint, align=E));
//draw top interface DSM-SC

//draw red arrow
draw(project((depth, 3.5*width, 1.5*height) -- (depth, 0.5*width, 1.5*height)), arrow=Arrow(TeXHead), L=Label("red arrow", position=MidPoint, align=N), C3+linewidth(2*lw));

1 Answer 1


You should draw in 3D rather than trying to project the scene manually to 2D. That way you can you view your figure interactively from different viewpoints using OpenGL, WebGL, or Adobe Reader (using PRC). Just remove the project functions. You may prefer the look of DefaultHead2 with oblique projections:

draw((depth, 3.5*width, 1.5*height) -- (depth, 0.5*width, 1.5*height), arrow=Arrow3(DefaultHead2,size=30,emissive(C3)), L=Label("red arrow", position=MidPoint, align=N), C3+linewidth(2*lw));
  • Thanks, that's the solution. I have been playing with that before, but had color issues. The emissive(C3) from your answer solved this. Still an asymptote beginner...
    – laolux
    Mar 15, 2021 at 1:49
  • It's essential to work with the 2D projection if you prepare a publication, because some elements are... well, correspond to the 2D paper space. For example, dots may look nice if they have different colors of fill and outline contour. Good luck modeling it with 3D spheres. If you need to view your model interactively, there are better tools. Blender, for example.
    – facetus
    Jun 28, 2021 at 0:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .