6.4 等間隔データをおまかせにする

これまでのプログラム uspac1uspac2 では, x 座標値の配 列を宣言して等間隔に値を代入し, f(x)型の一次元図を描きましたが, これ はちょっと大げさな気もします. ここで, 未定義値 rundef をうまく使 うと, プログラムが簡単になります. 次のプログラム uspac3uspac1 と同じ図を描くプログラムですが, x 座標値は等間隔なので, UUPACK におまかせします.

まず, 19行めで rundef の値を参照し, 22行めの usgrph ルーチ ンで x を指定するかわりに rundef を指定します. このように, x は定義されていないと宣言すると, usgprhx 座標値がウ インドウの幅いっぱいに等間隔にならんでいるものと解釈してグラフを描きま す. このとき, usgrph が呼ばれる前に x 方向のウインドウは決まっ ていないといけませんから, grswnd ルーチンで x 方向だけを陽に与 えています. ここでも, y 方向は未定義にして, 正規化変換の確定は usgprh ルーチンにおまかせしています. 実行結果は, 前の uspac1 の 場合と全く同じです.

      PROGRAM USPAC3

      PARAMETER( NMAX=50, XMIN=1950, XMAX=2000 )
      REAL Y(0:NMAX)

      R    = 3.7
      Y(0) = 0.5
      DO 10 N=0,NMAX-1
        Y(N+1) = R*Y(N)*(1.-Y(N))
   10 CONTINUE

      WRITE(*,*) ' WORKSTATION ID (I)  ? ;'
      CALL sgpwsn
      READ (*,*) IWS

      NumRu::DCL.gropn(iws)
      CALL grfrm

      rpara = NumRu::DCL.glrget(cp)
      NumRu::DCL.grswnd(uxmin,uxmax,uymin,uymax)
      NumRu::DCL.ussttl(cxttl,cxunit,cyttl,cyunit)
      NumRu::DCL.usgrph(x,y)

      CALL grcls

      END
program uspac3




次のプログラム uspac4 では, usspntuulin などのルー チンで y を指定するかわりに rundef を指定して, y 方向に 等間隔なデータを描きます. ここで, uumrk ルーチンはポリマーカープ リミティブに対応するもので, uusmkt, uusmki, uusmksで このパッケージで使うマーカーの属性(種類, 描く線の太さ, 大きさ)を設定で きます. usspnt ルーチンを使ってウインドウを決め, ビューポートの 設定は初期値に頼りますので, grstrf ルーチンの前に uspfit を呼んでいることを再確認しておきましょう.

      PROGRAM USPAC4

      PARAMETER( NMAX=50, YMIN=0., YMAX=50. )
      REAL X1(0:NMAX), X2(0:NMAX)

      ISEED = 1
      DO 10 N=0,NMAX
        Y = YMIN + (YMAX-YMIN)*N/NMAX
        X1(N) = 10.*(EXP(-Y/20))**2 * EXP((return_value = NumRu::DCL.rngu3(iseed)**2
        X2(N) = 10.*(EXP(-Y/20))**2
   10 CONTINUE

      WRITE(*,*) ' WORKSTATION ID (I)  ? ;'
      CALL sgpwsn
      READ (*,*) IWS

      NumRu::DCL.gropn(iws)
      CALL grfrm

      rpara = NumRu::DCL.glrget(cp)
      NumRu::DCL.grswnd(uxmin,uxmax,uymin,uymax)
      NumRu::DCL.usspnt(x,y)
      NumRu::DCL.usspnt(x,y)
      NumRu::DCL.grstrn(itr)
      CALL uspfit
      CALL grstrf

      NumRu::DCL.ussttl(cxttl,cxunit,cyttl,cyunit)
      CALL usdaxs

      NumRu::DCL.uusmkt(itype)
      NumRu::DCL.uumrk(upx,upy)
      NumRu::DCL.uulin(upx,upy)

      CALL grcls

      END
program uspac4

\resizebox{10cm}{!}{\includegraphics{uspack/uspac4.eps}}
uspac4.f: frame1

この章で紹介した正規化変換のおまかせ確定は, 「らくらくDCL」の他の章で は使っていません. 教育的な配慮を優先したからで, 正規化変換の内容を陽に 意識してもらいたいからです. しかし, この章で「おまかせ」の意味がはっき り分かったら, これを積極的に使って何も問題ありません. より簡単にプログ ラムが書けることでしょう.

 


DCLのしくみ 3

根回し型ルーチンと上意下達型ルーチン

SGPACK の各出力プリミティブにはそれぞれ2種類の描画ルーチンがあります.

例えば,ポリラインプリミティブでは,sgplv, sgplu ルーチンで折れ線を描くように説明しました.ポリラインの属性は sgsplt, sgspli などのルーチンで前もって設定しておきました.これらは,いろいろ属性を決めておいてから描画ルーチンを呼ぶという「根回し型」のルーチンです.

これに対して,属性も同時に指定してポリラインを描画するルーチンも用意されています.呼び出し方法は,それぞれ,

NumRu::DCL.sgplzv(vpx,vpy,itype,index)
NumRu::DCL.sgplzu(upx,upy,itype,index)
です.引数の itype でラインタイプを与え,index でラインインデクスを与えます.これらは,メソッド(元サブルーチン)ひとつで一度に描いてしまう「上意下達型」のルーチンです.

同様に,他の出力プリミティブも上意下達型のルーチンが用意されています.引数の説明は省きますが,次のように呼び出します.

NumRu::DCL.sgpmzv(vpx,vpy,itype,index,rsize)
NumRu::DCL.sgpmzu(upx,upy,itype,index,rsize)
NumRu::DCL.sgtxzv(vx,vy,chars,rsize,irota,icent,index)
NumRu::DCL.sgtxzu(ux,uy,chars,rsize,irota,icent,index)
NumRu::DCL.sgtnzv(vpx,vpy,itpat)
NumRu::DCL.sgtnzu(upx,upy,itpat)
NumRu::DCL.sglazv(vx1,vy1,vx2,vy2,itype,index)
NumRu::DCL.sglazu(ux1,uy1,ux2,uy2,itype,index)
NumRu::DCL.sglnzv(vx1,vy1,vx2,vy2,index)
NumRu::DCL.sglnzu(ux1,uy1,ux2,uy2,index)

 

他のグラフィクスパッケージでも,GKS の流れは前者の型で,CALCOMP 系のものは後者の型です.これまでにどちらかの型に馴染んでいるユーザーは,好みの方をお使い下さい.