I stumbled across this page about generating random fractal terrain. I went ahead and made a simple wxpython app to put the ideas I learned into practice. Below is the result and source code.
import wx
import math
import random
class Point():
def __init__(self, x, y):
self.X = x
self.Y = y
def RandY(self, displacement):
self.Y = self.Y + (random.uniform(-1,1) * displacement)
class Line():
def __init__(self, p1, p2):
self.P1 = p1
self.P2 = p2
def FindMid(self):
p = Point((self.P1.X + self.P2.X) / 2.0, (self.P1.Y + self.P2.Y) / 2.0)
return p
def Draw(self, dc):
dc.SetPen(wx.Pen(wx.BLACK))
dc.DrawLine(self.P1.X, self.P1.Y, self.P2.X, self.P2.Y)
dc.DrawLine(self.P1.X, self.P1.Y, self.P1.X, 700)
dc.DrawLine(self.P2.X, self.P2.Y, self.P2.X, 700)
def Fractal(line, number, rand, dc):
if number == 0:
line.Draw(dc)
else:
p = line.FindMid()
p.RandY(rand)
rand = rand/2
Fractal(Line(line.P1, p), number-1, rand, dc)
Fractal(Line(p, line.P2), number-1, rand, dc)
class Mountain2D(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title='Fractial Mountain!', style=wx.DEFAULT_FRAME_STYLE & ~wx.RESIZE_BORDER)
self.DrawingPanel = DrawingPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.DrawingPanel, 1, wx.EXPAND|wx.ALL, 5)
self.SetSizer(sizer)
self.Fit()
self.Show(True)
class DrawingPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, id=wx.ID_ANY, size=(600,500), style=wx.SIMPLE_BORDER)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
def OnEraseBackground(self, event):
pass
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self)
self.Draw(dc)
def Draw(self, dc):
dc.SetBrush(wx.WHITE_BRUSH)
dc.DrawRectangle(-1, -1, self.Size.width, self.Size.height)
# Draw the sky
scale = 255.0 / self.Size.height
for i in range(0,self.Size.height):
dc.SetPen(wx.Pen(wx.Colour(0, 255 - int(scale * i), 255 - int(scale * i))))
dc.DrawLine(0, i, self.Size.width, i)
# Draw some stars
for i in range(0,150):
dc.SetPen(wx.Pen(wx.Colour(255, 255, 255)))
dc.SetBrush(wx.Brush(wx.Colour(255, 255, 255), wx.SOLID))
dc.DrawCircle(random.uniform(0, self.Size.width), random.uniform(-1,self.Size.height / 1.5), random.uniform(1, 3))
P1 = Point(self.Size.width * 0.0, self.Size.height * 0.60)
P2 = Point(self.Size.width * 1.0, self.Size.height * 0.60)
LINE = Line(P1, P2)
Fractal(LINE, 10, 200, dc)
if __name__ == '__main__':
app = wx.App(0)
frame = Mountain2D(None)
app.MainLoop()
No comments:
Post a Comment