如何为麦克劳林三分线的极坐标图制作动画?

如何为麦克劳林三分线的极坐标图制作动画?

我之前的问题,这是我从 g.kov 的回答中得到的代码:

import graph;
import math;
import animate;
settings.tex="pdflatex";

size(300);
real a=2;

animation Anim;
real f(real t){ 
  return a/2*(4*cos(t)-1/cos(t));
}

xaxis(xmin=-2,xmax=4,Ticks(Step=1,modify=NoZero,pTick=invisible));
yaxis(ymin=-3,ymax=3,Ticks(Step=1,modify=NoZero,pTick=invisible));

real dtheta=0.25;
int n=500;
guide g=polargraph(f,-pi/2+dtheta,pi/2-dtheta,n,operator ..);
draw(g,dashed);

for (int i=0; i<360; ++i){
save();
drawline((0,0),dir(i));
drawline((a,0),(a,0)+dir(3*i));
Anim.add();
restore();
}
erase();
Anim.movie(BBox(2mm,invisible));

输出

https://i.imgur.com/Y6KDNyj.gif

我想要得到这样的红色曲线:

在此处输入图片描述

https://i.imgur.com/AHwHOk2.gif

答案1

这种情况下,我们已经知道了追踪曲线的参数方程,所以只要在动画的每一帧中画出来就行了。为了简单起见,下面是一个圆上某个点的动画(看起来就像我们的地球绕着太阳旋转一样)。

在此处输入图片描述

// save as x.asy, 
// compile with asy x.asy to get x.pdf in several pages
// then using this ImageMagick command:
// magick -density 200 x.pdf -alpha remove x.gif

import graph;
import animate;
unitsize(1cm);
real a=3;
animation Anim;
real x(real t){return a*cos(t);}
real y(real t){return a*sin(t);}

guide g=graph(x,y,0,2*pi,operator ..);
draw(g,dashed+gray+linewidth(.2pt));
fill(unitcircle,orange);

for (int i=0; i<360; i=i+2){
save();
real irad=radians(i);
guide gtracing=graph(x,y,0,irad,operator ..);
draw(gtracing,red+linewidth(1pt));
fill(circle((x(irad),y(irad)),.2),blue);
Anim.add();
restore();
}
erase();
Anim.movie(BBox(2mm,invisible));

更新:现在适应 OP 的情况。为了控制动画的流程,我构建了一个合适的移动角度序列,避免 i=90 和 i=270,其中 cos(i)=0。

int istep=2;
int[] arrangle;
for (int i=0; i<90; i=i+istep)
arrangle.push(i);
for (int i=90+dtheta; i<180; i=i+istep)
arrangle.push(i);
for (int i=180; i<270; i=i+istep)
arrangle.push(i);
for (int i=270+dtheta; i<360; i=i+istep)
arrangle.push(i);

在此处输入图片描述

完整代码

import math;
import graph;
import animate;
unitsize(1cm);
real a=2;
animation Anim;
real f(real t){ 
return a/2*(4*cos(t)-1/cos(t));
}

xaxis(xmin=-2.5,xmax=4.5,Ticks(Step=1,modify=NoZero,pTick=invisible));
yaxis(Ticks(Step=1,modify=NoZero,pTick=invisible));

int dtheta=2; // in degrees
int n=100;    // smooth
guide g=polargraph(f,-pi/2+radians(dtheta),pi/2-radians(dtheta),n,operator ..);
draw(g,dashed);

// spiral for moving angles
pair spiral(real t){ // t is in degree
real trad=radians(t);
real r=.1+trad/50;
return r*(cos(trad),sin(trad));};

// construct sequence for moving angles 
// avoiding i=90 and i=270 where cos(i)=0
int istep=2;
int[] arrangle;
for (int i=0; i<90; i=i+istep)
arrangle.push(i);
for (int i=90+dtheta; i<180; i=i+istep)
arrangle.push(i);
for (int i=180; i<270; i=i+istep)
arrangle.push(i);
for (int i=270+dtheta; i<360; i=i+istep)
arrangle.push(i);
 
for (int i : arrangle){
save();
real irad=radians(i);
guide gtracing=polargraph(f,0,irad,n,operator ..);
draw(gtracing,.5red+.5white+linewidth(1pt));
draw(arc((0,0),.5,0,i),blue);
drawline((0,0),dir(i));
guide stracing=graph(spiral,0,3*i,operator ..);
draw(shift(a,0)*stracing,blue);

drawline((a,0),(a,0)+dir(3*i));
fill(circle(f(irad)*dir(i),.08),red);
clip(box((-2.5,-3.5),(4.5,3.5)));
Anim.add();
restore();
}

erase();
Anim.movie(BBox(2mm,invisible));

更新 2 (根据 OP 要求更新一些代码) 不知道(参数)方程的跟踪动画。

知道(参数)方程只是确定动点的一种方法,如果有其他方法可以得到动点的位置,那么我们可以把所有动点从起点连到当前位置。

再次为了简单起见,使用第一个例子。首先定义一个移动点数组

pair[] arrMovingPoints; 

现在在循环中,获得移动点后tmp,我们将其推送到数组中,然后使用连接语法arrMovingPoints绘制通过所有点的移动曲线(参见Moperator..(...arrMovingPoints)这个答案由@Charles Staats 提供)。

pair tmp=a*dir(i); // the moving point
arrMovingPoints.push(tmp);
draw(operator..(...arrMovingPoints));

下面是完整的代码,根本没有(参数)方程。

在此处输入图片描述

import animate;
unitsize(1cm);
real a=3;
animation Anim;
pair[] arrMovingPoints;
fill(unitcircle,purple);

for (int i=0; i<360; i=i+2){
save();
pair tmp=a*dir(i); // the moving point
arrMovingPoints.push(tmp);
draw(operator..(...arrMovingPoints),pink+1);
fill(circle(tmp,.2),red);
Anim.add();
restore();
}
erase();
Anim.movie(BBox(2mm,invisible));

相关内容