実座標のサンプル・プログラム

プログラム REALG.F90 は,1 つの画面上で,複数のウィンドウ座標の組をそれぞれ別のビューポートに作成する方法を示しています。REALG.F90Visual Fortran サンプルとして,...\DF98\SAMPLES\TUTORIAL フォルダに収録されています。

!	REALG.F90:(主プログラム) 座標を説明しています。
!
	USE DFLIB
	LOGICAL		statusmode
	TYPE (windowconfig)	myscreen
	COMMON		myscreen
!
!	最良の解像度と利用可能な最大色に画面を設定します。
	myscreen.numxpixels  = -1
	myscreen.numypixels  = -1
	myscreen.numtextcols = -1
	myscreen.numtextrows = -1
	myscreen.numcolors   = -1
	myscreen.fontsize    = -1
	myscreen.title       = " "C
	statusmode = SETWINDOWCONFIG(myscreen)
	IF(.NOT. statusmode) statusmode = SETWINDOWCONFIG(myscreen)
	statusmode = GETWINDOWCONFIG( myscreen )
	CALL threegraphs( )
	END
	.
	.
	.

プログラムの本体はきわめて短いものです。まず,ウィンドウをグラフィックス・ドライバの最高の解像度に設定し (最初の 4 つの欄を -1 に設定),色数をその最大値に設定しています (numcolors を -1 に設定)。その後,プログラムは 3 つのグラフを描画するサブルーチン threegraphs を呼び出します。次図にプログラムの出力を示します。

REALG プログラムの出力

グラフを描画するサブルーチン gridshapeは,すべての場合で同じデータを使用します。ただし,プログラムは 3 つの異なる座標ウィンドウを使用します。上にある 2 つのビューポートは物理座標で同じ大きさですが,ウィンドウの大きさが異なります。また,各ウィンドウは異なる最大値と最小値を使用します。

3 つの場合のいずれでも,グラフ領域は 2 単位分の幅を持っています。ウィンドウ左上の X 軸方向の範囲は 4 単位です (幅が 4 単位)。ウィンドウ右上の X 軸方向の範囲は 6 単位なので,右側のグラフは小さく見えています。

3 グラフ中の 2 つで,線の 1 つが端を越え,クリッピング領域外にはみ出しています。これらの線は他のビューポートには入り込んでいません。これは,ビューポートを定義することでクリッピング領域が作成されるからです。

最後に,下のグラフは上の 2 グラフのデータを反転させています。

次の節では,REALG.F90 が呼び出すサブルーチンを示し,説明しています。

グラフの描画

主プログラムは,3 つのグラフを出力するサブルーチン threegraphs を呼び出しています。

	SUBROUTINE threegraphs()
	USE DFLIB
	INTEGER(2) status, halfx, halfy
	INTEGER(2) xwidth, yheight, cols, rows
	TYPE (windowconfig) myscreen
	COMMON myscreen
	 
	CALL CLEARSCREEN( $GCLEARSCREEN )
	xwidth   = myscreen.numxpixels
	yheight  = myscreen.numypixels
	cols     = myscreen.numtextcols
	rows     = myscreen.numtextrows
	halfx    = xwidth / 2
	halfy    = (yheight / rows) * ( rows / 2 )
!
!	第 1 ウィンドウ
	CALL SETVIEWPORT( INT2(0), INT2(0), halfx - 1, halfy - 1 )
	CALL SETTEXTWINDOW( INT2(1), INT2(1), rows / 2, cols / 2 )
	status = SETWINDOW( .FALSE., -2.0_8, -2.0_8, 2.0_8, 2.0_8)
!	2.0_8 の表現は,これらの定数値を REAL(8) にします。
	CALL gridshape( rows / 2 )
	status = RECTANGLE( $GBORDER,INT2(0),INT2(0),halfx-1,halfy-1)
!
!	第 2 ウィンドウ
	CALL SETVIEWPORT( halfx, INT2(0), xwidth - 1, halfy - 1 )
	CALL SETTEXTWINDOW( INT2(1), (cols/2) + 1, rows/2, cols)
	status = SETWINDOW( .FALSE., -3.0D0, -3.0D0, 3.0D0, 3.0D0)
!	3.0D0 の表現は,これらの定数値を REAL(8) にします。
	CALL gridshape( rows / 2 )
	status = RECTANGLE_W( $GBORDER, -3.0_8,-3.0_8,3.0_8, 3.0_8)
!
!	第 3 ウィンドウ
	CALL SETVIEWPORT( 0, halfy, xwidth - 1, yheight - 1 )
	CALL SETTEXTWINDOW( (rows / 2 ) + 1, 1_2, rows, cols )
	status = SETWINDOW( .TRUE., -3.0_8, -1.5_8, 1.5_8, 1.5_8)
	CALL gridshape( INT2( (rows / 2) + MOD( rows, INT2(2))))
	status = RECTANGLE_W( $GBORDER, -3.0_8, -1.5_8, 1.5_8, 1.5_8)
	END

画面は初期状態ではクリアされていますが,サブルーチン threegraphsCLEARSCREEN ルーチンを呼び出して,確実にウィンドウをクリアします。

	CALL CLEARSCREEN( $GCLEARSCREEN )

$GCLEARSCREEN 定数はウィンドウ全体をクリアします。他のオプションとしては $GVIEWPORT$GWINDOW があり,それぞれ現在のビューポートとテキスト・ウィンドウをクリアします。

いくつかの変数に値を代入した後に,サブルーチン threegraphs は第 1 ウィンドウを作成します。

	CALL SETVIEWPORT( INT2(0), INT2(0), halfx - 1, halfy - 1)
	CALL SETTEXTWINDOW( INT2(1), INT2(1), rows / 2, cols / 2)
	status = SETWINDOW( .FALSE., -2.0_8, -2.0_8, 2.0_8, 2.0_8)

