3次元グラフの表面はsplot
の後にwith pm3d
をつけることで色をつけることができます。この場合、色はz座標で指定されます。
実行例を以下に示します。
set xrange [-1*pi:1*pi]
set yrange [-1*pi:1*pi]
set isosamples 50
splot sin(x)*sin(y) with pm3d
上の例のset isosamples 50
という部分では、メッシュの数を指定しています。デフォルト値は10なので、これを多少増やしておかないと下のように見栄えのよくない図になってしまいます。
媒介変数表示の場合も同様です。ただし、視点に近い部分がちゃんと手前に来るように描画するように、set pm3d depthorder
というコマンドを追加しています。
set parametric
set urange [0:pi]
set vrange [0:2*pi]
set isosamples 50
set pm3d depthorder
set view 75,45
set xrange [-1:1]
set yrange [-1:1]
set zrange [-1:1]
splot sin(u)*cos(v),sin(u)*sin(v),cos(u) with pm3d
3次元グラフの表面の色をもっと自由に指定したい場合は、using
の4つ目の引数で色を指定します。ただし、この機能はusing
を使うので、当然データファイルのプロットにしか使えません。ある関数をプロットする場合は擬似ファイル"+"
や"++"
を使う(gnuplot4.3以降)か、set table
を使っていったん別にデータファイルを作っておく必要があります。
まず、擬似ファイル"++"
を使うやり方を紹介します。擬似ファイル"++"
はgnuplot4.3以降に新しく加わった機能で、xrange
とyrange
で指定した範囲内にset samples
(x方向の点数)とset isosamples
(y方向の点数)で指定した数の点のファイルがあるものとして解釈されます。下の例ではusing
の4番目の引数に(sin($1+$2*2))
を指定しているので、sin(x+2*y)の値で決まる色が表面につきます。
set xrange [-1*pi:1*pi]
set yrange [-1*pi:1*pi]
set samples 50
set isosamples 50
splot "++" using 1:2:(sin($1)*sin($2)):(sin($1+$2*2)) with pm3d
次に、set table
を使ってデータファイルを別に作っておく例を示します。下の例ではset table "table.dat"
というコマンドを使って、"table.dat"
というファイルにいったんsin(x)*sin(y)
をプロットした結果を出力しています。その後、unset table
でデータファイルへの出力を解除し、その後グラフを出力しています。出力結果は上の例と全く同じになります。
set xrange [-1*pi:1*pi]
set yrange [-1*pi:1*pi]
set samples 50
set isosamples 50
set table "table.dat"
splot sin(x)*sin(y)
unset table
splot "table.dat" using 1:2:3:(sin($1+$2*2)) with pm3d
媒介変数で表すようなグラフの場合は、set table
を使うほうがよさそうです。下の例では、"table2.dat"
というファイルにデータを書き出していますが、媒介変数表示の場合はxとyの値(後で図を出力するときには媒介変数uとvとしてそれぞれ使われる)しか必要ないので、定数関数0をデータファイルに出力しています。その後xrange
などを指定しなおしてから図を出力しています。
set xrange [0:pi]
set yrange [0:2*pi]
set samples 100
set isosamples 100
set pm3d depthorder
set table "table2.dat"
splot 0
unset table
set xrange [-1:1]
set yrange [-1:1]
set zrange [-1:1]
splot "table2.dat" using (sin($1)*cos($2)):(sin($1)*sin($2)):(cos($1)):(sin($2*2)) \\
with pm3d
上のような4つ目のusing
パラメータを使用した表面色指定の例として、光の当たっているように見える色のつけ方を紹介します。
媒介変数形式で指定されている曲面
を考えます。この曲面に光がベクトル
で表される方向から当たっているとします。ここでは、この曲面の色は光の方向sと曲面の法線nとの内積で決まるという簡単なモデルを考えます。媒介変数で表される曲面の場合は法線nは曲面の2つの接線
の外積
で表すことができます。従って、using
の第4引数には
を与えればいいわけです。
一つ例を示します。set palette defined ( 0 "dark-blue" , 1 "cyan")
で、濃い青から水色へと徐々に変わっていく色使いを指定しています。light(u,v)
関数で三項演算子を使っているのは、接線ベクトルのうちの一方がゼロになってしまう場合を回避するためです。もし法線ベクトルが定義できない場合、わずかにずれた場所のlight(u,v)
で代用します。
# 表面の媒介変数関数
Fx(u,v)=sin(u)*cos(v)
Fy(u,v)=sin(u)*sin(v)
Fz(u,v)=cos(u)
# 光の方向
sx=1.0
sy=1.0
sz=1.0
# 微分用の微小数
h=0.000001
# Fx,Fy,Fzのuおよびvによる偏微分
dFxu(u,v)=(Fx(u+h,v)-Fx(u-h,v))/(2.0*h)
dFyu(u,v)=(Fy(u+h,v)-Fy(u-h,v))/(2.0*h)
dFzu(u,v)=(Fz(u+h,v)-Fz(u-h,v))/(2.0*h)
dFxv(u,v)=(Fx(u,v+h)-Fx(u,v-h))/(2.0*h)
dFyv(u,v)=(Fy(u,v+h)-Fy(u,v-h))/(2.0*h)
dFzv(u,v)=(Fz(u,v+h)-Fz(u,v-h))/(2.0*h)
# 法線ベクトルの各成分 n = lu x lv
nx(u,v)=dFyu(u,v)*dFzv(u,v)-dFyv(u,v)*dFzu(u,v)
ny(u,v)=dFzu(u,v)*dFxv(u,v)-dFzv(u,v)*dFxu(u,v)
nz(u,v)=dFxu(u,v)*dFyv(u,v)-dFxv(u,v)*dFyu(u,v)
# 光の方向ベクトルsの長さ
s_length=sqrt(sx**2+sy**2+sz**2)
# 法線ベクトルnの長さ
n_length(u,v)=sqrt(nx(u,v)**2+ny(u,v)**2+nz(u,v)**2)
# 光の方向ベクトルsと表面の法線ベクトルnの内積で色を決める
light(u,v)=(n_length(u,v)!=0.0 ? \
(sx*nx(u,v)+sy*ny(u,v)+sz*nz(u,v))/(s_length*n_length(u,v)) :\
light(u+h,v+h))
set xrange [0:pi]
set yrange [0:2*pi]
set samples 100
set isosamples 100
# いったんパラメータファイルを作る
tablefile="table3.dat"
set table tablefile
splot 0
unset table
set xrange [-1:1]
set yrange [-1:1]
set zrange [-1:1]
set pm3d depthorder
set view 60,30
# 色使いの指定
set palette defined ( 0 "dark-blue" , 1 "cyan")
splot tablefile using (Fx($1,$2)):(Fy($1,$2)):(Fz($1,$2)):(light($1,$2)) \
with pm3d
上のように光が当たっている感じの出ている球になりました。
関数を変える場合はFx(u,v),Fy(u,v),Fz(u,v)
を変更すればOKです。以下では
Y(u,v)=sqrt(5.0/(4.0*pi))*0.5*(3.0*cos(u)**2-1) # 球面調和関数
Fx(u,v)=sin(u)*cos(v)*abs(Y(u,v))
Fy(u,v)=sin(u)*sin(v)*abs(Y(u,v))
Fz(u,v)=cos(u)*abs(Y(u,v))
のように球面調和関数(l=2,m=0)に変更した場合の例を示します。(各方向のrange
も[-0.65:0.65]
に変更しています。)
このように立体感のある球面調和関数が描けました。