9.1 コンターラインをコントロール

第2.2節で扱ったデータを用いて, コンターラインをユーザー の好みで制御することを考えてみましょう(u2d1).

# u2d1.rb


require "narray"
require "numru/dcl"
include NumRu
include Math

nx = 37
ny = 37
xmin = 0
xmax = 360
ymin = -90
ymax = 90
drad = PI/180
p = NArray.sfloat(nx, ny)

#-- data ---
for j in 0..ny-1
  for i in 0..nx-1
    alon = (xmin + (xmax-xmin)*i/(nx-1)) * drad
    alat = (ymin + (ymax-ymin)*j/(ny-1)) * drad
    slat = sin(alat)
    p[i,j] = 3*sqrt(1-slat**2)*slat*cos(alon) - 0.5*(3*slat**2-1)
  end
end

#-- graph ---
iws = (ARGV[0] || (puts ' WORKSTATION ID (I)  ? ;'; DCL::sgpwsn; gets)).to_i
DCL::gropn iws

DCL::grfrm

DCL::grswnd(xmin, xmax, ymin, ymax)
DCL::grsvpt(0.2, 0.8, 0.2, 0.8)
DCL::grstrn(1)
DCL::grstrf

DCL::usdaxs
DCL::udsfmt('(F4.1)')
DCL::udgcla(0.0, 1.4, 0.2)
DCL::udsclv(-1.0, 3, 4, 'abc', 0.028)
DCL::uddclv(0.6)
DCL::udcntr(p)

DCL::grcls

program u2d1

\resizebox{10cm}{!}{\includegraphics{u2d1/u2d1.eps}}
u2d1.rb: frame1

デフォルトではラベル付きの太線が1本おきに引かれますが, これをメジャー ラインとよびます. このメジャーラインに付いているコンターラベルのフォー マットは, udsfmt ルーチンで設定できます. 29行めのように, 指定す るフォーマットを文字型で与えます. コンターラインにつけるラベルは, コン ターレベルを決定するルーチンの中で生成されますから, udsfmt ルー チンはコンターラインを生成するルーチン(udgcla や udgclb)の 前に呼ばなければなりません.

コンターラインの生成ですが, ここでは, udgcla ルーチンで等間隔の コンターレベルを生成します. 最初の2つの引数がコンターレベルの最小値と 最大値で, 30行めの例では負のコンターは描かれません. 最後の引数は刻み 幅ですが, これが負の時にはその絶対値程度の本数のコンターレベルを生成し ます.

これらのルーチンでは, 等間隔のコンターレベルしか生成されません. もしも, 不等間隔のコンターレベルを指定したい場合や, 特定のコンターレベルを追加 したい場合は, 31行めのように udsclv ルーチンで1本1本のコンターレ ベルを生成します. 最初の引数がコンターレベルの値で, 残りの4つがコンター ラインの属性です. 順に, ラインインデクス, ラインタイプ, ラベル, V-座標 系におけるラベルの大きさ, です. 逆に, ある1本のコンターレベルを無効に するには uddclv ルーチンを呼びます. 引数はコンターレベルの値で, この例では, 0.6の等高線を描いていません. また, すべてのコンターレベル を無効にするには udiclv ルーチンを呼びます.

あとは, 同じ udcntr ルーチンを呼ぶだけです. このプログラムを実行すると, 次のようなメッセージが出るはずです.

*** MESSAGE (udcntr) *** INAPPROPRIATE DATA WILL BE MODIFIED INTERNALLY.
*** MESSAGE (-CNT.-) *** Z( 1, 1)= -1.00000000 ===> -1.00000119
udcntr では, ある格子点での値がコンターレベルと等しい時に, 格子 点値をわずかにずらして作画し, このようなメッセージを出力します. たいて いの場合, このメッセージを気にする必要はありません.



もう少しコンターラインにこだわってみましょう. 次のプログラム u2d2 では, 内部変数を変更することにより, コンターラインをコントロール しています. UDPACK メソッド(元サブルーチン)パッケージで使用する内部変数の参照と変 更は, udpget と udpset のルーチンで行ないます. ここで, p は, 内部変数の型によって l(論理型), i(整数型), r(実数型)のどれかをとります. この例では, 内部変数 'LABEL' を .false. にして, メジャーラインにラベルを付けないようにします. 'LDASH' も .false. にして正も負も同じラインタイプでコンター ラインを描くことにします. また, その時のラインタイプを 'ISOLID' で2(破線)と指定しています. さらに, 'ICYCLE' を4として, 4本に1本 の割合でメジャーラインを引くことにします. 結果は, 正負の区別もつかず, わけのわからない等高線図となってしまいましたが, このような機能もあると いうデモンストレーションです.

# u2d2.rb


require "narray"
require "numru/dcl"
include NumRu
include Math


nx = 37
ny = 37
xmin = 0
xmax = 360
ymin = -90
ymax = 90
drad = PI / 180
p = NArray.sfloat(nx, ny)

#-- data ---
for j in 0..ny-1
  for i in 0..nx-1
    alon = (xmin + (xmax-xmin)*i/(nx-1)) * drad
    alat = (ymin + (ymax-ymin)*j/(ny-1)) * drad
    slat = sin(alat)
    p[i,j] = 3*sqrt(1-slat**2)*slat*cos(alon) - 0.5*(3*slat**2-1)
  end
end

#-- graph ---
iws = (ARGV[0] || (puts ' WORKSTATION ID (I)  ? ;'; DCL::sgpwsn; gets)).to_i
DCL::gropn iws

DCL::grfrm

DCL::grswnd(xmin, xmax, ymin, ymax)
DCL::grsvpt(0.2, 0.8, 0.2, 0.8)
DCL::grstrn(1)
DCL::grstrf

DCL::usdaxs
DCL::udlset('LABEL', false)
DCL::udlset('LDASH', false)
DCL::udiset('isolid', 2)    
DCL::udiset('icycle', 4)    
DCL::udcntr(p)

DCL::grcls

program u2d2

\resizebox{10cm}{!}{\includegraphics{u2d1/u2d2.eps}}
u2d2.rb: frame1