wxPythonのwx.Panelを使ってマンデルブロ集合を描画
した。wx.PaintDCを使ってPanelの上に描画している。OpenGLのディスプレイリストのような機能がないので(よく探していないので実際はあるかもしれない)、1度の描画にしばらく時間がかかる。なので、計算結果がすぐにみられるようにピクセルの描画の順番を工夫した。ピクセルを左上から右下に順番に描画していくのではなくて、描画処理を2パスに分けて1パス目は
■ | ■ | ■ | |||
■ | ■ | ■ | |||
■ | ■ | ■ | |||
■ | ■ | ■ | |||
■ | ■ | ■ |
の■にあたるピクセルを描画して2パス目はそれ以外を描画、というふうにして結果がすぐにわかるようにした。
# coding: utf-8 import wx class Frame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, "mandelbrot", pos=(0,0),size=(450,450)) self.panel = wx.Panel(self, size=(400,400)) self.resol = self.panel.GetSize() self.panel.Bind(wx.EVT_PAINT, self.OnDraw) self.mandel() def mandel(self): # [(-2.5, -2.0), (+1.5,+2.0)]の矩形で計算 w,h = self.resol self.points = [[0]*w for i in xrange(h)] coef = 30 for i in xrange(h): for j in xrange(w): a = -2.5 + 4./w*j b = -2.0 + 4./h*i c = complex(a, b) z = 0j countup = 0 for k in xrange(coef): z = z*z + c if abs(z) > 1e10: break countup += 1 self.points[i][j] = int(255.0 * countup / coef) def OnDraw(self, event): dc = wx.PaintDC(self.panel) w,h = self.resol """ for i in xrange(h): for j in xrange(w): c = self.points[i][j] dc.SetBrush(wx.Brush(wx.Colour(c, c, c))) dc.DrawPoint(i, j) """ def draw(y, x): c = self.points[y][x] dc.SetPen(wx.Pen(wx.Colour(c,c,c))) dc.DrawPoint(x, y) # . . . . # . . . # . . . . # . . . # ------- # . . . # . . . . # . . . # . . . . # ------- # と塗り分けることで情報の提示を高速化 for i in xrange(h): for j in xrange([0,1][i%2], w, 2): draw(i, j) for i in xrange(h): for j in xrange([1,0][i%2], w, 2): draw(i, j) if __name__ == '__main__': app = wx.PySimpleApp() Frame().Show() app.MainLoop()