import wx import sys # UI's ID ID_RUN = 101 ID_EXIT = 110 TIMER_ID = 120 TIMER_PERIOD = 100 # bounding boxes MAX_COORDINATE = 1200 MIN_COORDINATE = 300 def bounding_box(position_list): #minx = maxx = position_list[0][0] #miny = maxy = position_list[0][1] minx = miny = -MIN_COORDINATE maxx = maxy = MIN_COORDINATE for x,y in position_list: if xmaxx: maxx = x if ymaxy: maxy = y if minx < -MAX_COORDINATE: minx = -MAX_COORDINATE if maxx > MAX_COORDINATE: maxx = MAX_COORDINATE if miny < -MAX_COORDINATE: miny = -MAX_COORDINATE if maxy > MAX_COORDINATE: maxy = MAX_COORDINATE return (minx,miny,maxx,maxy) def draw_balls(dc, ms, qs, position_list): dc.SetPen(wx.Pen("BLACK", 1)) dc.Clear() minx, miny, maxx, maxy = bounding_box(position_list) pw = maxx - minx ph = maxy - miny w,h = dc.GetSize() for (x,y),m,q in zip(position_list,ms,qs): if q>0: dc.SetBrush(wx.Brush("BLUE")) else: dc.SetBrush(wx.Brush("RED")) r = 3 #+ (m/10) dc.DrawCircle(int((x-minx)*w/pw),int((y-miny)*h/ph),r) class MainWindow(wx.Frame): """ We simply derive a new class of Frame. """ def __init__(self, parent, id, title, n, steps, ms, qs, positions): self.n = n self.steps = steps self.ms = ms self.qs = qs self.positions = positions self.current_time = 0 wx.Frame.__init__(self, parent, id, title, size=(500,400)) self.panel = wx.Panel(self) self.panel.Bind(wx.EVT_PAINT, self.OnPaint) self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnLeftClick) self.panel.Bind(wx.EVT_RIGHT_DOWN, self.OnRightClick) self.timer = wx.Timer(self, TIMER_ID) wx.EVT_TIMER(self, TIMER_ID, self.OnTimer) # Setting up the menu. filemenu= wx.Menu() filemenu.Append(ID_RUN, "&Run"," Run the simulation") filemenu.AppendSeparator() filemenu.Append(ID_EXIT,"E&xit"," Terminate the program") # Creating the menubar. menuBar = wx.MenuBar() menuBar.Append(filemenu,"&File") self.SetMenuBar(menuBar) wx.EVT_MENU(self, ID_EXIT, self.OnExitMenu) wx.EVT_MENU(self, ID_RUN, self.OnRunMenu) self.Show(True) def OnExitMenu(self,event): self.Close(True) def OnRunMenu(self,event): self.timer.Start(TIMER_PERIOD) def OnPaint(self,event): dc = wx.PaintDC(event.GetEventObject()) draw_balls(dc,self.ms,self.qs,self.positions[self.current_time]) def OnTimer(self,event): self.current_time += 1 if self.current_time==self.steps: self.current_time = 0 self.Refresh() def OnLeftClick(self,event): if self.timer.IsRunning(): self.timer.Stop() else: self.timer.Start(TIMER_PERIOD) pass def OnRightClick(self,event): self.current_time = 0 pass def read_input_data(filename): fin = open(filename) n_str, s_str = fin.readline().strip().split() n = int(n_str) steps = int(s_str) fin.readline() # ignore dt qs = [] ms = [] for i in range(n): items = fin.readline().strip().split() q = int(items[1]) m = int(items[0]) if q>0: qs.append(+1) else: qs.append(-1) ms.append(m) return (n,steps,ms,qs) def read_snapshot(f,n): l = [] for i in range(n): xs,ys = f.readline().strip().split() l.append((float(xs),float(ys))) f.readline() return l def read_output_data(n,steps,filename): fout = open(filename) positions = {} for i in range(steps): snapshot = read_snapshot(fout,n) positions[i] = snapshot fout.close() return positions def main(): if len(sys.argv)!=3: print 'usage: viewer.py [input_file] [your_output_file]' sys.exit(0) n,steps,ms,qs = read_input_data(sys.argv[1]) positions = read_output_data(n,steps,sys.argv[2]) app = wx.PySimpleApp() frame=MainWindow(None, wx.ID_ANY, 'Ball viewer', n, steps, ms, qs, positions) app.MainLoop() if __name__ == "__main__": main()