この図では簡素過ぎてよくわからないのでさらに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のコードに変換し、文字や矢印を入れていくと次のような図になりました。これはこれでゴチャゴチャし過ぎな感じがします。もうちょっと修正が必要かな。