graph3
This module implements three-dimensional versions of the
functions in graph.asy
. They work much like their
two-dimensional counterparts, except that the user has to keep track
of the three-dimensional axes limits (which in two dimension are stored in
the picture) in a bbox3
bounding box. The function
bbox3 autolimits(picture pic=currentpicture, triple min, triple max);can be used to determine “nice” values for the bounding box corners. A user-space bounding box that takes into account of the axes scalings for picture
pic
is returned by
bbox3 limits(picture pic=currentpicture, triple min, triple max);
To crop a bounding box to a given interval use:
void xlimits(bbox3 b, real min, real max); void ylimits(bbox3 b, real min, real max); void zlimits(bbox3 b, real min, real max); void limits(bbox3 b, triple min, triple max);
To draw an x axis in three dimensions from triple min
to
triple max
with ticks in the direction dir
, use the routine
void xaxis(picture pic=currentpicture, Label L="", triple min, triple max, pen p=currentpen, ticks ticks=NoTicks, triple dir=Y, arrowbar arrow=None, bool put=Above, projection P=currentprojection, bool opposite=false);To draw an x axis in three dimensions from triple
min
to
triple (max,min.y,min.z)
with ticks in the direction
dir
, use the routine
void xaxis(picture pic=currentpicture, Label L="", triple min, real max, pen p=currentpen, ticks ticks=NoTicks, triple dir=Y, arrowbar arrow=None, bool put=Above, projection P=currentprojection, bool opposite=false);To draw an x axis in three dimensions using
bbox3 b
with ticks in the direction dir
, use the routine
void xaxis(picture pic=currentpicture, Label L="", bool all=false, bbox3 b, pen p=currentpen, ticks ticks=NoTicks, triple dir=Y, arrowbar arrow=None, bool put=Above, projection P=currentprojection);If
all=true
, also draw opposing edges of the three-dimensional
bounding box.
Analogous routines yaxis
and zaxis
can be used to draw
y and z axes in three dimensions.
Here is an example of a helix and bounding box axes with rotated tick and axis labels, using orthographic projection:
import graph3; size(0,200); currentprojection=orthographic(4,6,3); real x(real t) {return cos(2pi*t);} real y(real t) {return sin(2pi*t);} real z(real t) {return t;} defaultpen(overwrite(SuppressQuiet)); path3 p=graph(x,y,z,0,2.7,Spline); bbox3 b=autolimits(min(p),max(p)); aspect(b,1,1,1); xaxis(rotate(X)*"$x$",all=true,b,red,RightTicks(rotate(X)*Label,2,2)); yaxis(rotate(Y)*"$y$",all=true,b,red,RightTicks(rotate(Y)*Label,2,2)); zaxis("$z$",all=true,b,red,RightTicks); draw(p,Arrow);
The next example illustrates three-dimensional x, y, and z axes, with autoscaling of the upper z limit disabled:
import three; import graph; import graph3; size(0,200,IgnoreAspect); currentprojection=perspective(5,2,2); defaultpen(overwrite(SuppressQuiet)); scale(Linear,Linear,Log(automax=false)); bbox3 b=autolimits(Z,X+Y+30Z); xaxis("$x$",b,red,RightTicks(2,2)); yaxis("$y$",b,red,RightTicks(2,2)); zaxis("$z$",b,red,RightTicks);
One can also place ticks along a general three-dimensional axis:
import graph3; size(0,100); path3 G=xscale3(1)*(yscale3(2)*unitcircle3); axis(Label("C",align=Relative(5E)),G, LeftTicks(endlabel=false,8,end=false), ticklocate(0,360,new real(real v) { path g=G; path h=O--max(abs(max(G)),abs(min(G)))*dir(90,v); return intersect(g,h).x; },perpendicular(G,Z)));
Surface plots of functions and matrices over the region
box(a,b)
in the XY plane are also implemented:
// draw the surface described by a matrix f, with lighting picture surface(real[][] f, pair a, pair b, pen surfacepen=lightgray, pen meshpen=nullpen, light light=currentlight, projection P=currentprojection); // draw the surface described by a function f, with lighting picture surface(real f(pair z), pair a, pair b, int n=nmesh, int m=n, pen surfacepen=lightgray, pen meshpen=nullpen, light light=currentlight, projection P=currentprojection) // draw the surface described by f, subsampling nsub times along cell edges picture surface(real f(pair z), int nsub, pair a, pair b, int n=nmesh, int m=n, pen surfacepen=lightgray, pen meshpen=currentpen, projection P=currentprojection);Here is an example of a Gaussian surface subsampled 4 times:
import graph3; size(200,0); currentprojection=perspective(5,4,2); real f(pair z) {return 0.5+exp(-abs(z)^2);} draw((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle3); draw(arc(0.12Z,0.2,90,60,90,15),ArcArrow); picture surface=surface(f,4,(-1,-1),(1,1),10); bbox3 b=limits(O,1.75(1,1,1)); xaxis(Label("$x$",1),b,red,Arrow); yaxis(Label("$y$",1),b,red,Arrow); zaxis(Label("$z$",1),b,red,Arrow); label("$O$",(0,0,0),S,red); add(surface);
sinc.asy
.