Comment detail

2次元ランダムウォーク (Nested Flatten)

貧相ですが,画面上に表示する様にしてみました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
require 'vr/vruby'
require 'vr/vrcontrol'

class RandomWalk
    attr_accessor :x, :y, :trace
    
    def self.next(current)
        rand(2) == 0 ? (current - 1) : (current + 1)
    end
    
    def initialize
        self.trace = []
        self.x = 0
        self.y = 0
    end
    
    def walk(step=10000)
        self.trace = (1..step).map { |_| move }
    end
    
private
    def move
        [:x,:y].map { |p| send("#{p.to_s}=".intern, self.class.next(send(p))) }
    end
end

class RandomWalkPlotter <VRForm
    
    include VRDrawable
    
    WIDTH    = 300
    STEP    = 10000
    
    attr_accessor :scale
    
    def construct
        random_walk
        addControl VRButton, "btn_walk", "walk", 10, 310, 40, 30
        addControl VRButton, "btn_save", "save", 60, 310, 40, 30
        addControl VRButton, "btn_quit", "quit", 240, 310, 40, 30
        move 100, 100, 300, 385
    end
    
    def btn_walk_clicked
        random_walk
        refresh
    end
    
    def btn_save_clicked
        if (file = SWin::CommonDialog::saveFilename(self))
            File.open(file,"w") { |f| (1..trace.size).zip(trace).each { |d| f.puts(d.flatten.join(",")) } }
        end
    end
    
    def btn_quit_clicked
        close
    end
    
    def self_paint
        setPen RGB(0, 0, 0)
        x, y = WIDTH / 2, WIDTH / 2
        trace.each do |p|
            l = [(p[0] * scale).to_i + WIDTH / 2,WIDTH / 2 - (p[1] * scale).to_i]
            drawLine x , y , *l
            x, y = *l
        end
    end
    
    def random_walk
        random_walk = RandomWalk.new
        random_walk.walk STEP
        self.trace = random_walk.trace
    end
    
    def trace=(trace)
        @trace = trace
        self.scale = WIDTH.to_f / (trace.flatten.inject(0) { |m,p| (m < p.abs) ? p.abs : m } * 2)
    end
    
    def trace
        @trace
    end
end

VRLocalScreen.start RandomWalkPlotter

Index

Feed

Other

Link

Pathtraq

loading...