6

In every Asymptote animation example that I found (see e.g. here or here), the viewpoint is constant during the animation. I would like to make one which consists in a rotating viewpoint, the drawn objects being constant.

The following code works, but as you can see the resulting gif is unsteady. How can I avoid this?

problem illustration

size(10cm,10cm);
import graph3;
import grid3;
//import animation;
import animate;

settings.render=1;
animation A;
A.global=false;

real xmin=-2, xmax=2;
real ymin=-2, ymax=1.5;
real zmin=-2.5, zmax=2.5;

limits((xmin,ymin,zmin),(xmax,ymax,zmax));

unitsize(3cm,3cm,2cm);

viewportmargin=(2,2);


////// PLANES ///////
pen bg=gray(0.9)+opacity(0.2);
draw(surface((xmax,ymin,zmin)--(xmax,ymin,zmax)--(xmin,ymin,zmax)--(xmin,ymin,zmin)--cycle),bg);
draw(surface((xmin,ymax,zmin)--(xmin,ymax,zmax)--(xmin,ymin,zmax)--(xmin,ymin,zmin)--cycle),bg);
draw(surface((xmax,ymax,zmin)--(xmax,ymin,zmin)--(xmin,ymin,zmin)--(xmin,ymax,zmin)--cycle),bg);


xaxis3(Label("$x$",MidPoint,align=Y-Z),Bounds(Both,Min),InTicks(Step=1),p=black);
yaxis3(Label("$y$",MidPoint,align=X-Z),Bounds(Both,Min),InTicks(Step=.5),p=black);
zaxis3(Label("$z$",MidPoint,align=X-Y),Bounds(Both,Min),InTicks(Step=2),p=black);

for(real i;i<6.28;i=i+0.05) {
  currentprojection=perspective(camera=(2*cos(i),2*sin(i),2.5));    
  A.add();
  save();
}

A.movie(loops=3,delay=50);

Edit I followed Harish Kumar's suggestion and added a bounding box; it's better but still far from perfect.

enter image description here

Code (only the end changes):

for(real i;i<6.28;i=i+.1) {
  currentprojection=perspective(camera=(2*cos(i),2*sin(i),2.5));
  picture pic;
  add(pic,bbox(20mm));  
  A.add(pic);
  save();
}
  • I don't know how but you can define a fixed bounding box. – user11232 Feb 8 '15 at 4:31
  • @HarishKumar: I added your suggestion to my answer; the result is still unsteady. – anderstood Feb 8 '15 at 5:04
  • What if you add it outside the loop and make it some what large enough? – user11232 Feb 8 '15 at 5:19
  • @HarishKumar Well, if I add bbox(5000mm); or shipout(bbox(5000mm)); outside the loop in my first code, it has no effect (that's why I added it in the loop). – anderstood Feb 8 '15 at 5:25
8

It is better to insert a sphere, its projection does not depend on the camera (in this case). Please find the code

size(10cm,10cm);
import graph3;
import grid3;
//import animation;
import animate;

settings.render=1;
animation A;
A.global=false;

real xmin=-2, xmax=2;
real ymin=-2, ymax=1.5;
real zmin=-2.5, zmax=2.5;

limits((xmin,ymin,zmin),(xmax,ymax,zmax));

unitsize(3cm,3cm,2cm);

viewportmargin=(2,2);


////// PLANES ///////
pen bg=gray(0.9)+opacity(0.2);
draw(surface((xmax,ymin,zmin)--(xmax,ymin,zmax)--(xmin,ymin,zmax)--(xmin,ymin,zmin)--cycle),bg);
draw(surface((xmin,ymax,zmin)--(xmin,ymax,zmax)--(xmin,ymin,zmax)--(xmin,ymin,zmin)--cycle),bg);
draw(surface((xmax,ymax,zmin)--(xmax,ymin,zmin)--(xmin,ymin,zmin)--(xmin,ymax,zmin)--cycle),bg);

xaxis3(Label("$x$",MidPoint,align=Y-Z),Bounds(Both,Min),InTicks(Step=1),p=black);
yaxis3(Label("$y$",MidPoint,align=X-Z),Bounds(Both,Min),InTicks(Step=.5),p=black);
zaxis3(Label("$z$",MidPoint,align=X-Y),Bounds(Both,Min),InTicks(Step=2),p=black);
draw(scale(4,4,5)*unitsphere,invisible);

for(real i;i<6.28;i=i+0.05) {
  currentprojection=perspective(camera=(2*cos(i),2*sin(i),2.5));
  A.add();
  save();
}

A.movie(loops=3,delay=50);

You obtain this animation

enter image description here

O.G.

  • or draw(scale(4,4,5)*unitsphere,opacity(.0)); so one can change the opacity easily to check if the sphere covers everything. – Symbol 1 Feb 8 '15 at 14:26
  • Regarding transparency, the behaviour is due tosettings.render=0;. I forgot to change it to something settings.render=1; in my OP. – anderstood Feb 8 '15 at 15:46
  • Code and gif animation modified. – O.G. Feb 8 '15 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.