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 ルー チンはコンターラインを生成するルーチン(udgclaudgclb)の 前に呼ばなければなりません.

コンターラインの生成ですが, ここでは, 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 メソッド(元サブルーチン)パッケージで使用する内部変数の参照と変 更は, udpgetudpset のルーチンで行ないます. ここで, 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