2015年9月20日日曜日

ketpicによる被覆空間の習作2

曲面上の領域を斜線塗りする方法を利用して、被覆空間における平行移動と被覆変換を図示してみました。
この図では簡素過ぎてよくわからないのでさらにinkscapeに取り込んでさらに加工する必要がありますが、この図を出力するためのソースは次の通りです。
currentdir=pwd()

tic();

a=2;//内側の円の半径
b=2;//被覆空間のxy平面からの距離
R=3;//外側の円の半径と内側の円の半径の差

//視点のアングル
phi=20;
theta=75;
Setangle(theta,phi);


//曲面の定義
function x=CX(u,v)
    x=(u+a)*cos(2*%pi*v)
endfunction

function y=CY(u,v)
    y=(u+a)*sin(2*%pi*v)
endfunction

function z=CZ(u,v)
    z=2*v+b
endfunction
//



//被覆空間
FD=list('p','x=CX(U,V)','y=CY(U,V)','z=CZ(U,V)','U=[0,R]','V=[0,4]');

//底空間
GC1=Spacecurve('[CX(0,V),CY(0,V),0]','V=[0,1]');
GC2=Spacecurve('[CX(R,V),CY(R,V),0]','V=[0,1]');


//被覆空間の輪郭線・境界線データ
SFb=Sfbdparadata(FD,[50,250],0.01,0.001);



//被覆空間上の領域
EHSC=list();//斜線で塗った領域を曲面に埋め込んだもののリスト
ESC=list();//領域の境界を曲面に埋め込んだもののリスト
for K=list(-1,0,2,3)
  
function Z=Embz(X,Y)
  if K>0 then
    //atanの出力値は(-pi, pi]なので注意する。
    Z=atan(Y,X)/%pi+2*floor(K*0.5)+b;
  else
    //K=-1,0の場合はZ=0の平面
    Z=0
  end
endfunction


//埋め込み関数の定義
deff('Out=Emb(X,Y)','Out=[X,Y,Embz(X,Y)]');

//埋め込む平面上の領域の境界線を定義
function Y=CvY(T)
  Y=sin(T)+(a+0.5*R)*(-1)^(K+1)
endfunction
SC=Paramplot('[cos(T),CvY(T)]','T=[-%pi,%pi]');

//境界内を斜線で塗る
HSC=Hatchdata(list('i'),list(SC),45,2.5);

//領域を曲面に埋め込む
EHSC1=Embed(HSC,Emb);
ESC1=Embed(SC,Emb);

EHSC($+1)=EHSC1;
ESC($+1)=ESC1;

if K>0 then
  EHSC2=Translate3data(EHSC1,[0,0,4]);
  ESC2 =Translate3data(ESC1,[0,0,4]);
  EHSC($+1)=EHSC2;
  ESC($+1)=ESC2;
end

end


//ファイバー
Fibre=list();
SFibre=list();
for K=1:2
  Fibre1=Spacecurve('[0,(a+0.5*R)*(-1)^(K),T]','T=[0,10]');
  Fibre($+1)=Fibre1;
  SFibre1=Crvsfparadata(Fibre1,SFb,FD)
  SFibre($+1)=SFibre1;
end

//パス 後でスケルトンデータを取るため、曲面よりもz座標が少し大きくなるようにする
SPath=list();
for K=0:2
  if K>0 then
    Vmax=0.75+2*(K-1);
    Vmin=1.25+2*(K-1);
    SPath1=Spacecurve('[CX(0.5*R,V),CY(0.5*R,V),CZ(0.5*R,V)+0.02]','V=[Vmax,Vmin]');
    SPath($+1)=SPath1;
  else
    SPath1=Spacecurve('[CX(0.5*R,V),CY(0.5*R,V),0.02]','V=[0.75,1.25]');
    SPath($+1)=SPath1;
  end
end

//陰線処理
SkDom=Skeletonparadata(list(ESC,EHSC),list(Fibre,SPath),1,0.01);
SkSFb=Skeletonparadata(SFb,Fibre);
SkGC2=Skeletonpara3data(GC2,Fibre);

//曲面に隠れる曲線 曲面と交わらないときは最後に-1を付ける。
SGC2=Crvsfparadata(SkGC2,SFb,FD,-1);



Setwindow([-6,6],[-2,11]);//ウィンドウ範囲を設定
Windisp(list(Projpara(GC1,SGC2,SFibre,SPath),SkDom,SkSFb));

cd(currentdir);


Openfile('fiber_translation.tex')//書き出し用ファイルを開く
Beginpicture('10/12cm');//picture環境を始める。引数は単位長
Drwline(list(Projpara(GC1,SGC2,SFibre,SPath),SkDom,SkSFb),1);
Endpicture(0);//picture環境を終える(座標軸を書かない)
Closefile();//書き出し用ファイルを閉じる


T=toc();
minute=floor(T/60);
second=floor(T-60*minute);
disp(strcat([string(minute), ' minutes ', string(second), ' seconds']));
出力したpdfをinkscapeで取り込んで、パスを簡略化したあとsvg2tikzでtikzのコードに変換し、文字や矢印を入れていくと次のような図になりました。
これはこれでゴチャゴチャし過ぎな感じがします。もうちょっと修正が必要かな。