最初の命令は,画面の左上隅を覆うビューポートを定義します。次の命令は,その境界中にテキスト・ウィンドウを定義します。最後の命令は,X 値と Y 値の両方が -2.0 ~ 2.0 の範囲のウィンドウを作成します。.FALSE. は,Y 軸が上から下に向けて増大するようにします。これは基本設定です。_8 の表記は,定数を REAL(8) として識別します。

次に,サブルーチン gridshape がグリッドを挿入し,データをプロットします。その後,ウィンドウに境界が追加されます。

	CALL gridshape( rows / 2 )
	status = RECTANGLE( $GBORDER,INT2(0),INT2(0),halfx-1,halfy-1)

これは,ウィンドウではなくビューポートを基準とした座標を取る標準の RECTANGLE ルーチンです。

サブルーチン gridshape は,画面上にデータをプロットします。

!	GRIDSHAPE:このサブルーチンは,REALG.F90 のデータをプロットします。
	SUBROUTINE gridshape( numc )
	USE DFLIB
	INTEGER(2) numc, i, status
	INTEGER(4) rgbcolor, oldcolor
	CHARACTER(8) str
	REAL(8) bananas(21), x
	TYPE (windowconfig) myscreen
	TYPE (wxycoord) wxy
	TYPE (rccoord) curpos
	COMMON myscreen
!	グラフ・データ
	DATA bananas / -0.3, -0.2, -0.224, -0.1, -0.5, 0.21, 2.9, &
	&	0.3, 0.2, 0.0, -0.885, -1.1, -0.3, -0.2, &
	&	0.001, 0.005, 0.14, 0.0, -0.9, -0.13, 0.31 /
!	色付けしたテキストを画面に出力します。
	IF(myscreen.numcolors .LT. numc) numc = myscreen.numcolors-1
	DO i = 1, numc
	  CALL SETTEXTPOSITION( i, INT2(2), curpos )
	  rgbcolor = 12**i -1
	  rgbcolor = MODULO(rgbcolor, #FFFFFF)
	  oldcolor = SETTEXTCOLORRGB( rgbcolor )
	  WRITE ( str, '(I8)' ) rgbcolor
	  CALL OUTTEXT( 'Color ' // str )
	END DO
!	グラフの周りに 2 重矩形を描画します。
	oldcolor = SETCOLORRGB( #0000FF ) ! 赤色
	status = RECTANGLE_W( $GBORDER, -1.00_8, -1.00_8, 1.00_8,1.00_8)
!	_8 を付けることによって,定数値を REAL(8) にします。
	status = RECTANGLE_W( $GBORDER, -1.02_8, -1.02_8, 1.02_8, 1.02_8)
!	点をプロットします。
	x = -0.90
	DO i = 1, 19
	  oldcolor = SETCOLORRGB( #00FF00 ) ! 緑色
	  CALL MOVETO_W( x, -1.0_8, wxy )
	  status = LINETO_W( x, 1.0_8 )
	  CALL MOVETO_W( -1.0_8, x, wxy )
	  status = LINETO_W( 1.0_8, x )
	  oldcolor = SETCOLORRGB( #FF0000 ) ! 青色
	  CALL MOVETO_W( x - 0.1_8, bananas( i ), wxy )
	  status = LINETO_W( x, bananas( i + 1 ) )
	  x = x + 0.1
	END DO
	CALL MOVETO_W( 0.9_8, bananas( i ), wxy )
	status = LINETO_W( 1.0_8, bananas( i + 1 ) )
	oldcolor = SETCOLORRGB( #00FFFF ) ! 黄色
	END

_W で終わるルーチン名は,整数の代わりに倍精度浮動小数点値を渡すという点を除けば,それに対応するビューポート関数と同じように動作します。たとえば,LINETO には INTEGER(2) を渡しますが,LINETO_W には REAL(8) の値を渡します。

他の 2 つのウィンドウも,最初のウィンドウに似ています。3 つのウィンドウは,いずれも位置 (-1.0,-1.0) から (1.0, 1.0) までのグリッドを描画するサブルーチン gridshape を呼び出します。グリッドは,ウィンドウ座標が違うために,それぞれ異なる大きさで表示されます。第 2 ウィンドウの範囲は (-3.0,-3.0) から (3.0, 3.0) で,第 3 ウィンドウの範囲は (-3.0, -1.5) から (1.5, 1.5) なので,これに応じて大きさが変わります。

また,第 3 ウィンドウには反転引数として .TRUE. が含まれています。これにより,Y 軸は上から下でなく,下から上に向けて増大するようになります。その結果,このグラフは他の 2 つと比べて上下逆になっているように見えます。

プログラムは,サブルーチン gridshape を呼び出した後に,次のような文を使って個々のウィンドウのフレームを作成します。

	status = RECTANGLE_W( $GBORDER, -3.0_8, -1.5_8, 1.5_8, 1.5_8)

第 1 引数は,矩形の内側を塗り潰すか,その輪郭を描画するだけかを示す塗り潰しフラグです。残りの引数は,左上隅の X および Y 座標と,右下隅の X および Y 座標です。RECTANGLE は,ビューポート座標を参照する整数の引数を取ります。RECTANGLE_W は,ウィンドウ座標を参照する 4 つの倍精度浮動小数点値を取ります。

各種のグラフィックス要素を作成したら,フォント関連のルーチンを使って,タイトル,見出し,注釈,またはラベルの見栄えをよくすることができます。「グラフィックス・ライブラリーからのフォントの使用」では,テキストをフォント・ルーチンを使ってさまざまなフォントで出力する方法を詳しく説明しています。