マウスでシミュレーション制御(工事中)

以下の解説は私のカスタマイズ用ファイルの使用を前提とします。



制御関数の説明

idl

使用例

単純な例 
2次元の例 
3次元の例 
反応拡散方程式 

idl:制御関数

idl(dp,count,rot=,flag_stop=,fun1=,fun2=,arg1=,arg2=)

基本操作

補足1:コマンド実行(メニューの"command"をクリック)

fun3に何も指定しない場合、デフォルトのidl_fun3という関数が実行されて、"Enter command:"というプロンプトが表示されるので、任意のコマンドを実行できます。

グローバル変数nlevsの値を変更する例:
Stop
"fun2"
Enter command: extern nlevs; nlevs=5;
他にも例えば、グラフを画像として保存(outpng)、パレットを変える(pal)、他の関数を実行、などができます。

補足2:回転モード(メニューの"RoAxis"を左クリック)

回転モードは①自由な回転」と②x,y,z軸のいずれかを回転軸とする回転、の2種類あります。
②の場合は、回転軸にしたい軸と垂直な方向に左ドラッグすると、その軸を回転軸として描画物が回転します。

補足3:仕組み

関数の実行中はプロンプトへの入力はできませんが、マウスの左クリックや右クリックによる描画物の拡大・縮小の操作は反映されます(グラフィクスが独自のイベントループを持っている)。
すなわち、実行中の関数が描画領域のx,y座標の変化をチェックすることで、マウスクリックに対応して一時停止できます。
一時停止できれば後はマウスやキーボードからの入力を得て色んなことができます(グラフィクスのイベントループに自分の計算を埋め込む感じになります)。



単純な例 

line_color=red;
idl_init_pause=1;
idl_init=1;
x=span(0,12,100);
win2;
animate,1;
for(i=0;i<=10000;i++){
fma;
plg,sin(i*0.05+x)+cos(-i*0.08+1.5*x+1),x,color=line_color;
if(idl(20))break;
}
animate,0;

補足

for文の前のanimate,1と終了後のanimate,0はアニメーションモードのオンオフです。必須ではありませんが、画面のチラつきを防ぐことができます。

2次元の例

func function1(void){
  extern nlevs;
  nlevs=nlevs+1;
  write,"Contours are increased to:",nlevs;
}
func function2(void){
  extern nlevs;
  nlevs=nlevs-1;
  write,"Contours are decreased to:",nlevs;
}

nlevs=10;

func idl_demo1(dp){
if(is_void(dp))dp=20;
extern nlevs;
x= span(-3,3,64)(,-:1:64);
y= transpose(x);
  z= sin(2*sqrt(x^2+y^2))+cos(x+y+0.13);
  
  animate,1;
  
  for(t=0;t<=10000;t++){
    z= sin(2*sqrt(x^2+y^2)+0.02*t)+cos(x+y+0.013*t);
    fma;
    levs=span(-1.5,1.5,nlevs);
    plfc,z,y,x,levs=levs;
    plc,z,y,x,color=red,levs=levs;
    //    cbfc,[-2,2],levs=levs,ticks=1,label=1;
    xyt,"x","y";
    redraw;
    if(idl(dp,fun1=function1,fun2=function2))break;
  }
  animate,0;
}


win2;
idl_init=1;
idl_demo1,10;


3次元の例

func idl_demo2(void){
 
  x= span(-3,3,32)(,-:1:32);
  y= transpose(x);
  z= sin(2*sqrt(x^2+y^2))+cos(x+y+0.13);
  make_xyz,z,y,x,nv,xyzv;

  pl3surf,nv,xyzv;
  lim3,3,3,6;
  cage3,1;
  orient3;
  setz3,7;
  limits;
  draw3,1;
  scale,0.9;
   
  animate,1;
  for(t=0;t<=3000;t++){
    xyzv(3,)= sin(2*sqrt(xyzv(1,)^2+xyzv(2,)^2)+0.2*t)+cos(xyzv(1,)+xyzv(2,)+0.13*t);
    
    pl3surf,nv,xyzv;
    lim3,3,3,6;
    draw3,1;
    if(idl(20,t,rot=1))break;
  }
  animate,0;
}

idl_rotation=2;
idl_rotation_speed=[0,0,0.003];

win2,offset_w=100;
win3;
idl_init=1;
idl_init_pause=1;
idl_demo2;



反応拡散方程式の例

func function1(void){
  cpal=["earth","heat","sunrise","bb","cr"];
  id=1;
  n=read(prompt="Choose palette: 1: earth, 2: heat, 3: sunrise, 4: bb, 5: cr >",id);
  pal,cpal(id);
}

size = 120;
dt =0.2;
view_interval=100;
count_interval=1000;
a = 0.023;
b = 0.055;

gridx=span(0,1,size)(,-:1:size);
gridy=transpose(gridx);
dif_gridx=span(0.3,2.0,size)(,-:1:size);
dif_gridy=transpose(dif_gridx);
dif_rate_x = (8.0e-2)*dif_gridx;
dif_rate_y = (4.6e-2)*dif_gridy;

x=array(1.0,size,size);
y=array(0.001,size,size);
y(size/2,size/3) = 0.5;
diffuse_mask=grow(1,indgen(size),size);

func idl_demo3 (T,dp=){
  if(is_void(T))T=10000;
  if(is_void(dp))dp=1;
  fma;
  plfc,y,gridy,gridx,levs=spanl(0.05,0.6,20);
  xyt,"Diffusion rate for x", "Diffusion rate for y";
  limits;
  
  animate,1;
  for(t=0; t<=T;t++){
    diffuse_x=(x(,diffuse_mask)(,dif)(,dif)+x(diffuse_mask,)(dif,)(dif,));
    diffuse_y=(y(,diffuse_mask)(,dif)(,dif)+y(diffuse_mask,)(dif,)(dif,));
    x += dt*(-1.0*x*y*y + a*(1.0-x) +dif_rate_x*diffuse_x);
    y += dt*(x*y*y - (a+b)*y+dif_rate_y*diffuse_y);
    
    if(t%count_interval==0)t; 
    if(t%view_interval==0){
      fma;
      plfc,y,gridy,gridx,levs=spanl(0.05,0.6,20);
      xyt,"Diffusion rate for x", "Diffusion rate for y";
  
  
      if(idl(5,fun1=function1))break;
    }
    
  }
  animate,0;
}

win2,500,500;
idl_init_pause=1;

idl_init=1;
idl_demo3,100000;