HSP3 プログラミングの基礎W | |
(7) グラフィックス 2
◆ 四角形内部のハッチ描画命令(g_hatch)作成
ハッチ(hatch)とは、辞書で引くと「線影」とある。図のように、線で影をつけることである。
棒グラフなどは、四角形の塗りつぶしで描画して区別するとカラフルで見やすくなる。しかし、そのグラフを白黒で印刷するとすべてがグレーになり、区別がしにくくなる。このように白黒で印刷する場合、色で塗りつぶすのではなく、ハッチにすると区別がしやすくなる。
ここでは、指定した四角形内部にハッチを描画する命令g_hatchを作成する。
命令g_hatchの仕様は次の通りとする。
g_hatch 左上座標x,左上座標y,右下座標x,右下座標y,ハッチの種類
ハッチの種類はビットパターンで指定する。ハッチの種類は次の通りとする。
値 ハッチ(8ドット間隔) 値 ハッチ(最初4ドット、以降8ドット間隔) 1(0x01) 45度斜線右上がり 16(0x10) 45度斜線右上がり 2(0x02) 45度斜線左上がり 32(0x20) 45度斜線左上がり 4(0x04) 垂直 64(0x40) 垂直 8(0x08) 水平 128(0x80) 水平
ハッチの種類をビットパターンで指定することによって、3(0x03)を指定するとクロス状のハッチを描画することができる。このように値を加算していくことでいろいろな模様のハッチを描画させることができる。
◎ 水平ハッチ
水平のハッチを描画する。(ハッチの種類=4(0x04))
#module #deffunc g_circle int x, int y, int r, int nuri <<省略>> #deffunc g_line int x1, int y1, int x2, int y2, int pat <<省略>> #deffunc g_box int x1, int y1, int x2, int y2, int pat <<省略>> #deffunc g_hatch int x1, int y1, int x2, int y2, int hc ; ;g_hatch 左上座標x,左上座標y,右下座標x,右下座標y,ハッチの種類 ; ハッチの種類は、ビットパターンで指定する。 ; spc = 8 ;間隔(8ドット) if hc and 4 { ;水平ハッチ if y1 < y2 : yy1 = y1 : yy2 = y2 : else : yy1 = y2 : yy2 = y1 repeat , 1 yy = cnt * spc + yy1 ;Y座標計算 if yy > yy2 : break line x1, yy, x2, yy ;描画 loop } return #global color 255, 0, 0 ;赤 g_box 50, 50, 200, 200 color 0, 0, 0 ;黒 g_hatch 50, 50, 200, 200, 0x04 stop
水平のハッチが描画される。四角形内部であることがわかりやすいように赤色で四角形を描画している。
四角形の左上と右下の座標を逆に指定したときも処理できるようにif文でy1, y2の小さい方をyy1に、大きい方をyy2に格納している。
水平の直線を描画するので、x座標はx1からx2までの範囲である。
y座標は左上のyy1から8ドット間隔で描画するので、1本目は「1(本目)*8(ドット)+yy1」、2本目は「2(本目)*8(ドット)+yy1」となる。
直線は繰り返しで描画している。繰り返しの終了はyyがyy2を超えたときである。
最初の間隔だけ4ドットの水平のハッチ描画を追加する。(ハッチの種類=64(0x40))
#module #deffunc g_circle int x, int y, int r, int nuri <<省略>> #deffunc g_line int x1, int y1, int x2, int y2, int pat <<省略>> #deffunc g_box int x1, int y1, int x2, int y2, int pat <<省略>> #deffunc g_hatch int x1, int y1, int x2, int y2, int hc ; ;g_hatch 左上座標x,左上座標y,右下座標x,右下座標y,ハッチの種類 ; ハッチの種類は、ビットパターンで指定する。 ; spc = 8 ;間隔(8ドット) if hc and 4 { ;水平ハッチ if y1 < y2 : yy1 = y1 : yy2 = y2 : else : yy1 = y2 : yy2 = y1 repeat , 1 yy = cnt * spc + yy1 ;Y座標計算 if yy > yy2 : break line x1, yy, x2, yy ;描画 loop } if hc and 0x40 { ;水平ハッチ if y1 < y2 : yy1 = y1 : yy2 = y2 : else : yy1 = y2 : yy2 = y1 repeat , 1 yy = cnt * spc + yy1 - (spc / 2) ;Y座標計算 if yy > yy2 : break line x1, yy, x2, yy ;描画 loop } return #global color 255, 0, 0 ;赤 g_box 50, 50, 200, 200 color 0, 0, 0 ;黒 g_hatch 50, 50, 200, 200, 0x40 stop
水平のハッチが描画される。
8ドット間隔のハッチ描画処理でy座標を4ドット(通常間隔8ドットの半分)ずらすだけである。Y座標計算でspc/2だけ減算している。左上のy座標より4ドット上から描画しているのでY軸方向の長さはspc/2だけ加算している。
最後のハッチが四角形の下辺と重なっている。これを防ぐには、if文を次のようにする。
if yy >= y2 : break
ハッチの種類として、0x44を指定すると間隔の狭い(4ドット)水平のハッチが描画できる。
◎ 垂直ハッチ
垂直のハッチを描画する。(ハッチの種類=8(0x08)と128(0x80))
#module #deffunc g_circle int x, int y, int r, int nuri <<省略>> #deffunc g_line int x1, int y1, int x2, int y2, int pat <<省略>> #deffunc g_box int x1, int y1, int x2, int y2, int pat <<省略>> #deffunc g_hatch int x1, int y1, int x2, int y2, int hc ; ;g_hatch 左上座標x,左上座標y,右下座標x,右下座標y,ハッチの種類 ; ハッチの種類は、ビットパターンで指定する。 ; spc = 8 ;間隔(8ドット) if hc and 4 { ;水平ハッチ <<省略>> } if hc and 0x40 { ;水平ハッチ <<省略>> } if hc and 8 { ;垂直ハッチ if x1 < x2 : xx1 = x1 : xx2 = x2: else : xx1 = x2 : xx2 = x1 repeat , 1 xx = cnt * spc + xx1 ;X座標計算 if xx > xx2 : break line xx, y1, xx, y2 loop } if hc and 0x80 { ;垂直ハッチ if x1 < x2 : xx1 = x1 : xx2 = x2: else : xx1 = x2 : xx2 = x1 repeat , 1 xx = cnt * spc + xx1 - (spc / 2) ;X座標計算 if xx > xx2 : break line xx, y1, xx, y2 loop } return #global color 255, 0, 0 ;赤 g_box 50, 50, 200, 200 color 0, 0, 0 ;黒 g_hatch 50, 50, 200, 200, 0x08 stop
垂直のハッチが描画される。
水平ハッチ処理のX座標とY座標の役割が入れ替わっているだけである。
◎ 斜線(右上がり)ハッチ
斜線(右上がり)のハッチを描画する。(ハッチの種類=1(0x01))
#module #deffunc g_circle int x, int y, int r, int nuri <<省略>> #deffunc g_line int x1, int y1, int x2, int y2, int pat <<省略>> #deffunc g_box int x1, int y1, int x2, int y2, int pat <<省略>> #deffunc g_hatch int x1, int y1, int x2, int y2, int hc ; ;g_hatch 左上座標x,左上座標y,右下座標x,右下座標y,ハッチの種類 ; ハッチの種類は、ビットパターンで指定する。 ; spc = 8 ;間隔(8ドット) if hc and 4 { ;水平ハッチ <<省略>> } if hc and 0x40 { ;水平ハッチ <<省略>> } if hc and 8 { ;垂直ハッチ <<省略>> } if hc and 0x80 { ;垂直ハッチ <<省略>> } if hc and 1 { ;斜線右上がりハッチ repeat , 1 xx1 = x1 + cnt * spc ;斜線の始点 yy1 = y1 xx2 = x1 ;斜線の終点 yy2 = y1 + cnt * spc if xx1 > x2 : yy1 = yy1 + xx1 - x2 : xx1 = x2 ;※1 if yy2 > y2 : xx2 = xx2 + yy2 - y2 : yy2 = y2 ;※2 if xx2 > x2 : break line xx1, yy1, xx2, yy2 loop } return #global color 255, 0, 0 ;赤 g_box 50, 50, 200, 200 color 0, 0, 0 ;黒 g_hatch 50, 50, 200, 200, 0x01 stop
斜線(右上がり)のハッチが描画される。
図は、斜線の始点(水色)と終点(青色)を示している。
始点のy座標はy1で変化しない。始点のx座標はspc(=8)ドットずつ右にずれていくのでx1に加算していく。
終点のx座標はx1で変化しない。終点のy座標はspc(=8)ドットずつ下にずれていくのでy1に加算していく。
斜線の始点(xx1, yy1)と終点(xx2, yy2)は次の式で求まる。cntはrepeatの回数で1で初期化する。
xx1 = x1 + cnt * spc yy1 = y1 xx2 = x1 yy2 = y1 + cnt * spc
このままでは、図のように四角形(赤色)の範囲を超えるので、計算値の修正が必要である。
まず、始点のxx1がx2を超えたとき、xx1がx2を超えた分だけすなわち xx1-x2 ドットだけy方向にもずれるので、修正した始点は次の式で求まる。(※1)
yy1 = yy1 + xx1 - x2 xx1 = x2
同じように、終点のyy2がy2を超えたとき、yy2がy2を超えた分だけx方向にもずれる。修正した始点は次の式で求まる。(※2)
xx2 = xx2 + yy2 - y2 yy2 = y2
繰り返しの終了は、終点のxx2がx2を超えたときである。
最初の間隔だけが4ドットの斜線(右上がり)のハッチを追加せよ。(ハッチの種類=16(0x10))
斜線の始点(xx1, yy1)と終点(xx2, yy2)の座標計算を次のようにするだけである。
xx1 = x1 + cnt * spc - (spc / 2) yy1 = y1 xx2 = x1 yy2 = y1 + cnt * spc - (spc / 2)
◎ 斜線(左上がり)ハッチ
斜線(左上がり)のハッチを描画する。(ハッチの種類=2(0x02)と32(0x20))
#module #deffunc g_circle int x, int y, int r, int nuri <<省略>> #deffunc g_line int x1, int y1, int x2, int y2, int pat <<省略>> #deffunc g_box int x1, int y1, int x2, int y2, int pat <<省略>> #deffunc g_hatch int x1, int y1, int x2, int y2, int hc ; ;g_hatch 左上座標x,左上座標y,右下座標x,右下座標y,ハッチの種類 ; ハッチの種類は、ビットパターンで指定する。 ; spc = 8 ;間隔(8ドット) if hc and 4 { ;水平ハッチ <<省略>> } if hc and 0x40 { ;水平ハッチ <<省略>> } if hc and 8 { ;垂直ハッチ <<省略>> } if hc and 0x80 { ;垂直ハッチ <<省略>> } if hc and 1 { ;斜線右上がりハッチ <<省略>> } if hc and 0x10 { ;斜線右上がりハッチ <<省略>> } if hc and 2 { ;斜線左上がりハッチ repeat , 1 xx1 = x1 + cnt * spc ;斜線の始点 yy1 = y2 xx2 = x1 ;斜線の終点 yy2 = y2 - cnt * spc if xx1 > x2 : yy1 = yy1 - xx1 + x2 : xx1 = x2 if yy2 < y1 : xx2 = xx2 + y1 - yy2 : yy2 = y1 if xx2 > x2 : break line xx1, yy1, xx2, yy2 loop } if hc and 0x20 { ;斜線左上がりハッチ repeat , 1 xx1 = x1 + cnt * spc - (spc / 2) ;斜線の始点 yy1 = y2 xx2 = x1 ;斜線の終点 yy2 = y2 - cnt * spc + (spc / 2) if xx1 > x2 : yy1 = yy1 - xx1 + x2 : xx1 = x2 if yy2 < y1 : xx2 = xx2 + y1 - yy2 : yy2 = y1 if xx2 > x2 : break line xx1, yy1, xx2, yy2 loop } return #global color 255, 0, 0 ;赤 g_box 50, 50, 200, 200 color 0, 0, 0 ;黒 g_hatch 50, 50, 200, 200, 0x02 stop
斜線(左上がり)のハッチが描画される。
サンプルと図を見ながら考えてみよう。
以上でハッチの描画命令は完成である。
2006 © Hiroshi Masuda |