#!/usr/bin/ruby # coding: utf-8 require 'dxopal' include DXOpal # 箱のサイズ BOX_WIDTH = 600 BOX_HEIGHT = 420 # 定数 R = 8.31 NA = 6.02e23 T = 300 E = 1.00e-3 A = 0.5e-6 Z = 6*3.14159*E*A DT = 1e-7 M = 1.00e-15 DX = 1.00e-10 class BoxMuller def initialize(mu, sigma) @mu = mu @sigma = sigma @r = Random.new @z2 = nil end def rand if @z2 z1 = @z2 @z2 = nil else x = @r.rand y = @r.rand z1 = Math.sqrt(-2.0 * Math.log(x)) * Math.sin(2 * Math::PI * y) @z2 = Math.sqrt(-2.0 * Math.log(x)) * Math.cos(2 * Math::PI * y) end @sigma * z1 + @mu end end # 円を描いて塗りつぶすためのクラスを追加(Imageクラスの継承) # r:半径, color:塗りつぶす色 class CircleImage < Image def initialize(r, color) # 透過に使う色 acolor = C_BLACK super(2 * r, 2 * r, acolor) self.set_color_key(acolor) self.circle_fill(r, r, r, color) #self.box_fill(0,0,r,r,color) end end class Items N = 3 def initialize @items = [] @player = Circle.new(250,200,20,C_YELLOW) @px = [] @py = [] N.times do # 円の初期位置(ランダム) x = rand(BOX_WIDTH-10) y = rand(BOX_HEIGHT-10) # 円の初期速度(ランダム) vx = 0 vy = 0 @items.push(Circle.new(x, y, 50,C_CYAN)) end end def update Sprite.check(@player,@items) Sprite.update([@player]) # Sprite.update(@items) if @px.length >= 500 @px.shift @py.shift end @px.push(@player.cx) @py.push(@player.cy) end def draw Sprite.draw(@items) Sprite.draw([@player]) (1..(@px.length-1)).each do |i| Window.draw_line(@px[i],@py[i],@px[i-1],@py[i-1],C_GREEN) end end def r2 return ((@px[-1] -@px[0])**2+(@py[-1] -@py[0])**2)*DX**2 end end # 円のクラスを追加(Spriteクラスの継承) # x:x座標, y:y座標, r:半径, vx:x方向の速度, vy:y方向の速度, color:塗りつぶす色 class Circle < Sprite def initialize(x, y, r, color) @r = r @bm = BoxMuller.new(0,Math.sqrt(2*Z*R*T/(M**2*NA*DT))) @vx = 0 @vy = 0 super(x, y, CircleImage.new(@r, color)) self.collision = [r, r, r] end # 円の中心のx座標 def cx return self.x + @r end # 円の中心のy座標 def cy return self.y + @r end def update px = @bm.rand py = @bm.rand @vx += (-Z/M*@vx+px)*DT @vy += (-Z/M*@vy+py)*DT # 速度分だけ移動 self.x += @vx/DX*DT self.y += @vy/DX*DT # 壁で跳ね返らせるため速度を反転 if (self.cx - @r < 0 || self.cx + @r > BOX_WIDTH) self.x -= @vx/DX*DT @vx = -@vx end if (self.cy - @r < 0 || self.cy + @r > BOX_HEIGHT) self.y -= @vy/DX*DT @vy = -@vy end end def speed(vx,vy) @vx = 100 @vy = 100 end end Window.load_resources do # フレームレート(デフォルトは60) Window.fps = 100 items = Items.new maxstep = 180 step = maxstep r2 = [] Window.loop do if step > 0 # 移動 items.update step -= 1 else r2.push(items.r2) printf("%d,%g",r2.length,r2.sum/r2.length) items = Items.new step = maxstep end # 描画 Window.draw_box_fill(0, 0, BOX_WIDTH, BOX_HEIGHT, [200, 200, 200]) items.draw # Window.draw_font(100, 100, items.r2,Font.default) # print items.r2.round(6) end end