#ワイヤー・ポリゴン型 class Draw_3d_2 #初期化 def initialize(width = 640, height = 480) Linebank::seting(width, height) @color = Color.new(255,255,255,255) @chrs = Array.new end #更新 def update return unless @check @check = false Linebank::reset() @chrs.each{|i|i.update} #余ったスプライトの処理 Linebank::remove() end #点描画 def point(x0,y0,z0, number=0,color=@color) pol = Polygon_dot.new pol.x0_3d = x0 pol.y0_3d = y0 pol.z0_3d = z0 pol.number = number pol.color = color pol.dimension = 1 @chrs.push pol @check = true end #線描画 def line(x0,y0,z0, x1,y1,z1, number=0,color=@color) pol = Polygon_line.new pol.x0_3d = x0 pol.y0_3d = y0 pol.z0_3d = z0 pol.x1_3d = x1 pol.y1_3d = y1 pol.z1_3d = z1 pol.number = number pol.color = color pol.dimension = 2 @chrs.push pol @check = true end #三角形描画 def triangle(x0,y0,z0, x1,y1,z1, x2,y2,z2, number=0,color=@color) line(x0, y0, z0, x1, y1, z1, number, color) line(x0, y0, z0, x2, y2, z2, number, color) line(x1, y1, z1, x2, y2, z2, number, color) end #四角形描画 def square(x0,y0,z0, x1,y1,z1, x2,y2,z2, x3,y3,z,number=0,color=@color) line(x0, y0, z0, x1, y1, z1, number, color) line(x0, y0, z0, x2, y2, z2, number, color) line(x1, y1, z1, x3, y3, z, number, color) line(x2, y2, z2, x3, y3, z, number, color) end #矩形描画 def rectangle(x0,y0,z0, width, height, number = 0, color = @color) x1, y1 = x0 + width, y0 + height line(x0, y0, z0, x1, y0, z0, number, color) line(x0, y0, z0, x0, y1, z0, number, color) line(x1, y1, z0, x1, y0, z0, number, color) line(x1, y1, z0, x0, y1, z0, number, color) end #立方体描画 def solidness(x0,y0,z0, width, height, depth, number = 0, color = @color) x1, y1 , z1 = x0 + width, y0 + height, z0 + depth line(x0, y0, z0, x1, y0, z0, number, color) line(x0, y0, z0, x0, y1, z0, number, color) line(x0, y0, z0, x0, y0, z1, number, color) line(x1, y0, z0, x1, y0, z1, number, color) line(x1, y0, z0, x1, y1, z0, number, color) line(x0, y1, z0, x0, y1, z1, number, color) line(x0, y1, z0, x1, y1, z0, number, color) line(x0, y0, z1, x0, y1, z1, number, color) line(x0, y0, z1, x1, y0, z1, number, color) line(x1, y1, z0, x1, y1, z1, number, color) line(x1, y0, z1, x1, y1, z1, number, color) line(x0, y1, z1, x1, y1, z1, number, color) end #三角形ポリゴン描画 def triangle_p(x0,y0,z0, x1,y1,z1, x2,y2,z2,number=0,rev=true,color=@color) pol = Polygon_triangle.new pol.x0_3d = x0 pol.y0_3d = y0 pol.z0_3d = z0 pol.x1_3d = x1 pol.y1_3d = y1 pol.z1_3d = z1 pol.x2_3d = x2 pol.y2_3d = y2 pol.z2_3d = z2 pol.reversible = rev pol.number = number pol.color = color pol.dimension = 3 @chrs.push pol @check = true end #矩形ポリゴン描画 def rectangle_p(x0,y0,z0, width, height, number=0, rev=true, color=@color) pol = Polygon_rectangle.new pol.x0_3d = x0 pol.y0_3d = y0 pol.z0_3d = z0 pol.x1_3d = x0 + width pol.y1_3d = y0 pol.z1_3d = z0 pol.x2_3d = x0 pol.y2_3d = y0+ height pol.z2_3d = z0 pol.reversible = rev pol.number = number pol.color = color pol.dimension = 3 @chrs.push pol @check = true end #立方体ポリゴン描画 def solidness_p(x0,y0,z0, width,height,depth,number=0,rev=false,color=@color) pol = Polygon_solidness.new pol.x0_3d = x0 pol.y0_3d = y0 pol.z0_3d = z0 pol.x1_3d = x0 + width pol.y1_3d = y0 pol.z1_3d = z0 pol.x2_3d = x0 pol.y2_3d = y0 + height pol.z2_3d = z0 pol.x3_3d = x0 pol.y3_3d = y0 pol.z3_3d = z0 + depth pol.reversible = rev pol.number = number pol.color = color pol.dimension = 4 @chrs.push pol @check = true end #四角錐ポリゴン描画 def pyramid_p(x0,y0,z0, length,depth,number=0,rev=false,color=@color) pol = Polygon_pyramid.new pol.x0_3d = x0 pol.y0_3d = y0 pol.z0_3d = z0 pol.x1_3d = x0 + length pol.y1_3d = y0 + length pol.z1_3d = z0 - depth pol.x2_3d = x0 - length pol.y2_3d = y0 - length pol.z2_3d = z0 - depth pol.x3_3d = x0 + length pol.y3_3d = y0 - length pol.z3_3d = z0 - depth pol.reversible = rev pol.number = number pol.color = color pol.dimension = 4 @chrs.push pol @check = true end #ダイヤモンドポリゴン描画 def diamond_p(x0,y0,z0, length,depth,number=0,rev=false,color=@color) pol = Polygon_diamond.new pol.x0_3d = x0 pol.y0_3d = y0 pol.z0_3d = z0 pol.x1_3d = x0 + length pol.y1_3d = y0 + length pol.z1_3d = z0 - depth / 2 pol.x2_3d = x0 - length pol.y2_3d = y0 - length pol.z2_3d = z0 - depth / 2 pol.x3_3d = x0 + length pol.y3_3d = y0 - length pol.z3_3d = z0 - depth / 2 pol.reversible = rev pol.number = number pol.color = color pol.dimension = 4 @chrs.push pol @check = true end #光源配置 def right(x,y,z) z = 1 if x == 0 && y == 0 && z == 0 Linebank::set_right(x,y,z) @check = true end #文字描画 def text(x, y, z, text, number = 0, size =22, color = @color) bitmap = Bitmap.new(1,1) bitmap.font.size = size text_size = bitmap.text_size(text) width = text_size.width height = text_size.height bitmap = Bitmap.new(width, height) bitmap.font.size = size bitmap.font.color = color bitmap.draw_text(0, 0, width, height, text) picture(x, y, z, bitmap, number) end #画像描画 def picture(x, y, z, bitmap, number = 0) sprite = Picture_3d.new sprite.bitmap = bitmap sprite.ox = sprite.bitmap.width / 2 sprite.oy = sprite.bitmap.height / 2 sprite.x0_3d = x sprite.y0_3d = y sprite.z0_3d = z sprite.x1_3d = x + bitmap.width / 2 sprite.y1_3d = y sprite.z1_3d = z sprite.x2_3d = x sprite.y2_3d = y + bitmap.height / 2 sprite.z2_3d = z sprite.number = number sprite.dimension = 3 @chrs.push sprite @check = true end #画像消去 def clear(number = nil) if number == nil @chrs.each{|i|i.dispose} @chrs.clear else @chrs.each{|i|i.dispose if i.number == number} @chrs.reject!{|i|i.number == number} end @check = true end #グループの統合 def join(number1, number2) @chrs.each{|i|i.number = number2 if i.number == number1} end #線移動 def move(vx, vy, vz, number = 0) @chrs.each{|i| if i.number == number i.x0_3d += vx i.y0_3d += vy i.z0_3d += vz if i.dimension >= 2 i.x1_3d += vx i.y1_3d += vy i.z1_3d += vz end if i.dimension >= 3 i.x2_3d += vx i.y2_3d += vy i.z2_3d += vz end if i.dimension == 4 i.x3_3d += vx i.y3_3d += vy i.z3_3d += vz end end } @check = true end #X軸回転 def roll_x(rad, number = 0, ox = nil, oy = nil, oz = nil) rad = rad * Math::PI / 180 @chrs.each{|i| if i.number == number oy = i.y0_3d if oy == nil oz = i.z0_3d if oz == nil a = i.y0_3d - oy b = i.z0_3d - oz i.y0_3d = a*Math.cos(rad) + b*Math.sin(rad) + oy i.z0_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oz if i.dimension >= 2 a = i.y1_3d - oy b = i.z1_3d - oz i.y1_3d = a*Math.cos(rad) + b*Math.sin(rad) + oy i.z1_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oz end if i.dimension >= 3 a = i.y2_3d - oy b = i.z2_3d - oz i.y2_3d = a*Math.cos(rad) + b*Math.sin(rad) + oy i.z2_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oz end if i.dimension == 4 a = i.y3_3d - oy b = i.z3_3d - oz i.y3_3d = a*Math.cos(rad) + b*Math.sin(rad) + oy i.z3_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oz end end } @check = true end #Y軸回転 def roll_y(rad, number = 0, ox = nil, oy = nil, oz = nil) rad = rad * Math::PI / 180 @chrs.each{|i| if i.number == number ox = i.x0_3d if ox == nil oz = i.z0_3d if oz == nil a = i.x0_3d - ox b = i.z0_3d - oz i.x0_3d = a*Math.cos(rad) + b*Math.sin(rad) + ox i.z0_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oz if i.dimension >= 2 a = i.x1_3d - ox b = i.z1_3d - oz i.x1_3d = a*Math.cos(rad) + b*Math.sin(rad) + ox i.z1_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oz end if i.dimension >= 3 a = i.x2_3d - ox b = i.z2_3d - oz i.x2_3d = a*Math.cos(rad) + b*Math.sin(rad) + ox i.z2_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oz end if i.dimension == 4 a = i.x3_3d - ox b = i.z3_3d - oz i.x3_3d = a*Math.cos(rad) + b*Math.sin(rad) + ox i.z3_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oz end end } @check = true end #Z軸回転 def roll_z(rad, number = 0, ox = nil, oy = nil, oz = nil) rad = rad * Math::PI / 180 @chrs.each{|i| if i.number == number ox = i.x0_3d if ox == nil oy = i.y0_3d if oy == nil a = i.x0_3d - ox b = i.y0_3d - oy i.x0_3d = a*Math.cos(rad) + b*Math.sin(rad) + ox i.y0_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oy if i.dimension >= 2 a = i.x1_3d - ox b = i.y1_3d - oy i.x1_3d = a*Math.cos(rad) + b*Math.sin(rad) + ox i.y1_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oy end if i.dimension >= 3 a = i.x2_3d - ox b = i.y2_3d - oy i.x2_3d = a*Math.cos(rad) + b*Math.sin(rad) + ox i.y2_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oy end if i.dimension == 4 a = i.x3_3d - ox b = i.y3_3d - oy i.x3_3d = a*Math.cos(rad) + b*Math.sin(rad) + ox i.y3_3d = -a*Math.sin(rad) + b*Math.cos(rad) + oy end end } @check = true end end #線情報の一括制御 module Linebank @lines = Array.new def self.seting(width, height) @width = width @height = height @vanish_x = @width / 2 @vanish_y = @height / 2 @vanish_z = -1*[@width, @height].max @fz = -@vanish_z / 2 @color = Color.new(255,255,255,255) @bitmap = Bitmap.new(1,1) @bitmap.fill_rect(0, 0, 1, 1, @color) @viewport = Viewport.new(0,0,width, height) @right_x = 0 @right_y = 0 @right_z = 1 end def self.set_right(x,y,z) @right_x = x @right_y = y @right_z = z end def self.line @pointer += 1 if @lines[@pointer] == nil @lines[@pointer] = Sprite.new(@viewport) @lines[@pointer].bitmap = @bitmap end @lines[@pointer] end def self.reset @pointer = -1 end def self.remove while @pointer < @lines.size-1 @pointer += 1 @lines[@pointer].x = -@width @lines[@pointer].y = -@height end end def self.clear @lines.each{|i|@dispose} @lines.clear end def self.viewport @viewport end def self.width @width end def self.height @height end def self.vanish_x @vanish_x end def self.vanish_y @vanish_y end def self.vanish_z @vanish_z end def self.fz @fz end def self.right_x @right_x end def self.right_y @right_y end def self.right_z @right_z end end #ポリゴン土台 class Polygon_base attr_accessor :number #所属グループ attr_accessor :color #描画色 attr_accessor :dimension #次元 def update @vanish_x = Linebank::vanish_x @vanish_y = Linebank::vanish_y @vanish_z = Linebank::vanish_z @width = Linebank::width @height = Linebank::height @fz = Linebank::fz end def dispose return end end #点 class Polygon_dot < Polygon_base attr_accessor :x0_3d #3D空間での1点目X座標 attr_accessor :y0_3d #3D空間での1点目Y座標 attr_accessor :z0_3d #3D空間での1点目Z座標 def update super() x0, y0, z0 = @x0_3d, @y0_3d, @z0_3d x0 += (@vanish_x - x0) * z0 / (@vanish_z + z0) y0 += (@vanish_y - y0) * z0 / (@vanish_z + z0) return if x0 < 0 || x0 > @width || y0 < 0 || y0 > @height || z0 > @fz line = Linebank::line line.x = x0 line.y = y0 line.z = z0 line.zoom_x = 1 line.zoom_y = 1 line.color = @color line.opacity = @color.alpha end end #線 class Polygon_line < Polygon_base attr_accessor :x0_3d #3D空間での1点目X座標 attr_accessor :y0_3d #3D空間での1点目Y座標 attr_accessor :z0_3d #3D空間での1点目Z座標 attr_accessor :x1_3d #3D空間での2点目X座標 attr_accessor :y1_3d #3D空間での2点目Y座標 attr_accessor :z1_3d #3D空間での2点目Z座標 def update super() x0,y0,z0,x1,y1,z1 = @x0_3d,@y0_3d,@z0_3d,@x1_3d,@y1_3d,@z1_3d return if z0 > @fz && z1 > @fz if z0 > @fz x0,y0,z0 = (@fz-z0)*(x1-x0)/(z1-z0)+x0,(@fz-z0)*(y1-y0)/(z1-z0)+y0,@fz end if z1 > @fz x1,y1,z1 = (@fz-z1)*(x0-x1)/(z0-z1)+x1,(@fz-z1)*(y0-y1)/(z0-z1)+y1,@fz end x0 += (@vanish_x - x0) * z0 / (@vanish_z + z0) y0 += (@vanish_y - y0) * z0 / (@vanish_z + z0) x1 += (@vanish_x - x1) * z1 / (@vanish_z + z1) y1 += (@vanish_y - y1) * z1 / (@vanish_z + z1) x0 = x0.round y0 = y0.round x1 = x1.round y1 = y1.round return if (x0<0&&x1<0)||(y0<0&&y1<0)|| (x0>@width&&x1>@width)||(y0>@height&&y1>@height) if x1 != x0 x0,y0 = 0, -x0*(y1-y0)/(x1-x0) + y0 if x0 < 0 x1,y1 = 0, -x1*(y0-y1)/(x0-x1) + y1 if x1 < 0 x0,y0 = @width, (@width-x0)*(y1-y0)/(x1-x0) + y0 if x0 > @width x1,y1 = @width, (@width-x1)*(y0-y1)/(x0-x1) + y1 if x1 > @width end if y1 != y0 x0,y0 = -y0*(x1-x0)/(y1-y0) + x0, 0 if y0 < 0 x1,y1 = -y1*(x0-x1)/(y0-y1) + x1, 0 if y1 < 0 x0,y0 = (@height-y0)*(x1-x0)/(y1-y0) + x0, @height if y0 > @height x1,y1 = (@height-y1)*(x0-x1)/(y0-y1) + x1, @height if y1 > @height end line = Linebank::line line.x = x0 line.y = y0 line.z = z0 line.color = @color line.opacity = @color.alpha line.zoom_x = Math.hypot(y1 - y0, x1 - x0) line.zoom_y = 1 a = (x1 - x0).abs * 1.0 b = (y1 - y0).abs * 1.0 a *= -1 if x0 >= x1 b *= -1 if y0 <= y1 line.angle = Math.atan2(b, a) / 0.01745 end end #三角 class Polygon_triangle < Polygon_base attr_accessor :x0_3d #3D空間での1点目X座標 attr_accessor :y0_3d #3D空間での1点目Y座標 attr_accessor :z0_3d #3D空間での1点目Z座標 attr_accessor :x1_3d #3D空間での2点目X座標 attr_accessor :y1_3d #3D空間での2点目Y座標 attr_accessor :z1_3d #3D空間での2点目Z座標 attr_accessor :x2_3d #3D空間での3点目X座標 attr_accessor :y2_3d #3D空間での3点目Y座標 attr_accessor :z2_3d #3D空間での3点目Z座標 attr_accessor :reversible #ポリゴン両面描画判定 def update super() x0,y0,z0,x1,y1,z1,x2,y2,z2 = @x0_3d,@y0_3d,@z0_3d,@x1_3d,@y1_3d,@z1_3d,@x2_3d,@y2_3d,@z2_3d x0 += (@vanish_x - x0) * z0 / (@vanish_z + z0) y0 += (@vanish_y - y0) * z0 / (@vanish_z + z0) x1 += (@vanish_x - x1) * z1 / (@vanish_z + z1) y1 += (@vanish_y - y1) * z1 / (@vanish_z + z1) x2 += (@vanish_x - x2) * z2 / (@vanish_z + z2) y2 += (@vanish_y - y2) * z2 / (@vanish_z + z2) x0 = x0.round y0 = y0.round x1 = x1.round y1 = y1.round x2 = x2.round y2 = y2.round return if z0 > @fz || z1 > @fz || z2 > @fz color = getcolor(x0,x1,x2, y0,y1,y2 ,z0,z1,z2) draw_triangle(x0,x1,x2, y0,y1,y2 ,z0,z1,z2, color) end #色の変化 def getcolor(x0,x1,x2, y0,y1,y2 ,z0,z1,z2) right_x = Linebank::right_x right_y = Linebank::right_y right_z = Linebank::right_z #法線ベクトル作成 b1, b2, b3 = x0 - x1, y0 - y1, z0 - z1 a1, a2, a3 = x2 - x1, y2 - y1, z2 - z1 n1, n2, n3 = b3*a2 - b2*a3, b1*a3 - b3*a1, b2*a1 - b1*a2 l = Math.sqrt(n1*n1 + n2*n2 + n3*n3) #長さ1の法線ベクトル n1, n2, n3 = n1/l, n2/l, n3/l #表裏判定 if @reversible n1,n2,n3 = n1*-1, n2*-1, n3*-1 if n3 < 0 else return Color.new(0,0,0,0) if n3 < 0 end #光源処理 l = Math.sqrt(right_x**2+right_y**2+right_z**2) m1, m2, m3 = right_x/l, right_y/l, right_z/l ns = n1*m1+n2*m2+n3*m3 r1 = Math.sqrt(n1*n1+n2*n2+n3*n3) r2 = Math.sqrt(m1*m1+m2*m2+m3*m3) theta = Math.acos(ns/r1/r2) *2 pi = Math::PI red = @color.red * pi / (pi + theta) green = @color.green * pi / (pi + theta) blue = @color.blue * pi / (pi + theta) alpha = @color.alpha color = Color.new(red,green,blue,alpha) end #三角塗りつぶし def draw_triangle(x0,x1,x2, y0,y1,y2 ,z0,z1,z2, color) width = [(x0-x1).abs, (x2-x1).abs, (x0-x2).abs].max height = [(y0-y1).abs, (y2-y1).abs, (y0-y2).abs].max dim = false range = height a0,b0,a1,b1,a2,b2 = [[y0,x0],[y1,x1],[y2,x2]].sort!.flatten! if width < height dim = true range = width a0,b0,a1,b1,a2,b2 = [[x0,y0],[x1,y1],[x2,y2]].sort!.flatten! end for i in 0..range run = a0 + i if run <= a1 c0 = a1 == a0 ? [b1,b0].min : ((run-a0)*(b1-b0)/(a1-a0) + b0) else c0 = a1 == a2 ? [b1,b2].min : ((run-a2)*(b1-b2)/(a1-a2) + b2) end if run <= a2 c1 = a2 == a0 ? [b2,b0].min : ((run-a0)*(b2-b0)/(a2-a0) + b0) else c1 = a2 == a1 ? [a2,a1].min : ((run-a1)*(b2-b1)/(a2-a1) + b1) end next if i > 0 && c0 == c1 c0, c1 = c1, c0 if c0 > c1 line = Linebank::line if dim line.x = run line.y = c0 line.zoom_x = 1 line.zoom_y = c1 - c0 + 1 else line.x = c0 line.y = run line.zoom_x = c1 - c0 + 1 line.zoom_y = 1 end line.z = (z0 + z1 + z2)/3 line.color = color line.opacity = color.alpha line.angle = 0 end end #四角塗りつぶし def draw_rectangle(x0,x1,x2,x3,y0,y1,y2,y3,z0,z1,z2,z3,color) width = [x0,x1,x2,x3].max - [x0,x1,x2,x3].min height = [y0,y1,y2,y3].max - [y0,y1,y2,y3].min dim = false range = height case [y0,y1,y2,y3].min when y0 a0,a1,a2,a3,b0,b1,b2,b3 = y0,y1,y2,y3,x0,x1,x2,x3 when y1 a0,a1,a2,a3,b0,b1,b2,b3 = y1,y0,y3,y2,x1,x0,x3,x2 when y2 a0,a1,a2,a3,b0,b1,b2,b3 = y2,y0,y3,y1,x2,x0,x3,x1 when y3 a0,a1,a2,a3,b0,b1,b2,b3 = y3,y1,y2,y0,x3,x1,x2,x0 end if width < height dim = true range = width case [x0,x1,x2,x3].min when x0 a0,a1,a2,a3,b0,b1,b2,b3 = x0,x1,x2,x3,y0,y1,y2,y3 when x1 a0,a1,a2,a3,b0,b1,b2,b3 = x1,x0,x3,x2,y1,y0,y3,y2 when x2 a0,a1,a2,a3,b0,b1,b2,b3 = x2,x0,x3,x1,y2,y0,y3,y1 when x3 a0,a1,a2,a3,b0,b1,b2,b3 = x3,x1,x2,x0,y3,y1,y2,y0 end end for i in 0..range run = a0 + i if run <= a1 c0 = a1 == a0 ? [b1,b0].min : ((run-a0)*(b1-b0)/(a1-a0) + b0) elsif run <= a3 c0 = a1 == a3 ? [b1,b3].min : ((run-a3)*(b1-b3)/(a1-a3) + b3) else c0 = a2 == a3 ? [b2,b3].min : ((run-a3)*(b2-b3)/(a2-a3) + b3) end if run <= a2 c1 = a2 == a0 ? [b2,b0].min : ((run-a0)*(b2-b0)/(a2-a0) + b0) elsif run <= a3 c1 = a2 == a3 ? [a2,a3].min : ((run-a3)*(b2-b3)/(a2-a3) + b3) else c1 = a1 == a3 ? [a1,a3].min : ((run-a3)*(b1-b3)/(a1-a3) + b3) end next if i > 0 && c0 == c1 c0,c1 = c1,c0 if c0 > c1 line = Linebank::line if dim line.x = run line.y = c0 line.zoom_x = 1 line.zoom_y = c1-c0 + 1 else line.x = c0 line.y = run line.zoom_x = c1-c0 + 1 line.zoom_y = 1 end line.z = (z0 + z1 + z2 + z3)/4 line.color = color line.opacity = color.alpha line.angle = 0 end end end #矩形 class Polygon_rectangle < Polygon_triangle def update @vanish_x = Linebank::vanish_x @vanish_y = Linebank::vanish_y @vanish_z = Linebank::vanish_z @width = Linebank::width @height = Linebank::height @fz = Linebank::fz x0,y0,z0, x1,y1,z1, x2,y2,z2 = @x0_3d,@y0_3d,@z0_3d, @x1_3d,@y1_3d,@z1_3d, @x2_3d,@y2_3d,@z2_3d x3, y3 = x2 + x1 - x0, y1 + y2 - y0 z3 = z2 + z1 - z0 x0 += (@vanish_x - x0) * z0 / (@vanish_z + z0) y0 += (@vanish_y - y0) * z0 / (@vanish_z + z0) x1 += (@vanish_x - x1) * z1 / (@vanish_z + z1) y1 += (@vanish_y - y1) * z1 / (@vanish_z + z1) x2 += (@vanish_x - x2) * z2 / (@vanish_z + z2) y2 += (@vanish_y - y2) * z2 / (@vanish_z + z2) x3 += (@vanish_x - x3) * z3 / (@vanish_z + z3) y3 += (@vanish_y - y3) * z3 / (@vanish_z + z3) x0 = x0.round y0 = y0.round x1 = x1.round y1 = y1.round x2 = x2.round y2 = y2.round x3 = x3.round y3 = y3.round return if z0 > @fz || z1 > @fz || z2 > @fz color = getcolor(x0,x1,x2, y0,y1,y2 ,z0,z1,z2) draw_rectangle(x0,x1,x2,x3,y0,y1,y2,y3,z0,z1,z2,z3,color)if color.alpha > 0 end end #立方体 class Polygon_solidness < Polygon_triangle attr_accessor :x3_3d #3D空間での4点目X座標 attr_accessor :y3_3d #3D空間での4点目Y座標 attr_accessor :z3_3d #3D空間での4点目Z座標 def update @vanish_x = Linebank::vanish_x @vanish_y = Linebank::vanish_y @vanish_z = Linebank::vanish_z @fz = Linebank::fz x0,y0,z0 = @x0_3d,@y0_3d,@z0_3d x1,y1,z1, x2,y2,z2 = @x1_3d,@y1_3d,@z1_3d, @x2_3d,@y2_3d,@z2_3d x3, y3, z3 = x2 + x1 - x0, y1 + y2 - y0, z2 + z1 - z0 solidset(x0,x1,x2, y0,y1,y2 ,z0,z1,z2) x1,y1,z1, x2,y2,z2 = @x3_3d,@y3_3d,@z3_3d, @x1_3d,@y1_3d,@z1_3d x4, y4, z4 = x2 + x1 - x0, y1 + y2 - y0, z2 + z1 - z0 solidset(x0,x1,x2, y0,y1,y2 ,z0,z1,z2) x1,y1,z1, x2,y2,z2 = @x2_3d,@y2_3d,@z2_3d, @x3_3d,@y3_3d,@z3_3d x5, y5, z5 = x2 + x1 - x0, y1 + y2 - y0, z2 + z1 - z0 solidset(x0,x1,x2, y0,y1,y2 ,z0,z1,z2) x0,y0,z0 = @x1_3d,@y1_3d,@z1_3d solidset(x0,x4,x3, y0,y4,y3 ,z0,z4,z3) x0,y0,z0 = @x2_3d,@y2_3d,@z2_3d solidset(x0,x3,x5, y0,y3,y5 ,z0,z3,z5) x0,y0,z0 = @x3_3d,@y3_3d,@z3_3d solidset(x0,x5,x4, y0,y5,y4 ,z0,z5,z4) end def solidset(x0,x1,x2, y0,y1,y2 ,z0,z1,z2) x3, y3, z3 = x2 + x1 - x0, y1 + y2 - y0, z2 + z1 - z0 x0 += (@vanish_x - x0) * z0 / (@vanish_z + z0) y0 += (@vanish_y - y0) * z0 / (@vanish_z + z0) x1 += (@vanish_x - x1) * z1 / (@vanish_z + z1) y1 += (@vanish_y - y1) * z1 / (@vanish_z + z1) x2 += (@vanish_x - x2) * z2 / (@vanish_z + z2) y2 += (@vanish_y - y2) * z2 / (@vanish_z + z2) x3 += (@vanish_x - x3) * z3 / (@vanish_z + z3) y3 += (@vanish_y - y3) * z3 / (@vanish_z + z3) x0 = x0.round y0 = y0.round x1 = x1.round y1 = y1.round x2 = x2.round y2 = y2.round x3 = x3.round y3 = y3.round return if z0 > @fz || z1 > @fz || z2 > @fz color = getcolor(x0,x1,x2, y0,y1,y2 ,z0,z1,z2) draw_rectangle(x0,x1,x2,x3,y0,y1,y2,y3,z0,z1,z2,z3,color)if color.alpha > 0 end end #四角錐 class Polygon_pyramid < Polygon_solidness def update @vanish_x = Linebank::vanish_x @vanish_y = Linebank::vanish_y @vanish_z = Linebank::vanish_z @fz = Linebank::fz x0,y0,z0, x1,y1,z1, x2,y2,z2, x3,y3,z3 = @x0_3d,@y0_3d,@z0_3d, @x1_3d,@y1_3d,@z1_3d, @x2_3d,@y2_3d,@z2_3d, @x3_3d,@y3_3d,@z3_3d x4,y4,z4 = x2 + x1 - x3, y1 + y2 - y3, z2 + z1 - z3 pyrset(x0,x3,x1, y0,y3,y1 ,z0,z3,z1) pyrset(x0,x1,x4, y0,y1,y4 ,z0,z1,z4) pyrset(x0,x4,x2, y0,y4,y2 ,z0,z4,z2) pyrset(x0,x2,x3, y0,y2,y3 ,z0,z2,z3) solidset(x3,x2,x1, y3,y2,y1 ,z3,z2,z1) end def pyrset(x0,x1,x2, y0,y1,y2 ,z0,z1,z2) x0 += (@vanish_x - x0) * z0 / (@vanish_z + z0) y0 += (@vanish_y - y0) * z0 / (@vanish_z + z0) x1 += (@vanish_x - x1) * z1 / (@vanish_z + z1) y1 += (@vanish_y - y1) * z1 / (@vanish_z + z1) x2 += (@vanish_x - x2) * z2 / (@vanish_z + z2) y2 += (@vanish_y - y2) * z2 / (@vanish_z + z2) x0 = x0.round y0 = y0.round x1 = x1.round y1 = y1.round x2 = x2.round y2 = y2.round return if z0 > @fz || z1 > @fz || z2 > @fz color = getcolor(x0,x1,x2, y0,y1,y2 ,z0,z1,z2) draw_triangle(x0,x1,x2,y0,y1,y2,z0,z1,z2,color)if color.alpha > 0 end end #ダイヤモンド class Polygon_diamond < Polygon_pyramid def update @vanish_x = Linebank::vanish_x @vanish_y = Linebank::vanish_y @vanish_z = Linebank::vanish_z @fz = Linebank::fz x0,y0,z0, x1,y1,z1, x2,y2,z2, x3,y3,z3 = @x0_3d,@y0_3d,@z0_3d, @x1_3d,@y1_3d,@z1_3d, @x2_3d,@y2_3d,@z2_3d, @x3_3d,@y3_3d,@z3_3d x4,y4,z4 = x2 + x1 - x3, y1 + y2 - y3, z2 + z1 - z3 x5,y5,z5 = x2 + x1 - x0, y1 + y2 - y0, z2 + z1 - z0 pyrset(x0,x3,x1, y0,y3,y1 ,z0,z3,z1) pyrset(x0,x1,x4, y0,y1,y4 ,z0,z1,z4) pyrset(x0,x4,x2, y0,y4,y2 ,z0,z4,z2) pyrset(x0,x2,x3, y0,y2,y3 ,z0,z2,z3) pyrset(x5,x1,x3, y5,y1,y3 ,z5,z1,z3) pyrset(x5,x4,x1, y5,y4,y1 ,z5,z4,z1) pyrset(x5,x2,x4, y5,y2,y4 ,z5,z2,z4) pyrset(x5,x3,x2, y5,y3,y2 ,z5,z3,z2) end end #画像 class Picture_3d < Sprite attr_accessor :x0_3d #3D空間での1点目X座標 attr_accessor :y0_3d #3D空間での1点目Y座標 attr_accessor :z0_3d #3D空間での1点目Z座標 attr_accessor :x1_3d #3D空間での2点目X座標 attr_accessor :y1_3d #3D空間での2点目Y座標 attr_accessor :z1_3d #3D空間での2点目Z座標 attr_accessor :x2_3d #3D空間での3点目X座標 attr_accessor :y2_3d #3D空間での3点目Y座標 attr_accessor :z2_3d #3D空間での3点目Z座標 attr_accessor :number #所属グループ attr_accessor :dimension #次元 def initialize super(Linebank::viewport) end def update @vanish_x = Linebank::vanish_x @vanish_y = Linebank::vanish_y @vanish_z = Linebank::vanish_z @fz = Linebank::fz x0,y0,z0,x1,y1,z1,x2,y2,z2 = @x0_3d,@y0_3d,@z0_3d,@x1_3d,@y1_3d,@z1_3d,@x2_3d,@y2_3d,@z2_3d x0 += (@vanish_x - x0) * z0 / (@vanish_z + z0) y0 += (@vanish_y - y0) * z0 / (@vanish_z + z0) x1 += (@vanish_x - x1) * z1 / (@vanish_z + z1) y1 += (@vanish_y - y1) * z1 / (@vanish_z + z1) x2 += (@vanish_x - x2) * z2 / (@vanish_z + z2) y2 += (@vanish_y - y2) * z2 / (@vanish_z + z2) x0 = x0.round y0 = y0.round x1 = x1.round y1 = y1.round x2 = x2.round y2 = y2.round if z0 > @fz || z1 > @fz || z2 > @fz self.zoom_x = 0 self.zoom_y = 0 return end self.x = x0 self.y = y0 self.z = z0 a = (x1 - x2).abs / 2.0 b = (y1 - y2).abs / 2.0 a *= -1 if x2 >= x1 b *= -1 if y2 <= y1 self.angle = Math.atan2(b, a) / Math::PI * 180 self.zoom_x = Math.hypot(x1-x2,y1-y2)*2.0/self.bitmap.width self.zoom_y = Math.hypot(x0-x2,y0-y2)*2.0/self.bitmap.height self.mirror = ((x1-x2)*(y2-y0)>0 || (y2-y1)*(x2-x0)>0) ? false : true self.angle += 180 if self.mirror end end