#============================================================================== #◆汎用描画ライブラリー ver 1.0 #   by 黒豹は月夜に踊る #     http://hunters.nobody.jp/ #------------------------------------------------------------------------------ # 線ひいたり、丸描いたり、三角形塗りつぶして、などができます。 # 基本的に動作が重いです。 #============================================================================== #------------------------------------------------------------------------------ # ▼ Sprite クラス #------------------------------------------------------------------------------ class Sprite attr_accessor :gs_viewport #-------------------------------------------------------------------------- # ● グレースケールビューポート #-------------------------------------------------------------------------- #  グレースケール画像を利用して様々な形のビューポートを指定できます。ハート # だったり、バラの形だったり、お好みに。 #  グレスケというか、指定すればレッドスケーるでもブルースケールでもグリーン # スケールでもいけます。ビューポートに使用するのは画像でもいいですし、スクリ # プトの命令で描画した物でも可です。要はビューポートが Bitmap クラスであれば # 何でもいいんです。ちなみに、プリセットの Viewport クラスとは別物です。 # # ox_vp : ビューポートの原点座標X # ox_vp : ビューポートの原点座標Y # color : 参照カラー("red","green","blue"以外は正常に動作しない) #-------------------------------------------------------------------------- def apply_gsvp(ox_vp = @gs_viewport.width/2 ,oy_vp = @gs_viewport.height/2 ,color = "red") ox = self.ox oy = self.oy w = self.bitmap.width h = self.bitmap.height w_vp = @gs_viewport.width h_vp = @gs_viewport.height for i in 0..w for j in 0..h scol = self.bitmap.get_pixel(i,j) if (i >= ox-ox_vp && i < w_vp+ox-ox_vp)&&(j >= oy-oy_vp && j < h_vp+oy-oy_vp) vcol = @gs_viewport.get_pixel(i-(ox-ox_vp),j-(oy-oy_vp)) else vcol = @gs_viewport.get_pixel(0,0) end eval "scol.alpha *= vcol.#{color}/255" self.bitmap.set_pixel(i,j,scol) end end end end #------------------------------------------------------------------------------ # ▼ Bitmap クラス #------------------------------------------------------------------------------ class Bitmap #-------------------------------------------------------------------------- # ※ Accuracy の値を小さくすると描画の精度を上げられますが、 #   動作が重くなります。 #-------------------------------------------------------------------------- Accuracy = 1/100.0 #-------------------------------------------------------------------------- # ● ライン描画 #-------------------------------------------------------------------------- # x1 : 始点座標X # y1 : 始点座標Y # x2 : 終点座標X # y2 : 終点座標Y # color : 描画色 #-------------------------------------------------------------------------- def draw_line(x1 ,y1 ,x2 ,y2 ,color=Color.new(255,255,255)) dist_x = x2-x1 dist_y = y2-y1 t = Accuracy u=v=0 i=0 while(i<=1) set_pixel(x1+u,y1+v,color) u+=dist_x*t v+=dist_y*t i+=t end end #-------------------------------------------------------------------------- # ● 正多角形描画 #-------------------------------------------------------------------------- # ox : 中心点座標X # oy : 中心点座標Y # vertices: 頂点数(値が 2 以下だと正常に動作しない) # radius : 半径 # rotate : 回転角(ラジアン) # color : 描画色 #-------------------------------------------------------------------------- def draw_polygon(ox ,oy ,vertices ,radius ,rotate=-Math::PI/2 ,color=Color.new(255,255,255)) pi=Math::PI i=rotate j=2*pi/vertices+rotate x1=y1=x2=y2=0 while(i<=2*pi+rotate) x1 = ox+Math.cos(i)*radius y1 = ox+Math.sin(i)*radius x2 = ox+Math.cos(j)*radius y2 = ox+Math.sin(j)*radius draw_line(x1 ,x2 ,y1 ,y2 ,color) i += 2*pi/vertices j += 2*pi/vertices end end #-------------------------------------------------------------------------- # ● 三角形塗りつぶし #-------------------------------------------------------------------------- #※動作重し  #-------------------------------------------------------------------------- # xs : 各X座標の配列 # ys : 各Y座標の配列 # [0]=原点 [1]=始点 [2]=終点 # color : 描画色 #-------------------------------------------------------------------------- def fill_triangle(xs,ys,color=Color.new(255,255,255)) dist_x = xs[2]-xs[1] dist_y = ys[2]-ys[1] u=xs[1] v=ys[1] t = Accuracy i=0 while(i<=1) draw_line(xs[0] ,ys[0] ,u ,v ,color) u+=dist_x*t v+=dist_y*t i+=t end end #-------------------------------------------------------------------------- # ● 正多角形塗りつぶし #-------------------------------------------------------------------------- #※動作重し #-------------------------------------------------------------------------- # ox : 中心点座標X # oy : 中心点座標Y # vertices: 頂点数(値が 2 以下だと正常に動作しない) # radius : 半径 # rotate : 回転角(ラジアン) # color : 描画色 #-------------------------------------------------------------------------- def fill_polygon(ox ,oy ,vertices ,radius ,rotate=-Math::PI/2 ,color=Color.new(255,255,255)) pi=Math::PI i=rotate j=2*pi/vertices+rotate x1=y1=x2=y2=0 while(i<=2*pi+rotate) x1 = ox+Math.cos(i)*radius y1 = ox+Math.sin(i)*radius x2 = ox+Math.cos(j)*radius y2 = ox+Math.sin(j)*radius fill_triangle([ox,x1,x2],[oy,y1,y2],color) i += 2*pi/vertices j += 2*pi/vertices end end #-------------------------------------------------------------------------- # ● グラフ特化多角形塗りつぶし #-------------------------------------------------------------------------- #※動作重し #-------------------------------------------------------------------------- # # ox : 中心点座標X # oy : 中心点座標Y # param : パラメーター値の配列(値は百分率表示) # radius : 基本半径 # rotate : 回転角(ラジアン) # color : 描画色 #-------------------------------------------------------------------------- def fill_polygon2(ox ,oy ,param ,radius ,rotate=-Math::PI/2 ,color=Color.new(255,255,255)) vertices = param.size pi=Math::PI i=rotate j=2*pi/vertices+rotate x1=y1=x2=y2=0 for t in 0...vertices-1 x1 = ox+Math.cos(i)*radius*(param[t]/100.0) y1 = ox+Math.sin(i)*radius*(param[t]/100.0) x2 = ox+Math.cos(j)*radius*(param[t+1]/100.0) y2 = ox+Math.sin(j)*radius*(param[t+1]/100.0) fill_triangle([ox,x1,x2],[oy,y1,y2],color) i += 2*pi/vertices j += 2*pi/vertices end x1 = ox+Math.cos(i)*radius*(param[t+1]/100.0) y1 = ox+Math.sin(i)*radius*(param[t+1]/100.0) x2 = ox+Math.cos(j)*radius*(param[0]/100.0) y2 = ox+Math.sin(j)*radius*(param[0]/100.0) fill_triangle([ox,x1,x2],[oy,y1,y2],color) end #-------------------------------------------------------------------------- # ● 円塗りつぶし #-------------------------------------------------------------------------- # ox : 中心点座標X # oy : 中心点座標Y # radius: 半径 # color : 描画色 #-------------------------------------------------------------------------- def fill_circle(ox,oy,radius,color=Color.new(255,255,255)) pi=Math::PI t = Accuracy i=0 u=v=0 while(i<=2*pi) u = ox+Math.cos(i)*radius v = oy+Math.sin(i)*radius draw_line(ox ,oy ,u ,v ,color) i += 2*pi*t end end end