![如何为麦克劳林三分线的极坐标图制作动画?](https://linux22.com/image/427261/%E5%A6%82%E4%BD%95%E4%B8%BA%E9%BA%A6%E5%85%8B%E5%8A%B3%E6%9E%97%E4%B8%89%E5%88%86%E7%BA%BF%E7%9A%84%E6%9E%81%E5%9D%90%E6%A0%87%E5%9B%BE%E5%88%B6%E4%BD%9C%E5%8A%A8%E7%94%BB%EF%BC%9F.png)
从我之前的问题,这是我从 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));
输出
我想要得到这样的红色曲线:
答案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
绘制通过所有点的移动曲线(参见M
operator..(...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));