今回はなんちゃって離散ボロノイ図の描画(描画は完全にいつものやつ)です。全然厳密ではないので、実行結果を見て楽しむぐらいしかできません。
ソースコード
class Voronoi
POINT_TYPE = {
:nomal => 0,
:generator => 1,
:border => 2
}
def initialize(i, j, generators)
@i_size, @j_size = i, j
@generators = generators
@points = Array.new(@i_size) do
Array.new(@j_size) { POINT_TYPE[:nomal] }
end
@generators.each do |i, j|
@points[i][j] = POINT_TYPE[:generator]
end
end
def exec
@i_size.times.to_a.product(@j_size.times.to_a) do |i, j|
@generators.map do |gi, gj|
Math.sqrt( ((i-gi)**2) + ((j-gj)**2) )
end
.sort.tap do |ary|
if (ary[0] - ary[1]).abs < 0.9
@points[i][j] = POINT_TYPE[:border]
puts self
printf "\e[#{@i_size + 1}A"; STDOUT.flush; #sleep 0.1
end
end
end
puts self
rescue Interrupt
exit 0
end
def to_s
"\n" << @points.map do |line|
" " << line.map do |point|
case point
when POINT_TYPE[:nomal] then "\e[47m \e[0m"
when POINT_TYPE[:generator] then "\e[41m \e[0m"
when POINT_TYPE[:border] then "\e[46m \e[0m"
end
end.join("")
end.join("\n")
end
end
generators = [
[8, 2], [6, 26], [30, 20], [35, 5], [20, 10], [20, 33]
]
voronoi = Voronoi.new(40, 40, generators)
voronoi.exec実行結果
赤が母点、青が境界を表しています。楽しい。
図1 voronoi.rb 実行結果
おわりに
今やりたいことでボロノイ図が必要だったのですが、正しい点が求められているか確認するため境界線だけわかればよかったので、そのようなコードを書いてみました。とは言え図1のようでは線が粗いので、全く同じ処理でマス目を10等分した版をgnuplotで出力してみました(図2)。ちゃんと線に見えるのでとりあえずこれでいいかなという感じです。(ちゃんとしたボロノイ図もいつかやってみたい)
図2 gnuplotの出力結果
0 件のコメント:
コメントを投稿