def run_pinballview(width, height, configuration): """ Changed from original Pierre-Luc Bacon implementation to reflect the visualization changes in the PinballView Class. """ width, height = float(width), float(height) master = Tk() master.title('RLPY Pinball') screen = Canvas(master, width=500.0, height=500.0) screen.configure(background='LightGray') screen.pack() environment = PinballModel(configuration) environment_view = PinballView(screen, width, height, environment) actions = [ PinballModel.ACC_X, PinballModel.DEC_Y, PinballModel.DEC_X, PinballModel.ACC_Y, PinballModel.ACC_NONE ] done = False while not done: user_action = np.random.choice(actions) environment_view.blit() if environment.episode_ended(): done = True if environment.take_action(user_action) == environment.END_EPISODE: done = True environment_view.blit() screen.update()
def plot_results(self): grid_x = (self.canvas_width - 2 * self.canvas_margin) / (self.grid_size) grid_y = (self.canvas_height - 2 * self.canvas_margin) / (self.grid_size) pin_dx = grid_x / 6 pin_dy = grid_y / 6 master = Tk() w = Canvas(master, width=self.canvas_width, height=self.canvas_height) w.pack() for node in self.graph: i, j = self.id_to_coord(node) if node[-1] == 's': i += 0.5 j += 0.5 nx, ny = self.get_xy(i, j) if node[-1] == 's': fill_col = 'green' w.create_rectangle(nx - pin_dx, ny - pin_dy, nx + pin_dx, ny + pin_dy, fill=fill_col) else: fill_col = 'black' w.create_oval(nx - 2, ny - 2, nx + 2, ny + 2, fill=fill_col) self.draw_routes(w) w.update() w.postscript(file='sol35.ps', colormode='color') mainloop()
class Wall(object): MIN_RED = MIN_GREEN = MIN_BLUE = 0x0 MAX_RED = MAX_GREEN = MAX_BLUE = 0xFF PIXEL_WIDTH = 96 def __init__(self, width, height): self.width = width self.height = height self._tk_init() self.pixels = [(0, 0, 0) for i in range(self.width * self.height)] def _tk_init(self): self.root = Tk() self.root.title("ColorWall %d x %d" % (self.width, self.height)) self.root.resizable(0, 0) self.frame = Frame(self.root, bd=5, relief=SUNKEN) self.frame.pack() self.canvas = Canvas(self.frame, width=self.PIXEL_WIDTH * self.width, height=self.PIXEL_WIDTH * self.height, bd=0, highlightthickness=0) self.canvas.pack() self.root.update() def set_pixel(self, x, y, hsv): self.pixels[self.width * y + x] = hsv def get_pixel(self, x, y): return self.pixels[self.width * y + x] def draw(self): self.canvas.delete(ALL) for x in range(len(self.pixels)): x_0 = (x % self.width) * self.PIXEL_WIDTH y_0 = (x / self.width) * self.PIXEL_WIDTH x_1 = x_0 + self.PIXEL_WIDTH y_1 = y_0 + self.PIXEL_WIDTH hue = "#%02x%02x%02x" % self._get_rgb(self.pixels[x]) self.canvas.create_rectangle(x_0, y_0, x_1, y_1, fill=hue) self.canvas.update() def clear(self): for i in range(self.width * self.height): self.pixels[i] = (0, 0, 0) def _hsv_to_rgb(self, hsv): rgb = colorsys.hsv_to_rgb(*hsv) red = self.MAX_RED * rgb[0] green = self.MAX_GREEN * rgb[1] blue = self.MAX_BLUE * rgb[2] return (red, green, blue) def _get_rgb(self, hsv): red, green, blue = self._hsv_to_rgb(hsv) red = int(float(red) / (self.MAX_RED - self.MIN_RED) * 0xFF) green = int(float(green) / (self.MAX_GREEN - self.MIN_GREEN) * 0xFF) blue = int(float(blue) / (self.MAX_BLUE - self.MIN_BLUE) * 0xFF) return (red, green, blue)
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.x0=[x*0.1 for x in range(10, 15)] self.y0=[0 for x in range(10, 15)] #self.tet1 = [i for i in range(90)] #self.tet2 = [i for i in range(45, 135)] self.tet1_con = 0 self.tet2_con = 0 self.count1 = 0 self.count2 = 0 self.sign1 = 1 self.sign2 = -1 self.parent = parent self.initUI() self.parent.after(0, self.animation) def initUI(self): self.parent.title("Arm") self.pack(fill=BOTH, expand=1) self.canvas = Canvas(self) #self.canvas.create_line(0, 0, 200, 100+self.count, width=arm_width) line = Line(self.canvas, points['1'], (800/2, 400)) arms.append(line) line = Line(self.canvas, 90-(points['2']-points['1']), line.cor1) arms.append(line) self.canvas.pack(fill=BOTH, expand=1) def animation(self): self.canvas.delete("all") #self.canvas.create_line(0, 0, 200, 100+self.count, width=arm_width) '''if points['1'] > 90 and self.sign1 == 1: self.sign1 = -1 elif points['1'] == 45 and self.sign1 == -1: self.sign1 = 1 if points['2'] > 135 and self.sign2 == 1: self.sign2 = -1 elif points['2'] == 90 and self.sign2 == -1: self.sign2 = 1 points['2']+=self.sign2 points['1']+=self.sign1''' if self.count1 >= len(self.x0) and self.sign1 == 1: self.sign1 = -1 if self.count1 <= 0 and self.sign1 == -1: self.sign1 = 1 self.count1+=self.sign1 tet1, tet2 = getAngles(self.x0[self.count1-1], self.y0[self.count1-1]) print tet1, tet2 line = arms[0].draw(tet1) arms[1].draw(90-(tet2+tet1), line, 'red') #line = arms[0].draw(points['1']) #arms[1].draw(90-(points['2']-points['1']), line) self.canvas.update() #self.count +=1 self.parent.after(50, self.animation)
def run_pinballview(width, height, configuration): """ Changed from original Pierre-Luc Bacon implementation to reflect the visualization changes in the PinballView Class. """ width, height = float(width), float(height) master = Tk() master.title('RLPY Pinball') screen = Canvas(master, width=500.0, height=500.0) screen.configure(background='LightGray') screen.pack() environment = PinballModel(configuration) environment_view = PinballView(screen, width, height, environment) actions = [ PinballModel.ACC_X, PinballModel.DEC_Y, PinballModel.DEC_X, PinballModel.ACC_Y, PinballModel.ACC_NONE] done = False while not done: user_action = np.random.choice(actions) environment_view.blit() if environment.episode_ended(): done = True if environment.take_action(user_action) == environment.END_EPISODE: done = True environment_view.blit() screen.update()
def xGC_skew(seq, window=1000, zoom=100, r=300, px=100, py=100): """Calculates and plots normal and accumulated GC skew (GRAPHICS !!!).""" from Tkinter import Scrollbar, Canvas, BOTTOM, BOTH, ALL, \ VERTICAL, HORIZONTAL, RIGHT, LEFT, X, Y yscroll = Scrollbar(orient=VERTICAL) xscroll = Scrollbar(orient=HORIZONTAL) canvas = Canvas(yscrollcommand=yscroll.set, xscrollcommand=xscroll.set, background='white') win = canvas.winfo_toplevel() win.geometry('700x700') yscroll.config(command=canvas.yview) xscroll.config(command=canvas.xview) yscroll.pack(side=RIGHT, fill=Y) xscroll.pack(side=BOTTOM, fill=X) canvas.pack(fill=BOTH, side=LEFT, expand=1) canvas.update() X0, Y0 = r + px, r + py x1, x2, y1, y2 = X0 - r, X0 + r, Y0 - r, Y0 + r ty = Y0 canvas.create_text(X0, ty, text='%s...%s (%d nt)' % (seq[:7], seq[-7:], len(seq))) ty += 20 canvas.create_text(X0, ty, text='GC %3.2f%%' % (GC(seq))) ty += 20 canvas.create_text(X0, ty, text='GC Skew', fill='blue') ty += 20 canvas.create_text(X0, ty, text='Accumulated GC Skew', fill='magenta') ty += 20 canvas.create_oval(x1, y1, x2, y2) acc = 0 start = 0 for gc in GC_skew(seq, window): r1 = r acc += gc # GC skew alpha = pi - (2*pi*start)/len(seq) r2 = r1 - gc*zoom x1 = X0 + r1 * sin(alpha) y1 = Y0 + r1 * cos(alpha) x2 = X0 + r2 * sin(alpha) y2 = Y0 + r2 * cos(alpha) canvas.create_line(x1, y1, x2, y2, fill='blue') # accumulated GC skew r1 = r - 50 r2 = r1 - acc x1 = X0 + r1 * sin(alpha) y1 = Y0 + r1 * cos(alpha) x2 = X0 + r2 * sin(alpha) y2 = Y0 + r2 * cos(alpha) canvas.create_line(x1, y1, x2, y2, fill='magenta') canvas.update() start += window canvas.configure(scrollregion=canvas.bbox(ALL))
def xGC_skew(seq, window = 1000, zoom = 100, r = 300, px = 100, py = 100): """Calculates and plots normal and accumulated GC skew (GRAPHICS !!!).""" from Tkinter import Scrollbar, Canvas, BOTTOM, BOTH, ALL, \ VERTICAL, HORIZONTAL, RIGHT, LEFT, X, Y yscroll = Scrollbar(orient = VERTICAL) xscroll = Scrollbar(orient = HORIZONTAL) canvas = Canvas(yscrollcommand = yscroll.set, xscrollcommand = xscroll.set, background = 'white') win = canvas.winfo_toplevel() win.geometry('700x700') yscroll.config(command = canvas.yview) xscroll.config(command = canvas.xview) yscroll.pack(side = RIGHT, fill = Y) xscroll.pack(side = BOTTOM, fill = X) canvas.pack(fill=BOTH, side = LEFT, expand = 1) canvas.update() X0, Y0 = r + px, r + py x1, x2, y1, y2 = X0 - r, X0 + r, Y0 -r, Y0 + r ty = Y0 canvas.create_text(X0, ty, text = '%s...%s (%d nt)' % (seq[:7], seq[-7:], len(seq))) ty +=20 canvas.create_text(X0, ty, text = 'GC %3.2f%%' % (GC(seq))) ty +=20 canvas.create_text(X0, ty, text = 'GC Skew', fill = 'blue') ty +=20 canvas.create_text(X0, ty, text = 'Accumulated GC Skew', fill = 'magenta') ty +=20 canvas.create_oval(x1,y1, x2, y2) acc = 0 start = 0 for gc in GC_skew(seq, window): r1 = r acc+=gc # GC skew alpha = pi - (2*pi*start)/len(seq) r2 = r1 - gc*zoom x1 = X0 + r1 * sin(alpha) y1 = Y0 + r1 * cos(alpha) x2 = X0 + r2 * sin(alpha) y2 = Y0 + r2 * cos(alpha) canvas.create_line(x1,y1,x2,y2, fill = 'blue') # accumulated GC skew r1 = r - 50 r2 = r1 - acc x1 = X0 + r1 * sin(alpha) y1 = Y0 + r1 * cos(alpha) x2 = X0 + r2 * sin(alpha) y2 = Y0 + r2 * cos(alpha) canvas.create_line(x1,y1,x2,y2, fill = 'magenta') canvas.update() start += window canvas.configure(scrollregion = canvas.bbox(ALL))
class SimulationStrip(Strip): def __init__(self, length, row_length, led_size=DEFAULT_LED_SIZE): super(SimulationStrip, self).__init__(length) led_window = Tk() led_window.title('LED Simulator') MARGIN = 5 led_size = min( (led_window.winfo_screenwidth() - 2 * MARGIN) / row_length, led_size) num_rows = math.ceil(length / row_length) height = num_rows * led_size + (1 + num_rows) * MARGIN width = led_size * row_length + 2 * MARGIN self.canvas = Canvas(led_window, width=width, height=height) self.canvas.pack() self.leds = [] * length self.leds = [ self.create_rectangle(i, row_length, led_size, MARGIN) for i in xrange(length) ] self.canvas.update() def show(self): for i in xrange(self.length): color = '#%02x%02x%02x' % tuple([(255 * c) / MAX_BRIGHTNESS for c in self[i]]) self.canvas.itemconfigure(self.leds[i], fill=color) self.canvas.update() time.sleep(SHOW_SLEEP_TIME) def create_rectangle(self, index, row_length, led_size, margin): #x0 if (index / row_length) % 2 == 0: x0 = margin + (index % row_length) * led_size else: x0 = margin + (row_length - (index % row_length) - 1) * led_size #y0 y0 = margin + (led_size + margin) * (index / row_length) #x1 if (index / row_length) % 2 == 0: x1 = margin + ((index % row_length) + 1) * led_size else: x1 = margin + (row_length - (index % row_length)) * led_size #y1 y1 = margin + (led_size + margin) * (index / row_length) + led_size return self.canvas.create_rectangle(x0, y0, x1, y1)
class Animation: def __init__(self): root = Tk() self.canvas = Canvas(root, height=500, width=500) self.canvas.pack() self.canvas.create_rectangle(0, 0, 500, 500, fill="#0D4566", outline="#0D4566") # space self.venus = Planet(250, 150, self.canvas, "red") self.earth = Planet(250, 100, self.canvas, "green") self.sun = Planet(250, 250, self.canvas, "yellow") self.start = time.time() self.ticks = 0 self.done = False self.timer() root.mainloop() def rotate_body(self, body, amount): theta = math.degrees(amount) x = body.x - 250 y = body.y - 250 x, y = x * math.cos(theta) - y * math.sin(theta), x * math.sin(theta) + y * math.cos(theta) x += 250 y += 250 body.move_to(x, y) self.canvas.update() def timer(self): if self.done: print "Done after %2.2f seconds!" % (time.time() - self.start) return self.rotate_body(self.earth, math.pi / 36000 * 13.0) self.rotate_body(self.venus, math.pi / 36000 * 8.0) self.ticks += 1 if self.ticks % 2 == 0: self.canvas.create_line(self.earth.x, self.earth.y, self.venus.x, self.venus.y, fill="white") if self.ticks > 1250: self.done = True self.canvas.after(5, self.timer)
class Application(object): def __init__(self, root, grid_size): root.title("Diffusion-Limited Aggregation") self.cell_size = WINDOW / grid_size self.grid = Grid(grid_size) self.canvas = Canvas(root, width=WINDOW, height=WINDOW) self.canvas.create_rectangle(0, 0, WINDOW, WINDOW, fill=BACKGROUND) self.canvas.pack() self.colorizer = Colorizer() def fill(self, x, y, color): x *= self.cell_size y *= self.cell_size self.canvas.create_rectangle(x, y, x + self.cell_size, y + self.cell_size, fill=color) self.canvas.update() def mark(self, speck, color): grid = speck.grid grid[speck.x, speck.y] = True self.fill(speck.x, speck.y, color) def evolve(self): # Fill in center cell. self.mark(Speck(self.grid, (self.grid.size / 2, self.grid.size / 2)), self.colorizer.next()) # Fill until the edge. number = 0 while True: speck = Speck(self.grid) self.fill(speck.x, speck.y, "red") while speck.on_grid() and not speck.stuck(): speck.move() if speck.on_grid(): print "%d,+%d" % (number, speck.steps) self.mark(speck, self.colorizer.next()) if speck.on_edge(): break else: print "%d,-%d" % (number, speck.steps) number += 1
class Application(object): def __init__(self, root, grid_size): root.title("Diffusion-Limited Aggregation") self.cell_size = WINDOW / grid_size self.grid = Grid(grid_size) self.canvas = Canvas(root, width=WINDOW, height=WINDOW) self.canvas.create_rectangle(0, 0, WINDOW, WINDOW, fill=BACKGROUND) self.canvas.pack() self.colorizer = Colorizer() def fill(self, x, y, color): x *= self.cell_size y *= self.cell_size self.canvas.create_rectangle(x, y, x + self.cell_size, y + self.cell_size, fill=color) self.canvas.update() def mark(self, speck, color): grid = speck.grid grid[speck.x, speck.y] = True self.fill(speck.x, speck.y, color) def evolve(self): # Fill in center cell. self.mark(Speck(self.grid, (self.grid.size/2, self.grid.size/2)), self.colorizer.next()) # Fill until the edge. number = 0 while True: speck = Speck(self.grid) self.fill(speck.x, speck.y, "red") while speck.on_grid() and not speck.stuck(): speck.move() if speck.on_grid(): print "%d,+%d" % (number, speck.steps) self.mark(speck, self.colorizer.next()) if speck.on_edge(): break else: print "%d,-%d" % (number, speck.steps) number += 1
class SimulationStrip(Strip): def __init__(self, length, row_length, led_size=DEFAULT_LED_SIZE): super(SimulationStrip, self).__init__(length) led_window = Tk() led_window.title('LED Simulator') MARGIN = 5 led_size = min((led_window.winfo_screenwidth() - 2 * MARGIN) / row_length, led_size) num_rows = math.ceil(length / row_length) height = num_rows * led_size + (1 + num_rows) * MARGIN width = led_size * row_length + 2 * MARGIN self.canvas = Canvas(led_window, width=width, height=height) self.canvas.pack() self.leds = [] * length self.leds = [self.create_rectangle(i, row_length, led_size, MARGIN) for i in xrange(length)] self.canvas.update() def show(self): for i in xrange(self.length): color = '#%02x%02x%02x' % tuple([(255 * c) / MAX_BRIGHTNESS for c in self[i]]) self.canvas.itemconfigure(self.leds[i], fill=color) self.canvas.update() time.sleep(SHOW_SLEEP_TIME) def create_rectangle(self, index, row_length, led_size, margin): #x0 if (index / row_length) % 2 == 0: x0 = margin + (index % row_length) * led_size else: x0 = margin + (row_length - (index % row_length) - 1) * led_size #y0 y0 = margin + (led_size + margin) * (index / row_length) #x1 if (index / row_length) % 2 == 0: x1 = margin + ((index % row_length) + 1) * led_size else: x1 = margin + (row_length - (index % row_length)) * led_size #y1 y1 = margin + (led_size + margin) * (index / row_length) + led_size return self.canvas.create_rectangle(x0, y0, x1, y1)
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.x0, self.y0 = circle(-90, 90, 40) #self.x0, self.y0 = circle(-90, 90, 35) #print len(self.x0) #self.tet1 = [i for i in range(90)] #self.tet2 = [i for i in range(45, 135)] self.tet1_con = 0 self.tet2_con = 0 self.count1 = 0 self.count2 = 0 self.sign1 = 1 self.sign2 = -1 self.parent = parent self.initUI() self.parent.after(0, self.animation) def initUI(self): self.parent.title("Arm") self.pack(fill=BOTH, expand=1) self.canvas = Canvas(self) #self.canvas.create_line(0, 0, 200, 100+self.count, width=arm_width) line = Line(self.canvas, points['1'], (width/2, hight/2)) arms.append(line) line = Line(self.canvas, 90-(points['2']-points['1']), line.cor1) arms.append(line) self.canvas.pack(fill=BOTH, expand=1) def animation(self): self.canvas.delete("all") for i in range(0, len(self.x0), 2): self.canvas.create_line(width/2+self.x0[i], hight/2-self.y0[i], width/2+self.x0[i+1],hight/2-self.y0[i+1], width=2) tet1p, tet2p = getAngles(self.x0[self.count1], self.y0[self.count1]) tet1 = 180-(tet1p) tet2 = 180-((tet2p)-tet1)+180 text = '('+str(tet1p) +',' + str(tet2p) + ')' self.canvas.create_text((width/2, hight-100),text=text) line = arms[0].draw(tet1) arms[1].draw(tet2, line, 'red') self.count1+=self.sign1 if self.count1 == (len(self.x0)-1) and self.sign1 == 1: #self.sign1 = -1 self.count1 = 0 if self.count1 <= 0 and self.sign1 == -1: self.sign1 = 1 #self.x0=self.x01 #self.y0=self.y01 #line = arms[0].draw(points['1']) #arms[1].draw(90-(points['2']-points['1']), line) self.canvas.update() #self.count +=1 self.parent.after(100, self.animation)
class FourBarGUI(object): """ GUI to model a 4-bar mechanism. """ def __init__(self, wdw, r, c): """ Determines layout of the canvas, number of rows and colums is r and c. """ wdw.title('a 4-bar mechanism') self.fbr = FourBar() self.rows = r self.cols = c self.ox = c/3 self.oy = 3*r/4 # print "A =" , (self.ox, self.oy) self.togo = False # the canvas and start, stop, and clear buttons self.c = Canvas(wdw, width=self.cols, height=self.rows, bg='green') self.c.grid(row=1, column=2, columnspan=2) self.startbut = Button(wdw, text='start', command = self.start) self.startbut.grid(row=3, column=2, sticky=W+E) self.stopbut = Button(wdw, text='stop', command = self.stop) self.stopbut.grid(row=3, column=3, sticky=W+E) self.clearbut = Button(wdw, text='clear', command = self.clear) self.clearbut.grid(row=3, column=4, columnspan=3, sticky=W+E) # the length of the crank self.crank_lbl = Label(wdw, text='crank', justify=LEFT) self.crank_lbl.grid(row=0, column=0) self.crank_bar = IntVar() self.L = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \ tickinterval=20, resolution=1, length=self.rows, \ variable=self.crank_bar, command=self.draw_mechanism) self.L.set(self.fbr.crank) self.L.grid(row=1, column=0) # the angle that drives the crank self.angle_lbl = Label(wdw, text='angle', justify=LEFT) self.angle_lbl.grid(row=0, column=1) self.angle = DoubleVar() self.t = Scale(wdw, orient='vertical', from_=0, to=6.30, \ tickinterval=0.30, resolution=0.01, length=self.rows, \ variable=self.angle, command=self.draw_mechanism) self.t.grid(row=1, column=1) self.angle.set(self.fbr.angle) # the bar at the right self.right_bar_lbl = Label(wdw, text='right bar', justify=LEFT) self.right_bar_lbl.grid(row=0, column=4) self.right_bar = IntVar() self.r = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \ tickinterval=20, resolution=1, length=self.rows, \ variable=self.right_bar, command=self.draw_mechanism) self.r.grid(row=1, column=4) self.right_bar.set(self.fbr.right) # the top bar attached to the crank self.top_bar_lbl = Label(wdw, text='top bar', justify=LEFT) self.top_bar_lbl.grid(row=0, column=5) self.r_top_bar = IntVar() self.R = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \ tickinterval=20, resolution=1, length=self.rows, \ variable=self.r_top_bar, command=self.draw_mechanism) self.R.grid(row=1, column=5) self.r_top_bar.set(self.fbr.top) # the scale for the coupler bar self.coupler_bar_lbl = Label(wdw, text='coupler', justify=LEFT) self.coupler_bar_lbl.grid(row=0, column=6) self.coupler_bar = IntVar() self.cpl = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \ tickinterval=20, resolution=1, length=self.rows, \ variable=self.coupler_bar, command=self.draw_mechanism) self.cpl.grid(row=1, column=6) self.coupler_bar.set(self.fbr.coupler) # the horizontal bottom bar self.flat_lbl = Label(wdw, text='right joint', justify=RIGHT) self.flat_lbl.grid(row=2, column=1) self.flat = IntVar() self.f = Scale(wdw, orient='horizontal', from_=0, to=self.rows/2, \ tickinterval=50, resolution=1, length=self.cols, \ variable=self.flat, command=self.draw_mechanism) self.f.grid(row=2, column=2, columnspan=2) self.flat.set(self.fbr.flat) # coordinates of the coupler point appear on top self.ex = Entry(wdw) # for x value self.ex.grid(row=0, column=2) self.ex.insert(INSERT, "x = ") self.ey = Entry(wdw) # for y value self.ey.grid(row=0, column=3) self.ey.insert(INSERT,"y = ") # check button for drawing of coupler curve self.curve = IntVar() self.cb = Checkbutton(wdw, text='coupler', \ variable=self.curve, onvalue=1, offvalue=0) self.curve.set(1) self.cb.grid(row=3, column=0) # draw the mechanism on canvas self.draw_mechanism(0) def update_values(self): """ Takes all values of the scales and updates the data attributes of self.fbr. """ self.fbr.flat = self.flat.get() self.fbr.crank = self.crank_bar.get() self.fbr.top = self.r_top_bar.get() self.fbr.right = self.right_bar.get() self.fbr.coupler = self.coupler_bar.get() self.fbr.angle = self.angle.get() #self.fbr.print_joints() def draw_coupler_point(self, p): """ Draws coupler point with coordinates in p if the curve checkbox is on. Note that the previous values for the coordinates of the coupler point are stored in the entry fields. """ if self.curve.get() == 1: px = self.ox + p[0] py = self.oy - p[1] eqx = self.ex.get() Lx = eqx.split('=') if Lx[1] == ' ': qx = 0.0 else: qx = float(Lx[1]) eqy = self.ey.get() Ly = eqy.split('=') if Ly[1] == ' ': qy = 0.0 else: qy = float(Ly[1]) if (qx != 0.0) and (qy != 0.0): qx = self.ox + qx qy = self.oy - qy self.c.create_line(qx, qy, px, py, width=1) def fill_entries(self, p): """ Fills the entry fields with the coordinates of the coupler point in p. """ sx = 'x = %f' % p[0] sy = 'y = %f' % p[1] self.ex.delete(0, END) self.ex.insert(INSERT, sx) self.ey.delete(0, END) self.ey.insert(INSERT, sy) def draw_link(self, p, q, s): """ Draws the link from point with coordinates in p to the point with coordinates in q, using s as tag. """ self.c.delete(s) px = self.ox + p[0] py = self.oy - p[1] qx = self.ox + q[0] qy = self.oy - q[1] self.c.create_line(px, py, qx, qy, width=2, tags=s) def draw_mechanism(self, v): """ Fills the canvas with the current model of the planar 4-bar mechanism. Because this command is called by the sliders, the argument v is needed but not used. """ self.update_values() L = self.fbr.joints() for i in range(0, len(L)): p = L[i] px = self.ox + p[0] py = self.oy - p[1] sj = 'joint%d' % i self.c.delete(sj) self.c.create_oval(px-6, py-6, px+6, py+6, width=1, \ outline='black', fill='red', tags=sj) self.draw_link(L[0], L[2], 'link0') self.draw_link(L[1], L[3], 'link1') self.draw_link(L[2], L[3], 'link2') self.draw_link(L[2], L[4], 'link3') self.draw_coupler_point(L[4]) self.fill_entries(L[4]) def start(self): """ Starts the animation, adding 0.01 to angle. """ self.togo = True while self.togo: theta = self.angle.get() theta = theta + 0.01 if theta > 6.28: theta = 0 self.angle.set(theta) self.draw_mechanism(0) self.c.update() def stop(self): """ Stops the animation. """ self.togo = False def clear(self): """ Clears the canvas. """ self.c.delete(ALL)
class Board: def __init__(self, width, height, title = "Boids"): """ A board for boids to explore """ from Tkinter import Tk, Canvas, Toplevel self.colors = ["white", "black", "red", "yellow", "blue", "green", "purple", "pink", "cyan", "turquoise", "gray"] self.width = width self.height = height self.distance = 10 self.boids = [] self.oldVector = [] self.title = title self.app = Tk() self.app.withdraw() self.win = Toplevel() self.win.wm_title(title) self.canvas = Canvas(self.win, width=self.width, height=self.height) self.canvas.pack(side = 'bottom', expand = "yes", anchor = "n", fill = 'both') self.win.winfo_toplevel().protocol('WM_DELETE_WINDOW',self.close) #self.canvas.bind("<Configure>", self.changeSize) self.draw() def close(self): """ close the window """ self.app.destroy() def draw(self): """ Initialize the board. You must do this if you ever want to see the path """ print "Drawing...", self.canvas.delete("boid") for boid in self.boids: self.drawBoid( boid ) self.canvas.update() print "Done!" def drawBoid(self, boid): size = 40 angle = 80 x = boid.x - size/2 y = boid.y - size/2 start = ((boid.dir + 180 + angle/2) - 55) % 360 color = self.colors[boid.color] self.canvas.create_arc(x, y, x + size, y + size, start = start, extent = angle/2, fill = color, outline = color, tag = "boid") def addBoid(self, boid): self.boids.append( boid ) self.oldVector.append( 0 ) self.draw() def dist(self, x1, y1, x2, y2): return math.sqrt( (x1 - x2) ** 2 + (y1 - y2) ** 2) def angleTo(self, b1, b2): # figure out angle from boid1 to boid2 # this is just a test! if self.boids[b1].x < self.boids[b2].x: return -10 # return - if to the right, + if to the left else: return 10 def avoid(self, num, radius): for i in range(len(self.boids)): if i != num: if self.dist(self.boids[i].x, self.boids[i].y, self.boids[num].x, self.boids[num].y ) < radius: return -self.angleTo( num, i) return 0.0 def copy(self, num, radius): # if within radius, get closer to their angle # return - if to the right, + if to the left return 0 def center(self, num, radius): # make yoru angle head toward center # return - if to the right, + if to the left return 0 def view(self, num, radius): # try to have a clear view # return - if to the right, + if to the left return 0 def adjustDirections(self, weights): radius = 40 for boidNum in range(len(self.boids)): avoidVector = self.avoid( boidNum, radius ) copyVector = self.copy( boidNum, radius ) centerVector = self.center( boidNum, radius ) viewVector = self.view( boidNum, radius ) newVector = int(weights[0] * avoidVector + weights[1] * copyVector + weights[2] * centerVector + weights[3] * viewVector) self.boids[boidNum].dir += newVector self.oldVector[boidNum] = newVector def move(self): """ Make the boids move """ self.adjustDirections([1., 1., 1., 1.]) # pass in weights: avoid, copy, center, view for boid in self.boids: boid.x += self.distance * math.cos( boid.dir / 180.0 * math.pi) boid.y -= self.distance * math.sin( boid.dir / 180.0 * math.pi) if boid.x > self.width: boid.x = 0 if boid.x < 0: boid.x = self.width - 1 if boid.y > self.height: boid.y = 0 if boid.y < 0: boid.y = self.height - 1 self.draw()
class World(Tk): def __init__(self,filename=None,block=50,debug=True,delay=0.25,image=False,width=10,height=10): # def __init__(self,filename=None,block=50,debug=True,delay=0.25,image=True,width=10,height=10): Tk.__init__(self) self.title("") arg, self.width, self.height = block, width, height # self.photos = [PhotoImage(file=(k+".gif")) for k in ["east","north","west","south"]] self.beepers, self.ovals, self.numbers, self.robots, self.walls = {},{},{},{},{} self.m, self.n, self.t, self.delay = arg*(width+3), arg*(height+3), arg, delay self.debug, self.useImage = debug, image a, b, c = self.t+self.t/2, self.m-self.t-self.t/2, self.n-self.t-self.t/2 self.canvas = Canvas(self, bg="white", width=self.m, height=self.n) self.canvas.pack() count = 1 for k in range(2*self.t, max(self.m,self.n)-self.t, self.t): if k < b: self.canvas.create_line(k, c, k, a, fill="red") self.canvas.create_text(k, c+self.t/2, text=str(count), font=("Times",max(-self.t*2/3,-15),"")) if k < c: self.canvas.create_line(b, k, a, k, fill="red") self.canvas.create_text(a-self.t/2, self.n-k, text=str(count), font=("Times",max(-self.t*2/3,-15),"")) count += 1 self.canvas.create_line(a, c, b, c, fill="black", width=3) self.canvas.create_line(a, a, a, c, fill="black", width=3) if filename is not None: self.readWorld(filename) self.refresh() def readWorld(self,filename): try: infile = open("worlds\\%s.wld" % filename, "r") except IOError: try: infile = open("worlds/%s.wld" % filename, "r") except IOError: infile = open(filename, "r") text = infile.read().split("\n") infile.close() for t in text: if t.startswith("eastwestwalls"): s = t.split(" ") y, x = int(s[1]), int(s[2]) self.addWall(x, y, -1, y) if t.startswith("northsouthwalls"): s = t.split(" ") x, y = int(s[1]), int(s[2]) self.addWall(x, y, x, -1) if t.startswith("beepers"): s = t.split(" ") y, x, n = int(s[1]), int(s[2]), int(s[3]) if n is infinity: self.addInfiniteBeepers(x, y) else: for k in range(n): self.addBeeper(x, y) def pause(self): sleep(self.delay) def isBeeper(self,x,y): return (x,y) in self.beepers.keys() and not self.beepers[(x,y)] == 0 def countRobots(self,x,y): if (x,y) not in self.robots.keys(): return 0 return len(self.robots[(x,y)]) def crash(self,x1,y1,x2,y2): if 0 in (x1,y1,x2,y2): return True if (x2,y2) in self.walls.keys() and (x1,y1) in self.walls[(x2,y2)]: return True if (x1,y1) in self.walls.keys() and (x2,y2) in self.walls[(x1,y1)]: return True return False def addInfiniteBeepers(self,x,y): flag = (x,y) not in self.beepers.keys() or self.beepers[(x,y)] is 0 self.beepers[(x,y)] = infinity text = "oo" a, b = self.t+x*self.t, self.n-(self.t+y*self.t) t = self.t/3 if flag: self.ovals[(x,y)] = self.canvas.create_oval(a-t, b-t, a+t, b+t, fill="black") self.numbers[(x,y)] = self.canvas.create_text(a, b, text=text, fill="white", font=("Times",max(-self.t/2,-20),"")) else: self.canvas.itemconfig(self.numbers[(x,y)], text=text) if (x,y) in self.robots.keys(): for robot in self.robots[(x,y)]: robot.lift() def addBeeper(self,x,y): if (x,y) in self.beepers.keys() and self.beepers[(x,y)] is infinity: return flag = (x,y) not in self.beepers.keys() or self.beepers[(x,y)] is 0 if flag: self.beepers[(x,y)] = 1 else: self.beepers[(x,y)] += 1 text = str(self.beepers[(x,y)]) a, b = self.t+x*self.t, self.n-(self.t+y*self.t) t = self.t/3 if flag: self.ovals[(x,y)] = self.canvas.create_oval(a-t, b-t, a+t, b+t, fill="black") self.numbers[(x,y)] = self.canvas.create_text(a, b, text=text, fill="white", font=("Times",max(-self.t/2,-20),"")) else: self.canvas.itemconfig(self.numbers[(x,y)], text=text) if (x,y) in self.robots.keys(): for robot in self.robots[(x,y)]: robot.lift() def removeBeeper(self,x,y): if self.beepers[(x,y)] is infinity: return self.beepers[(x,y)] -= 1 flag = self.beepers[(x,y)] is 0 text = str(self.beepers[(x,y)]) if flag: self.canvas.delete(self.ovals[(x,y)]) self.canvas.delete(self.numbers[(x,y)]) else: self.canvas.itemconfig(self.numbers[(x,y)], text=text) if (x,y) in self.robots.keys(): for robot in self.robots[(x,y)]: robot.lift() def addWall(self,x1,y1,x2,y2): if not x1 == x2 and not y1 == y2: return if x1 == x2: y1, y2 = min(y1, y2), max(y1, y2) if y1 == -1: y1 = y2 for k in range(y1, y2+1): self.walls.setdefault((x1,k), []).append((x1+1,k)) a, b = self.t+x1*self.t+self.t/2, self.n-(self.t+k*self.t)+self.t/2 c, d = self.t+x1*self.t+self.t/2, self.n-(self.t+k*self.t)-self.t/2 self.canvas.create_line(a, b+1, c, d-1, fill="black", width=3) else: x1, x2 = min(x1, x2), max(x1, x2) if x1 == -1: x1 = x2 for k in range(x1, x2+1): self.walls.setdefault((k,y1), []).append((k,y1+1)) a, b = self.t+k*self.t-self.t/2, self.n-(self.t+y1*self.t)-self.t/2 c, d = self.t+k*self.t+self.t/2, self.n-(self.t+y1*self.t)-self.t/2 self.canvas.create_line(a-1, b, c+1, d, fill="black", width=3) def draw(self,x,y,d,img): # if self.useImage: # if img is not None: # self.canvas.delete(img) # x, y = self.t+x*self.t, self.n-(self.t+y*self.t) # photo = self.photos[d/90] # img = self.canvas.create_image(x, y, image=photo) # return img # else: t, angle = self.t/2, 120 x, y = self.t+x*self.t, self.n-(self.t+y*self.t) x1, y1 = x+3**0.5*t/2*cos(radians(d)), y-3**0.5*t/2*sin(radians(d)) x2, y2 = x+t*cos(radians(d+angle)), y-t*sin(radians(d+angle)) x3, y3 = x+t/4*cos(radians(d+180)), y-t/4*sin(radians(d+180)) x4, y4 = x+t*cos(radians(d-angle)), y-t*sin(radians(d-angle)) if img is not None: self.canvas.delete(img) img = self.canvas.create_polygon(x1, y1, x2, y2, x3, y3, x4, y4, fill="blue") return img def erase(self,img): self.canvas.delete(img) def recordMove(self,count,x1,y1,x2,y2): for robot in self.robots[(x1,y1)]: if robot.count == count: self.robots[(x1,y1)].remove(robot) self.robots.setdefault((x2,y2), []).append(robot) break def lift(self,img): self.canvas.lift(img) def refresh(self): self.canvas.update() self.pause() def register(self,x,y,robot): self.robots.setdefault((x,y), []).append(robot) def remove(self,x,y,robot): self.robots[(x,y)].remove(robot)
class Pinball(Domain): """ The goal of this domain is to maneuver a small ball on a plate into a hole. The plate may contain obstacles which should be avoided. **STATE:** The state is given by a 4-dimensional vector, consisting of position and velocity of the ball. **ACTIONS:** There are 5 actions, standing for slanting the plat in x or y direction or a horizontal position of the plate. **REWARD:** Slanting the plate costs -4 reward in addition to -1 reward for each timestep. When the ball reaches the hole, the agent receives 10000 units of reward. **REFERENCE:** .. seealso:: G.D. Konidaris and A.G. Barto: *Skill Discovery in Continuous Reinforcement Learning Domains using Skill Chaining.* Advances in Neural Information Processing Systems 22, pages 1015-1023, December 2009. """ #: default location of config files shipped with rlpy default_config_dir = os.path.join( __rlpy_location__, "Domains", "PinballConfigs") def __init__(self, noise=.1, episodeCap=1000, configuration=os.path.join(default_config_dir, "pinball_simple_single.cfg")): """ configuration: location of the configuration file episodeCap: maximum length of an episode noise: with probability noise, a uniformly random action is executed """ self.NOISE = noise self.configuration = configuration self.screen = None self.episodeCap = episodeCap self.actions_num = 5 self.actions = [ PinballModel.ACC_X, PinballModel.DEC_Y, PinballModel.DEC_X, PinballModel.ACC_Y, PinballModel.ACC_NONE] self.statespace_limits = np.array( [[0.0, 1.0], [0.0, 1.0], [-2.0, 2.0], [-2.0, 2.0]]) self.continuous_dims = [4] super(Pinball, self).__init__() self.environment = PinballModel( self.configuration, random_state=self.random_state) def showDomain(self, a): if self.screen is None: master = Tk() master.title('RLPY Pinball') self.screen = Canvas(master, width=500.0, height=500.0) self.screen.configure(background='LightGray') self.screen.pack() self.environment_view = PinballView( self.screen, 500.0, 500.0, self.environment) self.environment_view.blit() self.screen.pack() self.screen.update() def step(self, a): s = self.state [self.environment.ball.position[0], self.environment.ball.position[1], self.environment.ball.xdot, self.environment.ball.ydot] = s if self.random_state.random_sample() < self.NOISE: # Random Move a = self.random_state.choice(self.possibleActions()) reward = self.environment.take_action(a) self.environment._check_bounds() state = np.array(self.environment.get_state()) self.state = state.copy() return reward, state, self.isTerminal(), self.possibleActions() def s0(self): self.environment.ball.position[0], self.environment.ball.position[ 1] = self.environment.start_pos self.environment.ball.xdot, self.environment.ball.ydot = 0.0, 0.0 self.state = np.array( [self.environment.ball.position[0], self.environment.ball.position[1], self.environment.ball.xdot, self.environment.ball.ydot]) return self.state, self.isTerminal(), self.possibleActions() def possibleActions(self, s=0): return np.array(self.actions) def isTerminal(self): return self.environment.episode_ended()
class Board: def __init__(self, width, height, title="Boids"): """ A board for boids to explore """ from Tkinter import Tk, Canvas, Toplevel self.colors = [ "white", "black", "red", "yellow", "blue", "green", "purple", "pink", "cyan", "turquoise", "gray" ] self.width = width self.height = height self.distance = 10 self.boids = [] self.oldVector = [] self.title = title self.app = Tk() self.app.withdraw() self.win = Toplevel() self.win.wm_title(title) self.canvas = Canvas(self.win, width=self.width, height=self.height) self.canvas.pack(side='bottom', expand="yes", anchor="n", fill='both') self.win.winfo_toplevel().protocol('WM_DELETE_WINDOW', self.close) #self.canvas.bind("<Configure>", self.changeSize) self.draw() def close(self): """ close the window """ self.app.destroy() def draw(self): """ Initialize the board. You must do this if you ever want to see the path """ print "Drawing...", self.canvas.delete("boid") for boid in self.boids: self.drawBoid(boid) self.canvas.update() print "Done!" def drawBoid(self, boid): size = 40 angle = 80 x = boid.x - size / 2 y = boid.y - size / 2 start = ((boid.dir + 180 + angle / 2) - 55) % 360 color = self.colors[boid.color] self.canvas.create_arc(x, y, x + size, y + size, start=start, extent=angle / 2, fill=color, outline=color, tag="boid") def addBoid(self, boid): self.boids.append(boid) self.oldVector.append(0) self.draw() def dist(self, x1, y1, x2, y2): return math.sqrt((x1 - x2)**2 + (y1 - y2)**2) def angleTo(self, b1, b2): # figure out angle from boid1 to boid2 # this is just a test! if self.boids[b1].x < self.boids[b2].x: return -10 # return - if to the right, + if to the left else: return 10 def avoid(self, num, radius): for i in range(len(self.boids)): if i != num: if self.dist(self.boids[i].x, self.boids[i].y, self.boids[num].x, self.boids[num].y) < radius: return -self.angleTo(num, i) return 0.0 def copy(self, num, radius): # if within radius, get closer to their angle # return - if to the right, + if to the left return 0 def center(self, num, radius): # make yoru angle head toward center # return - if to the right, + if to the left return 0 def view(self, num, radius): # try to have a clear view # return - if to the right, + if to the left return 0 def adjustDirections(self, weights): radius = 40 for boidNum in range(len(self.boids)): avoidVector = self.avoid(boidNum, radius) copyVector = self.copy(boidNum, radius) centerVector = self.center(boidNum, radius) viewVector = self.view(boidNum, radius) newVector = int(weights[0] * avoidVector + weights[1] * copyVector + weights[2] * centerVector + weights[3] * viewVector) self.boids[boidNum].dir += newVector self.oldVector[boidNum] = newVector def move(self): """ Make the boids move """ self.adjustDirections([1., 1., 1., 1. ]) # pass in weights: avoid, copy, center, view for boid in self.boids: boid.x += self.distance * math.cos(boid.dir / 180.0 * math.pi) boid.y -= self.distance * math.sin(boid.dir / 180.0 * math.pi) if boid.x > self.width: boid.x = 0 if boid.x < 0: boid.x = self.width - 1 if boid.y > self.height: boid.y = 0 if boid.y < 0: boid.y = self.height - 1 self.draw()
def initUI(self, tree, scaling): self.parent.title("MST") self.pack(fill=BOTH, expand=1) canvas = Canvas(self, width=10000, height=10000) #canvas.create_oval(10, 10, 15, 15, outline="red", fill="red", width=1) tempMax1 = 0 tempMax2 = 0 for node in tree.nodes: tempMax1 = max(tempMax1, node.GetLoc()[0]) tempMax2 = max(tempMax2, node.GetLoc()[1]) for x in range(tempMax1 + 1): for y in range(tempMax2 + 1): canvas.create_oval(scaling * (x + 1) - 1, scaling * (tempMax2 - y + 1) - 1, scaling * (x + 1) + 1, scaling * (tempMax2 - y + 1) + 1, outline="black", fill="black", width=1) for edge in tree.edges: point1 = edge.GetPoints()[0] point2 = edge.GetPoints()[1] point3 = edge.GetPoints()[2] canvas.create_oval(scaling * (point1[0] + 1) - 2, scaling * (tempMax2 - point1[1] + 1) - 2, scaling * (point1[0] + 1) + 2, scaling * (tempMax2 - point1[1] + 1) + 2, outline="red", fill="red", width=1) canvas.create_oval(scaling * (point2[0] + 1) - 2, scaling * (tempMax2 - point2[1] + 1) - 2, scaling * (point2[0] + 1) + 2, scaling * (tempMax2 - point2[1] + 1) + 2, outline="red", fill="red", width=1) if point3 != None: point3 = edge.GetPoints()[2] canvas.create_line(scaling * (point1[0] + 1), scaling * (tempMax2 - point1[1] + 1), scaling * (point3[0] + 1), scaling * (tempMax2 - point3[1] + 1), fill="red") canvas.create_line(scaling * (point2[0] + 1), scaling * (tempMax2 - point2[1] + 1), scaling * (point3[0] + 1), scaling * (tempMax2 - point3[1] + 1), fill="red") else: canvas.create_line(scaling * (point1[0] + 1), scaling * (tempMax2 - point1[1] + 1), scaling * (point2[0] + 1), scaling * (tempMax2 - point2[1] + 1), fill="red") canvas.pack(fill=BOTH, expand=1) canvas.update() canvas.postscript(file="graph.6.ps", colormode='color')
class World(Tk): # def __init__(self,filename=None,block=50,debug=True,delay=0.25,image=False,width=10,height=10): def __init__(self, filename=None, block=50, debug=True, delay=0.25, image=True, width=10, height=10): Tk.__init__(self) self.title("") arg, self.width, self.height = block, width, height self.photos = [ PhotoImage(file=(k + ".gif")) for k in ["east", "north", "west", "south"] ] self.beepers, self.ovals, self.numbers, self.robots, self.walls = {},{},{},{},{} self.m, self.n, self.t, self.delay = arg * (width + 3), arg * ( height + 3), arg, delay self.debug, self.useImage = debug, image a, b, c = self.t + self.t / 2, self.m - self.t - self.t / 2, self.n - self.t - self.t / 2 self.canvas = Canvas(self, bg="white", width=self.m, height=self.n) self.canvas.pack() count = 1 for k in range(2 * self.t, max(self.m, self.n) - self.t, self.t): if k < b: self.canvas.create_line(k, c, k, a, fill="red") self.canvas.create_text(k, c + self.t / 2, text=str(count), font=("Times", max(-self.t * 2 / 3, -15), "")) if k < c: self.canvas.create_line(b, k, a, k, fill="red") self.canvas.create_text(a - self.t / 2, self.n - k, text=str(count), font=("Times", max(-self.t * 2 / 3, -15), "")) count += 1 self.canvas.create_line(a, c, b, c, fill="black", width=3) self.canvas.create_line(a, a, a, c, fill="black", width=3) if filename is not None: self.readWorld(filename) self.refresh() def readWorld(self, filename): try: infile = open("worlds\\%s.wld" % filename, "r") except IOError: try: infile = open("worlds/%s.wld" % filename, "r") except IOError: infile = open(filename, "r") text = infile.read().split("\n") infile.close() for t in text: if t.startswith("eastwestwalls"): s = t.split(" ") y, x = int(s[1]), int(s[2]) self.addWall(x, y, -1, y) if t.startswith("northsouthwalls"): s = t.split(" ") x, y = int(s[1]), int(s[2]) self.addWall(x, y, x, -1) if t.startswith("beepers"): s = t.split(" ") y, x, n = int(s[1]), int(s[2]), int(s[3]) if n is infinity: self.addInfiniteBeepers(x, y) else: for k in range(n): self.addBeeper(x, y) def pause(self): sleep(self.delay) def isBeeper(self, x, y): return (x, y) in self.beepers.keys() and not self.beepers[(x, y)] == 0 def countRobots(self, x, y): if (x, y) not in self.robots.keys(): return 0 return len(self.robots[(x, y)]) def crash(self, x1, y1, x2, y2): if 0 in (x1, y1, x2, y2): return True if (x2, y2) in self.walls.keys() and (x1, y1) in self.walls[(x2, y2)]: return True if (x1, y1) in self.walls.keys() and (x2, y2) in self.walls[(x1, y1)]: return True return False def addInfiniteBeepers(self, x, y): flag = (x, y) not in self.beepers.keys() or self.beepers[(x, y)] is 0 self.beepers[(x, y)] = infinity text = "oo" a, b = self.t + x * self.t, self.n - (self.t + y * self.t) t = self.t / 3 if flag: self.ovals[(x, y)] = self.canvas.create_oval(a - t, b - t, a + t, b + t, fill="black") self.numbers[(x, y)] = self.canvas.create_text( a, b, text=text, fill="white", font=("Times", max(-self.t / 2, -20), "")) else: self.canvas.itemconfig(self.numbers[(x, y)], text=text) if (x, y) in self.robots.keys(): for robot in self.robots[(x, y)]: robot.lift() def addBeeper(self, x, y): if (x, y) in self.beepers.keys() and self.beepers[(x, y)] is infinity: return flag = (x, y) not in self.beepers.keys() or self.beepers[(x, y)] is 0 if flag: self.beepers[(x, y)] = 1 else: self.beepers[(x, y)] += 1 text = str(self.beepers[(x, y)]) a, b = self.t + x * self.t, self.n - (self.t + y * self.t) t = self.t / 3 if flag: self.ovals[(x, y)] = self.canvas.create_oval(a - t, b - t, a + t, b + t, fill="black") self.numbers[(x, y)] = self.canvas.create_text( a, b, text=text, fill="white", font=("Times", max(-self.t / 2, -20), "")) else: self.canvas.itemconfig(self.numbers[(x, y)], text=text) if (x, y) in self.robots.keys(): for robot in self.robots[(x, y)]: robot.lift() def removeBeeper(self, x, y): if self.beepers[(x, y)] is infinity: return self.beepers[(x, y)] -= 1 flag = self.beepers[(x, y)] is 0 text = str(self.beepers[(x, y)]) if flag: self.canvas.delete(self.ovals[(x, y)]) self.canvas.delete(self.numbers[(x, y)]) else: self.canvas.itemconfig(self.numbers[(x, y)], text=text) if (x, y) in self.robots.keys(): for robot in self.robots[(x, y)]: robot.lift() def addWall(self, x1, y1, x2, y2): if not x1 == x2 and not y1 == y2: return if x1 == x2: y1, y2 = min(y1, y2), max(y1, y2) if y1 == -1: y1 = y2 for k in range(y1, y2 + 1): self.walls.setdefault((x1, k), []).append((x1 + 1, k)) a, b = self.t + x1 * self.t + self.t / 2, self.n - ( self.t + k * self.t) + self.t / 2 c, d = self.t + x1 * self.t + self.t / 2, self.n - ( self.t + k * self.t) - self.t / 2 self.canvas.create_line(a, b + 1, c, d - 1, fill="black", width=3) else: x1, x2 = min(x1, x2), max(x1, x2) if x1 == -1: x1 = x2 for k in range(x1, x2 + 1): self.walls.setdefault((k, y1), []).append((k, y1 + 1)) a, b = self.t + k * self.t - self.t / 2, self.n - ( self.t + y1 * self.t) - self.t / 2 c, d = self.t + k * self.t + self.t / 2, self.n - ( self.t + y1 * self.t) - self.t / 2 self.canvas.create_line(a - 1, b, c + 1, d, fill="black", width=3) def draw(self, x, y, d, img): if self.useImage: if img is not None: self.canvas.delete(img) x, y = self.t + x * self.t, self.n - (self.t + y * self.t) photo = self.photos[d / 90] img = self.canvas.create_image(x, y, image=photo) return img else: t, angle = self.t / 2, 120 x, y = self.t + x * self.t, self.n - (self.t + y * self.t) x1, y1 = x + 3**0.5 * t / 2 * cos( radians(d)), y - 3**0.5 * t / 2 * sin(radians(d)) x2, y2 = x + t * cos(radians(d + angle)), y - t * sin( radians(d + angle)) x3, y3 = x + t / 4 * cos(radians(d + 180)), y - t / 4 * sin( radians(d + 180)) x4, y4 = x + t * cos(radians(d - angle)), y - t * sin( radians(d - angle)) if img is not None: self.canvas.delete(img) img = self.canvas.create_polygon(x1, y1, x2, y2, x3, y3, x4, y4, fill="blue") return img def erase(self, img): self.canvas.delete(img) def recordMove(self, count, x1, y1, x2, y2): for robot in self.robots[(x1, y1)]: if robot.count == count: self.robots[(x1, y1)].remove(robot) self.robots.setdefault((x2, y2), []).append(robot) break def lift(self, img): self.canvas.lift(img) def refresh(self): self.canvas.update() self.pause() def register(self, x, y, robot): self.robots.setdefault((x, y), []).append(robot) def remove(self, x, y, robot): self.robots[(x, y)].remove(robot)
def main(): ImageFile.MAXBLOCK = 4096*2304 # this is only required for older PIL versions, if PILs output buffer is not large enough. see: https://mail.python.org/pipermail/image-sig/1999-August/000816.html parser = argparse.ArgumentParser(description='Simple Raytracer by Tilman Ginzel') parser.add_argument('-r', '--recursive', help='sets recursive depth, e.g. -r 3 (required)', nargs=1, type=checkPositiveInt, required=True, metavar='') parser.add_argument('-s', '--size', help='sets the size, e.g. -s 400 400', nargs=2, default=[400, 400], type=checkPositiveInt, required=False, metavar='') parser.add_argument('-v', '--verbose', help='enable live visualization while processing (slower)', required=False, action='store_true') parser.add_argument('-m', '--material', help='enable materials', required=False, action='store_true') parser.add_argument('-a', '--antialiasing', help='enables 4xSSAA (hence, 4 times slower)', required=False, action='store_true') parser.add_argument('-o', '--output', help='saves image to "./saves/"', required=False, action='store_true') parser.add_argument('-set', '--setting', help='choose a setting. -set 1 - 3', required=False, nargs=1, default=[1], type=int, metavar='') parser.add_argument('-nd', '--no-display', help='this should only be set if the script runs on a server without a $DISPLAY environment variable set!', required=False, action='store_true') try: args = vars(parser.parse_args()) except: parser.print_help() sys.exit(1) settingId = args['setting'][0] if settingId == 1: # default setting setting = DefaultSetting(width=args['size'][0], height=args['size'][1], recursiveDepth=args['recursive'][0], showMaterial=args['material']) elif settingId == 2: # space setting setting = SpaceSetting(width=args['size'][0], height=args['size'][1], recursiveDepth=args['recursive'][0], showMaterial=args['material']) elif settingId == 3: # room setting setting = RoomSetting(width=args['size'][0], height=args['size'][1], recursiveDepth=args['recursive'][0], showMaterial=args['material']) else: # default setting setting = DefaultSetting(width=args['size'][0], height=args['size'][1], recursiveDepth=args['recursive'][0], showMaterial=args['material']) # display is used to set whether you want to have a visual feedback in a graphical user interface. display = not args['no_display'] # easier to read and you do not have to negotiate it on every call if display: window = Tk() window._root().wm_title('Raytracer - Tilman Ginzel (173388)') if args['verbose']: can = Canvas(window, width=setting.WIDTH, height=setting.HEIGHT) else: frame = Frame(window, width=setting.WIDTH, height=setting.HEIGHT) can = Canvas(frame, width=setting.WIDTH, height=setting.HEIGHT) frame = Frame(window) can.pack() # photoImage is used to show live changes while processing if args['verbose']: photoImage = PhotoImage(width=setting.WIDTH, height=setting.HEIGHT) can.create_image((setting.WIDTH/2, setting.HEIGHT/2), image=photoImage, state="normal") # pilImage is used to save the image after processing or if verbose is deactivated pilImage = Image.new("RGB", (setting.WIDTH, setting.HEIGHT), (0, 0, 0)) start = time.clock() processor = Processor(setting, display=display, ssaa=args['antialiasing']) print 'start processing...' for pixel in processor.startProcessing(): if display and args['verbose']: photoImage.put("#%02x%02x%02x" %((pixel[1][0], pixel[1][1], pixel[1][2])), (pixel[0][0], pixel[0][1])) if pixel[0][1] == setting.HEIGHT-1: # if y == bottom, update canvas can.update() pilImage.putpixel((pixel[0][0], pixel[0][1]), ((pixel[1][0], pixel[1][1], pixel[1][2]))) end = time.clock() print 'done' print 'duration: %2.2f seconds' %(end-start) if display and not args['verbose']: tkImage = ImageTk.PhotoImage(pilImage) label = Label(image=tkImage) label.image = tkImage label.pack() can.pack() if args['output']: saveImage(pilImage, args) if display: window.mainloop()
class Example(Frame): def __init__(self, parent, board): Frame.__init__(self, parent) self.board = board self.x0=[-x*10 for x in range(9, 13)] self.y0=[9*10 for x in range(9, 13)] self.x0=self.x0+[-13*10 for x in range(9, 13)] self.y0=self.y0+[x*10 for x in range(9, 13)] self.x0=self.x0+[-x*10 for x in [-i for i in range(-13,-8)]] self.y0=self.y0+[x*10 for x in [-i for i in range(-13,-8)]] #self.x0=self.x0+[-9*10 for x in [-i for i in range(-13,-8)]] #self.y0=self.y0+[x*10 for x in [-i for i in range(-13,-8)]] #self.x0=[-90 for x in range(70,210)] #self.y0=[x*1 for x in [-i for i in range(-200,-60)]] #print self.x0 #self.x0=[5*10 for x in [-i for i in range(-20,-10)]]+self.x0 #self.y0=[x*10 for x in [-i for i in range(-20,-10)]]+self.y0 #self.x0=[-90+35*math.cos(x*math.pi/180) for x in range(1, 361,4)] #self.y0=[-35*math.sin(x*math.pi/180)+90 for x in range(1, 361,4)] print len(self.x0) #self.tet1 = [i for i in range(90)] #self.tet2 = [i for i in range(45, 135)] self.tet1_con = 0 self.tet2_con = 0 self.count1 = 0 self.count2 = 0 self.sign1 = 1 self.sign2 = -1 self.parent = parent self.initUI() self.parent.after(0, self.animation) def initUI(self): self.parent.title("Arm") self.pack(fill=BOTH, expand=1) self.canvas = Canvas(self) #self.canvas.create_line(0, 0, 200, 100+self.count, width=arm_width) line = Line(self.canvas, points['1'], (width/2, hight/2)) arms.append(line) line = Line(self.canvas, 90-(points['2']-points['1']), line.cor1) arms.append(line) self.canvas.pack(fill=BOTH, expand=1) def animation(self): self.canvas.delete("all") #self.canvas.create_line(0, 0, 200, 100+self.count, width=arm_width) '''if points['1'] > 90 and self.sign1 == 1: self.sign1 = -1 elif points['1'] == 45 and self.sign1 == -1: self.sign1 = 1 if points['2'] > 135 and self.sign2 == 1: self.sign2 = -1 elif points['2'] == 90 and self.sign2 == -1: self.sign2 = 1 points['2']+=self.sign2 points['1']+=self.sign1''' #for i in range(0, len(self.x0), 2): # self.canvas.create_line(width/2+self.x0[i], hight/2-self.y0[i], # width/2+self.x0[i+1],hight/2-self.y0[i+1], width=5) #print 800/2+self.x0[0], 300+self.y0[0], 800/2+self.x0[-1],300+self.y0[-1] tet1, tet2 = getAngles(self.x0[self.count1], self.y0[self.count1]) #tet1, tet2 = getAngles(1.5, 0) #print (self.x0[self.count1], self.y0[self.count1]) #print (tet1, tet2) print 'tet1:',tet1, 'tet2:', tet2 #print 'tet2:', tet2 tet2t = tet2 tet1 = 180-(tet1) tet2 = 180-((tet2)-tet1)+180 tet1 = tet1 tet2 = tet2 temp = 0 if tet1 > 90: temp = 0 text = '('+str(tet1-10) +',' + str(180-(tet2-270)-10) + ')' print text self.canvas.create_text((width/2, hight-100),text=text) self.board.Servos.write(9, tet2t-10) self.board.Servos.write(11, tet1-10) #print (tet1, tet2) #line = arms[0].draw(tet1) #arms[1].draw(90-(tet2+tet1), line, 'red') line = arms[0].draw(tet1) arms[1].draw(tet2, line, 'red') self.count1+=self.sign1 if self.count1 == (len(self.x0)-1) and self.sign1 == 1: #self.sign1 = -1 self.count1=0 if self.count1 <= 0 and self.sign1 == -1: self.sign1 = 1 #self.x0=self.x01 #self.y0=self.y01 #line = arms[0].draw(points['1']) #arms[1].draw(90-(points['2']-points['1']), line) self.canvas.update() #self.count +=1 self.parent.after(50, self.animation)
class SurfaceManipulator(Frame): r""" A translation surface editor in tk. """ # STATIC METHODS AND OBJECTS current = None # boolean variable to remember if the hook was run! _clear_hook_was_run = 0 @staticmethod def launch(geometry = "800x700+10+10"): r"""Prefered way to gain access to a SurfaceManipulator window.""" if SurfaceManipulator.current is None: SurfaceManipulator._clear_hook() root = Tk() root.geometry(geometry) SurfaceManipulator.current=SurfaceManipulator(root) return SurfaceManipulator.current @staticmethod def _window_destroyed(surface_manipulator): if SurfaceManipulator.current is surface_manipulator: SurfaceManipulator.current = None @staticmethod def _clear_hook(): if not SurfaceManipulator._clear_hook_was_run: # Hack due to Nathan Dunfield (http://trac.sagemath.org/ticket/15152) import IPython.lib.inputhook as ih ih.clear_inputhook() SurfaceManipulator._clear_hook_was_run = 1 # NORMAL METHODS def __init__(self, parent, surface=None, surfaces=[]): r""" INPUT: - ``surfaces`` -- a list of surfaces that the editor may modify - ``surface`` -- surface selected by default - ``parent`` -- parent Tk window """ Frame.__init__(self, parent) self._parent = parent self.pack(fill="both", expand=1) # Run something when closing self._parent.wm_protocol ("WM_DELETE_WINDOW", self.exit) # Surface currently being manipulated self._surface=None # List of surfaces in editor self._surfaces=[] # More variables to initialize self._currentActor=None # Initialization of GUI self._init_menu() self._init_gui() # Setup surface list for s in surfaces: self.add_surface(s) # Setup initial surface if surface is not None: self.add_surface(surface) self.set_surface(surface) def __repr__(self): return "Surface manipulator" def add_mega_wollmilchsau(self): from geometry.mega_wollmilchsau import MegaWollmilchsau s = MegaWollmilchsau() sm,sb = s.get_bundle() self.set_surface(sb) def add_octagon(self): from geometry.similarity_surface_generators import TranslationSurfaceGenerators ss=TranslationSurfaceGenerators.regular_octagon() ss.edit() def _init_menu(self): self._menubar = Menu(self._parent) menubar=self._menubar self._parent.config(menu=menubar) #new_menu = Menu(menubar, tearoff=0) #new_menu.add_command(label="Billiard Table", command=self.on_new_similarity_surface) file_menu = Menu(menubar, tearoff=0) #file_menu.add_cascade(label="New", menu=new_menu) file_menu.add_command(label="Octagon", command=self.add_octagon) file_menu.add_command(label="MegaWollmilchsau", command=self.add_mega_wollmilchsau) file_menu.add_separator() file_menu.add_command(label="About", command=self.on_about) file_menu.add_command(label="Export PostScript", command=self.on_export) file_menu.add_command(label="Exit", command=self.exit, accelerator="Alt+F4") menubar.add_cascade(label="File", underline=0, menu=file_menu) self._surface_menu = Menu(menubar, tearoff=0) self._selected_surface = IntVar() self._selected_surface.set(-1) menubar.add_cascade(label="Surface", underline=0, menu=self._surface_menu) self._surface_menu.add_radiobutton(label="None", command=self.menu_select_surface, variable=self._selected_surface, value=-1) def _init_gui(self): self._parent.title("FlatSurf Editor") self._canvas = Canvas(self, bg="#444", width=300, height=200) self._canvas.pack(fill="both", expand=1) self.bottom_text = Label(self, text="Welcome to FlatSurf.", anchor="w") self.bottom_text.pack(fill="x", expand=0) self.set_actor(None) def add_surface(self,newsurface): r""" Add a surface to the display list for the window. Returns the index of the new surface in the surface list. """ if (newsurface==None): return -1 i=0 for s in self._surfaces: if (s==newsurface): return i i=i+1 self._surfaces.append(newsurface) newsurface.zoom_fit_nice_boundary() self._reset_surface_menu() return len(self._surfaces)-1 def exit(self): SurfaceManipulator._window_destroyed(self) self._parent.destroy() def find_bundle(self, surface): for surface_bundle in self._surfaces: if surface is surface_bundle.get_surface(): return surface_bundle return None def get_bundle(self): return self._surface def get_bundles(self): return self._surfaces def get_canvas(self): return self._canvas def get_center(self): r""" Return the center of the canvas as a pair of integers. """ return ( self.get_width()/2, self.get_height()/2 ) def get_height(self): r""" Return the height of the canvas (an integer). """ return self.get_canvas().winfo_height() def get_parent(self): return self._parent def get_surface_bundle(self): r""" Get the current surface bundle, or None if there is none. """ return self._surface def get_width(self): r""" Return the width of the canvas (an integer). """ return self.get_canvas().winfo_width() def menu_select_surface(self): r""" Called when a surface is selected from a menu. """ i = self._selected_surface.get() if i == -1: self.set_surface(None) else: self.set_surface(self._surfaces[i]) def on_about(self): self.set_text("Written by Vincent Delecroix and Pat Hooper.") def on_delete_junk(self): self._canvas.delete("junk") def on_export(self): r""" Export image as postscript file. """ myFormats = [('PostScript','*.ps')] fileName = tkFileDialog.asksaveasfilename(parent=self, filetypes=myFormats , title="Save image as...") if len(fileName ) > 0: self._canvas.update() self._canvas.postscript(file = fileName) self.set_text("Wrote image to "+fileName) # def on_new_similarity_surface(self): # s = CreateSimilaritySurfaceBundle(len(self._surfaces),self) # if s is not None: # i = self.set_surface(s) # self.set_text("Created new surface `"+self._surfaces[i].get_name()+"'.") def _on_no_surface(self): self._canvas.delete("all") def _on_zoom(self): self.set_actor(ZoomActor(self)) def _on_zoom_box(self): self.set_actor(ZoomBoxActor(self)) def _on_redraw_all(self): if self._surface is not None: self._surface.redraw_all() def _on_recenter(self): self.set_actor(RecenterActor(self)) def _reset_menus(self): r""" Reset all menus except the file and surface menu """ # The following loop removes all but the first two menus (File and Surface). num = len(self._menubar.children) for i in range(num,2,-1): self._menubar.delete(i) if self._surface!= None: self._surface.make_menus(self._menubar) def _reset_surface_menu(self): r""" Reset the surface menu. """ ### This is a hack to get the number of items in the menu: num = self._surface_menu.index(100)+1 # First we remove everything but the first entry ("None") for i in range(num-1,0,-1): #print("removing a child2: "+str(i)+" of "+str(num)) self._surface_menu.delete(i) # Add an entry for every surface in the list. for i in range( len(self._surfaces) ): surface = self._surfaces[i] self._surface_menu.add_radiobutton(label=surface.get_name(), command=self.menu_select_surface, variable=self._selected_surface, value=i) def set_text(self, text): self.bottom_text["text"]=text def set_actor(self, actor): r""" Set the current mode of user interaction. """ if (actor != self._currentActor): if self._currentActor != None: self._currentActor.on_deactivate() if (actor==None): self.set_text("Nothing going on.") # Event bindings self._canvas.unbind('<Button-1>') self._canvas.unbind('<Button-2>') self._canvas.unbind('<Button-3>') self._canvas.unbind('<Double-Button-1>') self._canvas.unbind('<Shift-Button-1>') self._canvas.unbind('<Motion>') self.unbind('<FocusIn>') self.unbind('<FocusOut>') #self._canvas.unbind('<ButtonPress-1>') self._canvas.unbind('<ButtonRelease-1>') self._canvas.unbind('<B1-Motion>') self._parent.unbind('<Key>') self._parent.unbind('<KeyRelease>') else: # Event bindings self._canvas.bind('<Button-1>', actor.single_left_click) self._canvas.bind('<Double-Button-1>', actor.double_left_click) self._canvas.bind('<Triple-Button-1>', actor.double_left_click) self._canvas.bind('<Button-2>', actor.single_middle_click) self._canvas.bind('<Double-Button-2>', actor.double_middle_click) self._canvas.bind('<Triple-Button-2>', actor.double_middle_click) self._canvas.bind('<Button-3>', actor.single_right_click) self._canvas.bind('<Double-Button-3>', actor.double_right_click) self._canvas.bind('<Triple-Button-3>', actor.double_right_click) self._canvas.bind('<Shift-Button-1>', actor.shift_click) self._canvas.bind('<Motion>', actor.mouse_moved) #self._canvas.bind('<ButtonPress-1>', actor.left_mouse_pressed) self._canvas.bind('<ButtonRelease-1>', actor.left_mouse_released) self._canvas.bind('<B1-Motion>',actor.left_dragged) self.bind('<FocusIn>', actor.focus_in) self.bind('<FocusOut>', actor.focus_out) self._parent.bind('<Key>', actor.key_press) self._parent.bind('<KeyRelease>', actor.key_release) self._currentActor=actor self._currentActor.on_activate() def set_surface(self,surface_bundle): r""" Set the current surface to the one given by surface_bundle """ i = self.add_surface(surface_bundle) if surface_bundle != self._surface: self._canvas.delete("all") self._surface=surface_bundle self._surface_menu.invoke(i+1) if i >= 0: self.set_text("Switched to `"+self._surface.get_name()+"'.") self._parent.title(self._surface.get_name()) self._reset_menus() # stop the actor (was a bug). self.set_actor(None) if isinstance(self._surface, EditorRenderer): self._surface.initial_render() else: self.set_text("No surface selected.") self._parent.title("FlatSurf Editor") self._reset_menus() self.set_actor(None) return i def surface_renamed(self): if self._surface is not None: self._parent.title(self._surface.get_name()) self._reset_surface_menu()
class ConsumablePinball(Domain): """ RL NOTES: Pinball Domain has a ballmodel and environment object. Statespace augmentation will be only done in the _DOMAIN_. The goal of this domain is to maneuver a small ball on a plate into a hole. The plate may contain obstacles which should be avoided. **STATE:** The state is given by a 4-dimensional vector, consisting of position and velocity of the ball. **ACTIONS:** There are 5 actions, standing for slanting the plat in x or y direction or a horizontal position of the plate. **REWARD:** Slanting the plate costs -4 reward in addition to -1 reward for each timestep. When the ball reaches the hole, the agent receives 10000 units of reward. **REFERENCE:** .. seealso:: G.D. Konidaris and A.G. Barto: *Skill Discovery in Continuous Reinforcement Learning Domains using Skill Chaining.* Advances in Neural Information Processing Systems 22, pages 1015-1023, December 2009. """ #: default location of config files shipped with rlpy default_config_dir = os.path.join( __rlpy_location__, "Domains", "PinballConfigs") # seems to only have one reasonable goalfn def __init__(self, goalArray, noise=.1, episodeCap=1000, configuration=os.path.join(default_config_dir, "pinball_simple_single.cfg"), goalfn=None, rewardFunction=None, encodingFunction=allMarkovEncoding): """ configuration: location of the configuration file episodeCap: maximum length of an episode noise: with probability noise, a uniformly random action is executed """ self.NOISE = noise self.configuration = configuration self.screen = None self.episodeCap = episodeCap self.actions_num = 5 self.actions = [ PinballModel.ACC_X, PinballModel.DEC_Y, PinballModel.DEC_X, PinballModel.ACC_Y, PinballModel.ACC_NONE] self.statespace_limits = np.array( [[0.0, 1.0], [0.0, 1.0], [-2.0, 2.0], [-2.0, 2.0]]) self.goalArray0 = np.array(goalArray) self.prev_states = [] # TODO fix initial state # statespace augmentation self.encodingFunction = encodingFunction encodingLimits = [] for i in range(0,len(self.encodingFunction(self.prev_states))): encodingLimits.append([0,1]) self.statespace_limits = np.vstack((self.statespace_limits, encodingLimits)) self.state_space_dims = len(self.statespace_limits) self.continuous_dims = np.arange(self.state_space_dims) self.DimNames = ["Dim: "+str(k) for k in range(0,2+len(self.encodingFunction(self.prev_states)))] self.rewardFunction = rewardFunction super(ConsumablePinball, self).__init__() self.environment = PinballModel( self.configuration, goalArray, goalfn=goalfn, random_state=self.random_state) def showDomain(self, a): if self.screen is None: master = Tk() master.title('RLPY Pinball') self.screen = Canvas(master, width=500.0, height=500.0) self.screen.configure(background='LightGray') self.screen.pack() self.environment_view = PinballView( self.screen, 500.0, 500.0, self.environment) self.environment_view.blit() self.screen.pack() self.screen.update() def step(self, a): s = self.state[:4] [self.environment.ball.position[0], self.environment.ball.position[1], self.environment.ball.xdot, self.environment.ball.ydot] = s if self.random_state.random_sample() < self.NOISE: # Random Move a = self.random_state.choice(self.possibleActions()) reward = self.environment.take_action(a) self.environment._check_bounds() state = np.array(self.environment.get_state()) self.prev_states.append(state[:4]) state = self.augment_state(state) self.state = state terminal = self.isTerminal() if not terminal and self.rewardFunction: sr = self.environment.STEP_PENALTY gr = self.environment.END_EPISODE reward = reward + self.rewardFunction(self.prev_states, self.goalArray(), sr, gr) return reward, state, terminal, self.possibleActions() def s0(self): #TODO reset this initial state; move logic into PinballModel self.environment.ball.position[0], self.environment.ball.position[ 1] = self.environment.start_pos self.environment.ball.xdot, self.environment.ball.ydot = 0.0, 0.0 self.state = np.array( [self.environment.ball.position[0], self.environment.ball.position[1], self.environment.ball.xdot, self.environment.ball.ydot]) self.prev_states = [] self.state = self.augment_state(self.state) self.environment.goalArray = np.array(self.goalArray0) return self.state, self.isTerminal(), self.possibleActions() def possibleActions(self, s=0): return np.array(self.actions) def isTerminal(self): return self.environment.episode_ended() or len(self.prev_states) == self.episodeCap def augment_state(self, state): return np.concatenate((state, self.encodingFunction(self.prev_states))) def goalArray(self): return self.environment.goalArray
class DiscreteTAMPViewer(object): def __init__(self, rows, cols, width=500, height=250, side=25, block_buffer=10, title='Grid', background='tan', draw_fingers=False): assert (rows <= MAX_ROWS) assert (cols <= MAX_COLS) tk = Tk() tk.withdraw() top = Toplevel(tk) top.wm_title(title) top.protocol('WM_DELETE_WINDOW', top.destroy) self.width = width self.height = height self.rows = rows self.cols = cols self.canvas = Canvas(top, width=self.width, height=self.height, background=background) self.canvas.pack() self.side = side self.block_buffer = block_buffer self.draw_fingers = draw_fingers self.cells = {} self.robot = [] self.draw_environment() def transform_r(self, r): return self.table_y1 + r * (self.side + 2 * self.block_buffer ) + 2 * self.block_buffer + self.side / 2 def transform_c(self, c): # assert r >= 0 and r < self.width return self.table_x1 + c * (self.side + 2 * self.block_buffer ) + 2 * self.block_buffer + self.side / 2 def draw_environment(self, table_color='lightgrey', bin_color='grey'): table_width = self.cols * ( self.side + 2 * self.block_buffer) + 2 * self.block_buffer table_height = self.rows * ( self.side + 2 * self.block_buffer) + 2 * self.block_buffer border_buffer = 50 #self.table_x1 = border_buffer self.table_y1 = self.height - table_height - border_buffer self.table_x1 = self.width / 2 - table_width / 2 #self.table_y1 = self.height/2-table_height/2 bin_width = 20 self.environment = [ self.canvas.create_rectangle(self.table_x1, self.table_y1, self.table_x1 + table_width, self.table_y1 + table_height, fill=table_color, outline='black', width=2), self.canvas.create_rectangle(self.table_x1 - bin_width, self.table_y1, self.table_x1, self.table_y1 + table_height, fill=bin_color, outline='black', width=2), self.canvas.create_rectangle(self.table_x1 + table_width, self.table_y1, self.table_x1 + table_width + bin_width, self.table_y1 + table_height, fill=bin_color, outline='black', width=2), self.canvas.create_rectangle(self.table_x1, self.table_y1 + table_height, self.table_x1 + table_width, self.table_y1 + table_height + bin_width, fill=bin_color, outline='black', width=2), self.canvas.create_rectangle( self.table_x1 - bin_width, self.table_y1 + table_height, self.table_x1 + table_width + bin_width, self.table_y1 + table_height + bin_width, fill=bin_color, outline='black', width=2), ] pose_radius = 2 for r in range(self.rows): for c in range(self.cols): x = self.transform_c(c) y = self.transform_r(r) self.environment.append( self.canvas.create_oval(x - pose_radius, y - pose_radius, x + pose_radius, y + pose_radius, fill='black')) def draw_robot(self, r, c, color='yellow'): # TODO - could also visualize as top grasps instead of side grasps grasp_buffer = 3 # 0 | 3 | 5 finger_length = self.side + grasp_buffer # + self.block_buffer finger_width = 10 gripper_length = 20 if self.draw_fingers: gripper_width = self.side + 2 * self.block_buffer + finger_width else: gripper_width = self.side stem_length = 50 stem_width = 20 x = self.transform_c(c) y = self.transform_r( r) - self.side / 2 - gripper_length / 2 - grasp_buffer finger_x = gripper_width / 2 - finger_width / 2 self.robot = [ self.canvas.create_rectangle(x - stem_width / 2., y - stem_length, x + stem_width / 2., y, fill=color, outline='black', width=2), self.canvas.create_rectangle(x - gripper_width / 2., y - gripper_length / 2., x + gripper_width / 2., y + gripper_length / 2., fill=color, outline='black', width=2), ] if self.draw_fingers: self.robot += [ self.canvas.create_rectangle(x + finger_x - finger_width / 2., y, x + finger_x + finger_width / 2., y + finger_length, fill=color, outline='black', width=2), self.canvas.create_rectangle(x - finger_x - finger_width / 2., y, x - finger_x + finger_width / 2., y + finger_length, fill=color, outline='black', width=2), ] self.canvas.update() def draw_block(self, r, c, name='', color='red'): x = self.transform_c(c) y = self.transform_r(r) self.cells[(x, y)] = [ self.canvas.create_rectangle(x - self.side / 2., y - self.side / 2., x + self.side / 2., y + self.side / 2., fill=color, outline='black', width=2), self.canvas.create_text(x, y, text=name), ] # def delete(self, (x, y)): # if (x, y) in self.cells: # self.canvas.delete(self.cells[(x, y)]) def clear(self): self.canvas.delete('all') def save(self, filename): self.canvas.postscript(file='%s.ps' % filename, colormode='color') from PIL import ImageGrab ImageGrab.grab((0, 0, self.width, self.height)).save(filename + '.jpg')
class DisplayQuadTree(object): def __init__(self, width, height, scale=1, show_grid=False): self._scale = scale self._grid_width = 1 if show_grid else 0 self.size = (width*scale, height*scale) self._is_animate = False self._anime_time = 0.1 self._tk_root = Tk() self._canvas = Canvas(self._tk_root, width=self.size[0], height=self.size[1]) self._canvas.pack() self._button = Button(self._tk_root, text='Finished', command=self._stop_animate) self._button.configure(width=10, relief=FLAT) self._canvas.create_window(10, 10, anchor=NW, window=self._button) self._labelstr = StringVar() self._labelstr.set('0%') self._label = Label(self._tk_root, textvariable=self._labelstr) self._canvas.create_window(self.size[0] - 10, self.size[1] - 10, anchor=SE, window=self._label) def static(self, qtree): """ Draw the final output. """ if qtree is None: return stack = [qtree] while len(stack): qnode = stack.pop() if qnode.children: for child in qnode.children: stack.append(child) else: colour = '#{0:02x}{1:02x}{2:02x}'.format(*qnode.ave_color) self._canvas.create_rectangle(qnode.x * self._scale, qnode.y * self._scale, (qnode.x + qnode.width) * self._scale, (qnode.y + qnode.height) * self._scale, width=self._grid_width, outline='grey', fill=colour) self._labelstr.set('100%') def _stop_animate(self): """ Stop the animation. Called by the "Stop" button """ self._is_animate = False self._button.configure(text='Finished') def animate(self, qtree): """ Animate the development of the quadtree as it was generated. Press the "Stop" to stop the animation """ if qtree is None: return self._is_animate = True self._button.configure(text='Stop') q = Queue.Queue() q.put(qtree) count, max_qtrees = 0.0, qtree.sq_num while not q.empty() and self._is_animate: qnode = q.get() if qnode.children: for child in qnode.children: q.put(child) count += 1.0 colour = '#{0:02x}{1:02x}{2:02x}'.format(*qnode.ave_color) self._canvas.create_rectangle(qnode.x * self._scale, qnode.y * self._scale, (qnode.x + qnode.width) * self._scale, (qnode.y + qnode.height) * self._scale, width=self._grid_width, outline='grey', fill=colour) self._canvas.update() self._labelstr.set('{}%'.format(int(count/max_qtrees * 100))) time.sleep(self._anime_time) self._stop_animate() def show(self): """ Call this to start the display. """ self._tk_root.mainloop()
class Pinball(Domain): """ The goal of this domain is to maneuver a small ball on a plate into a hole. The plate may contain obstacles which should be avoided. **STATE:** The state is given by a 4-dimensional vector, consisting of position and velocity of the ball. **ACTIONS:** There are 5 actions, standing for slanting the plat in x or y direction or a horizontal position of the plate. **REWARD:** Slanting the plate costs -4 reward in addition to -1 reward for each timestep. When the ball reaches the hole, the agent receives 10000 units of reward. **REFERENCE:** .. seealso:: G.D. Konidaris and A.G. Barto: *Skill Discovery in Continuous Reinforcement Learning Domains using Skill Chaining.* Advances in Neural Information Processing Systems 22, pages 1015-1023, December 2009. """ #: default location of config files shipped with rlpy default_config_dir = os.path.join(__rlpy_location__, "Domains", "PinballConfigs") def __init__(self, noise=.1, episodeCap=1000, configuration=os.path.join(default_config_dir, "pinball_simple_single.cfg")): """ configuration: location of the configuration file episodeCap: maximum length of an episode noise: with probability noise, a uniformly random action is executed """ self.NOISE = noise self.configuration = configuration self.screen = None self.episodeCap = episodeCap self.actions_num = 5 self.actions = [ PinballModel.ACC_X, PinballModel.DEC_Y, PinballModel.DEC_X, PinballModel.ACC_Y, PinballModel.ACC_NONE ] self.statespace_limits = np.array([[0.0, 1.0], [0.0, 1.0], [-2.0, 2.0], [-2.0, 2.0]]) self.continuous_dims = [4] super(Pinball, self).__init__() self.environment = PinballModel(self.configuration, random_state=self.random_state) def showDomain(self, a): if self.screen is None: master = Tk() master.title('RLPY Pinball') self.screen = Canvas(master, width=500.0, height=500.0) self.screen.configure(background='LightGray') self.screen.pack() self.environment_view = PinballView(self.screen, 500.0, 500.0, self.environment) self.environment_view.blit() self.screen.pack() self.screen.update() def step(self, a): s = self.state [ self.environment.ball.position[0], self.environment.ball.position[1], self.environment.ball.xdot, self.environment.ball.ydot ] = s if self.random_state.random_sample() < self.NOISE: # Random Move a = self.random_state.choice(self.possibleActions()) reward = self.environment.take_action(a) self.environment._check_bounds() state = np.array(self.environment.get_state()) self.state = state.copy() return reward, state, self.isTerminal(), self.possibleActions() def s0(self): self.environment.ball.position[0], self.environment.ball.position[ 1] = self.environment.start_pos self.environment.ball.xdot, self.environment.ball.ydot = 0.0, 0.0 self.state = np.array([ self.environment.ball.position[0], self.environment.ball.position[1], self.environment.ball.xdot, self.environment.ball.ydot ]) return self.state, self.isTerminal(), self.possibleActions() def possibleActions(self, s=0): return np.array(self.actions) def isTerminal(self): return self.environment.episode_ended()
class SimVis(object): """Defines the visualisation aspects of the program. Draws and updates all visuals.""" SNAPSHOT_ENABLED = ENABLED = DEBUG_ID_ENABLED = HIGHLIGHT_COLLISIONS = SQUARESIZE = SNAPSHOT_HEIGHT = SNAPSHOT_WIDTH = None def __init__(self, width, height, squareSize): self.simRootPath = "" self.setSimRootPath(SimUtils.getRootPath()) self.currentFolder = self.simRootPath self.simRun = 0; self.simRunFolder = "" self.__initImageFolder() self.__updateSimRunFolder() self.width = width self.height = height self.root = Tk() self.squareSize = squareSize self.CANVAS_WIDTH = (self.width * squareSize) self.CANVAS_HEIGHT = (self.height * squareSize) + CANVAS_TEXT_PADDING self.canvas = Canvas(self.root, width=self.CANVAS_WIDTH, height=self.CANVAS_HEIGHT, bg='white') self.canvas.pack() self.timeFont = ImageFont.truetype("Arialbd.ttf", CANVAS_TEXT_SIZE) self.time = 0.0 self.timeMeasurement = "timesteps" self.timeStepsInMeasurement = 1 self.timeText = None self.__updateTimeText() self.root.minsize(self.CANVAS_WIDTH, self.CANVAS_HEIGHT) self.root.geometry(str(self.CANVAS_WIDTH)+"x"+str(self.CANVAS_HEIGHT)) self.world = None self.white = (255, 255, 255) # PIL image can be saved as .png .jpg .gif or .bmp file (among others) self.filenameJPG = None self.filename = None # PIL create an empty image and draw object to draw on # memory only, not visible self.image = Image.new("RGB", (self.CANVAS_WIDTH, self.CANVAS_HEIGHT), self.white) self.draw = ImageDraw.Draw(self.image) def __updateSimRunFolder(self) : if self.simRun > 0 : self.simRunFolder = SIM_RUN_DIR_PREFIX + str(self.simRun) + "/" else : self.simRunFolder = "" imageFolder = self.__getImageFolder() SimUtils.initFolder(folderName=imageFolder) def __updateTimeText(self) : self.timeText = TIME_TEXT_PREFIX + str(self.time) + " " + self.timeMeasurement def setTimeStepsInMeasurement(self, val): self.timeStepsInMeasurement = val self.__updateTimeText() def setTimeMeasurement(self, measurement): self.timeMeasurement = measurement self.__updateTimeText() def init(self, world, run=0) : self.canvas.delete("all") self.world = world self.setSimRun(run) def display(self): self.root.mainloop() # this method will hang until you close the TK (window), but is essential to display the window and canvas # Draw a 10 X 10 sqaure on the canvas with no border def drawSquare(self, x, y, color): if self.world[x][y].drawColor == color : return self.world[x][y].drawColor = color xPos = x * self.squareSize yPos = y * self.squareSize self.draw.rectangle([xPos , yPos, xPos + self.squareSize - 1, yPos + self.squareSize - 1], fill=color) # TODO: Remove this in final version? def __focusDebugDraw(self, x, y, id, colour): self.draw.text((x, y), str(id), fill=colour) #Draw an Epithelial Cell, the colour is set depandant on its state def drawEpiCell(self, eCell): x = eCell.location.x y = eCell.location.y color = None if(eCell.State == EpithelialStates.HEALTHY) : color = "#FCFEF5" elif(eCell.State == EpithelialStates.CONTAINING): color = "#F9D423" elif(eCell.State == EpithelialStates.EXPRESSING): color = "#FC913A" elif(eCell.State == EpithelialStates.INFECTIOUS): color = "#C21A01" elif(eCell.State == EpithelialStates.NATURAL_DEATH or eCell.State == EpithelialStates.INFECTION_DEATH): color = "#000000" else: raise AttributeError('Illegal Epithelial Cell State') self.drawSquare(x, y, color) # TODO: Remove this in final version? if SimVis.DEBUG_ID_ENABLED: if eCell.focusId != None: if eCell.State == EpithelialStates.INFECTION_DEATH: self.__focusDebugDraw(x * self.squareSize, y * self.squareSize, eCell.focusId, "#FFFFFF") else: self.__focusDebugDraw(x * self.squareSize, y * self.squareSize, eCell.focusId, "#000000") def drawSimWorld(self, save, timesteps): if self.width == 0 and self.height == 0 : return #self.image = Image.new("RGB", (self.CANVAS_WIDTH, self.CANVAS_HEIGHT), self.white) #self.draw = ImageDraw.Draw(self.image) for x in xrange(0, self.width) : for y in xrange(0, self.height) : site = self.world[x][y] drawImmCell = False immCells = site.getImmCells() if len(immCells) > 0 : mature = False for immCell in immCells : if immCell.State == ImmuneStates.MATURE : self.drawImmCell(immCell) drawImmCell = True mature = True break if mature == False : self.drawImmCell(immCell) drawImmCell = True if drawImmCell == False : eCell = site.getECell() self.drawEpiCell(eCell) self.time = round(timesteps / self.timeStepsInMeasurement, 1) self.__updateTimeText() w, h = self.draw.textsize(self.timeText, self.timeFont) x = (self.CANVAS_WIDTH / 2) - (w/2) y = (self.CANVAS_HEIGHT - (CANVAS_TEXT_PADDING/2) - (h/2)) self.draw.text((x, y), self.timeText, (0,0,0), font=self.timeFont) self.__savePILImageToFile(save) self.__updateCanvas(save) self.draw.rectangle([0, self.CANVAS_HEIGHT - CANVAS_TEXT_PADDING, self.CANVAS_WIDTH, self.CANVAS_HEIGHT], fill="white") #del self.draw #del self.image def drawImmCell(self, immCell): x = immCell.location.x y = immCell.location.y color = None if(immCell.State == ImmuneStates.VIRGIN) : color = "#C0D860" elif(immCell.State == ImmuneStates.MATURE): color = "#789048" else: raise AttributeError('Illegal Immune Cell State') self.drawSquare(x, y, color) def drawCollision(self, cell): self.drawSquare(cell.location.x, cell.location.y, "#5078F0") if SimVis.DEBUG_ID_ENABLED: self.__focusDebugDraw(cell.location.x * self.squareSize, cell.location.y * self.squareSize, str(cell.focusId), "#000000") def __initImageFolder(self): SimUtils.initFolder(folderParent=self.simRootPath, folderName=IMAGES_DIR_NAME, overwrite=True) SimUtils.initFolderPath(folderPath=self.__getTempFolder(), overwrite=True) def __getImageFolder(self): return self.simRootPath + IMAGES_DIR_NAME + self.simRunFolder def __getTempFolder(self): return self.simRootPath + IMAGES_DIR_NAME + TEMP_DIR_NAME def __savePILImageToFile(self, save): imageFolder = self.__getImageFolder() tempFolder = self.__getTempFolder() if save : self.filenameJPG = imageFolder + self.__getImageFileName() self.image.save(self.filenameJPG) self.filename = tempFolder + IMAGE_NAME_PREFIX + TEMP_IMAGE_EXTENSION self.image.save(self.filename) def __getImageFileName(self) : return IMAGE_NAME_PREFIX + "_" + str(int(self.time)) + self.timeMeasurement + "_" + str(self.height) + "x" + str(self.width) + IMAGE_EXTENSION def __updateCanvas(self, save): # draw PIL image to tkinter canvas self.canvas.background = PhotoImage(file=self.filename) self.canvas.create_image(2, 2, image=self.canvas.background, anchor="nw") self.canvas.update() def setSimRootPath(self, folderPath): if folderPath == "" : folderPath = "." if folderPath[len(folderPath) - 1] != '/' : folderPath += '/' self.simPathFolder = folderPath def setSimRun(self, run): self.simRun = run; self.__updateSimRunFolder(); @staticmethod def Configure(settings): SimVis.ENABLED = settings["bIsEnabled"] SimVis.SNAPSHOT_ENABLED = settings["bSnapshotEnabled"] SimVis.SNAPSHOT_HEIGHT = settings["iSnapshotHeight"] SimVis.SNAPSHOT_WIDTH = settings["iSnapshotWidth"] SimVis.SQUARESIZE = settings["iSquareSize"] SimVis.DEBUG_ID_ENABLED = settings["bDebugFocusIdEnabled"] SimVis.HIGHLIGHT_COLLISIONS = settings["bHighlightCollisions"]
class at_graph(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.u = utils('atoutput.pkl') self.km = dict() self.price = dict() self.km[0] = (min(self.u.all_km), max(self.u.all_km)) self.price[0] = (min(self.u.all_price), max(self.u.all_price)) self.zoom_level = 0 try: self.parent.title("Auto trader results") self.is_standalone = True except: self.is_standalone = False self.style = Style() self.style.theme_use("classic") # Assume the parent is the root widget; make the frame take up the # entire widget size. print self.is_standalone if self.is_standalone: self.w, self.h = map(int, self.parent.geometry().split('+')[0].split('x')) self.w, self.h = 800, 800 else: self.w, self.h = 600, 600 self.c = None # Are they hovering over a data point? self.is_hovering = False # Filter the description strings: lower and whiten any non-matching # data point. self.filter = '' self.re = list() self.replot() def replot(self, zlfrac=None): """Replot the graph. If zlfrac is not None, then it should be a fractional value between 0 and 1; this is used to do smooth zooming, which doesn't plot the axes (it only redraws the car points).""" if self.c is not None: self.c.destroy() self.c = Canvas(self, height=self.h, width=self.w, bd=1, bg='#f3f5f9') self.c.grid(sticky=S, pady=1, padx=1) zl = self.zoom_level if zlfrac is not None: z1l, z1h = self.zoom_price_start z2l, z2h = self.zoom_price_end price_low = z1l + (z2l - z1l) * zlfrac price_high = z1h + (z2h - z1h) * zlfrac z1l, z1h = self.zoom_km_start z2l, z2h = self.zoom_km_end km_low = z1l + (z2l - z1l) * zlfrac km_high = z1h + (z2h - z1h) * zlfrac self.axis((price_low, price_high), 'y', draw=False) self.axis((km_low, km_high), 'x', draw=False) self.car_points(draw=False) else: self.axis(self.price[zl], 'y') self.axis(self.km[zl], 'x') self.car_points() self.pack(fill=BOTH, expand=1) def xyp(self, x, y): "Given x in km and y in $, return canvas position (xp, yp)." xp = int(math.floor((1.0 * x - self.x1) / (self.x2 - self.x1) \ * (self.xp2 - self.xp1) + self.xp1 + 0.5)) yp = int(math.floor((1.0 * y - self.y1) / (self.y2 - self.y1) \ * (self.yp2 - self.yp1) + self.yp1 + 0.5)) return (xp, yp) def axis(self, arange, ax, draw=True): "Add an axis ax='x' or 'y', with arange=(min, max) values." if draw: a1, a2, ast = self.u.axis(*arange) else: a1, a2 = arange ast = (a2 - a1) * 0.2 nt = int(math.floor((a2 - a1) / ast + 0.5)) + 1 st_offset = 50 # Remember the min and max axis values, along with the canvas points # that correspond to each location (xp1 and xp2). This allows us to # calculate where on the canvas a particular (x, y) value falls. if ax == 'x': self.x1, self.x2 = a1, a2 self.xp1, self.xp2 = st_offset, self.w - st_offset self.xtick = [a1 + i * ast for i in range(nt)] # Remember where the midpoint of the axis is, relative to canvas. self.xmid = (self.xp1 + self.xp2) / 2 else: self.y1, self.y2 = a1, a2 self.yp1, self.yp2 = self.h - st_offset, st_offset self.ytick = [a1 + i * ast for i in range(nt)] # Remember where the midpoint of the axis is, relative to canvas. self.ymid = (self.yp1 + self.yp2) / 2 # Figure out tick labels. atick = ['%g' % ((a1 + i * ast) / 1000) for i in range(nt)] # Figure out maximum decimal places on all tick labels, and ensure # they all have that many decimal places. max_dec = max(map(lambda x: 0 if '.' not in x else len(x.split('.')[1]), atick)) if max_dec > 0: atick = map(lambda x: x + '.' + '0'*max_dec if '.' not in x else x + '0'*(max_dec - len(x.split('.')[1])), atick) yst, xst = self.h - st_offset, st_offset # Draw axis line proper, and axis label. if draw: if ax == 'x': self.c.create_line(xst, yst, self.w - st_offset, yst) xp = (xst + self.w - st_offset) / 2 self.c.create_text(xp, yst + 30, text='Mileage (km x 1000)') else: self.c.create_line(xst, yst, xst, st_offset) self.c.create_text(xst, st_offset - 30, text='Price') self.c.create_text(xst, st_offset - 15, text='($000)') tick_anchor = [N, E][ax == 'y'] tick_x, tick_y = xst, yst tick_step = ([self.w, self.h][ax == 'y'] - st_offset * 2 * 1.0) / \ (nt - 1) label_offset = 3 for i1, tick in enumerate(atick): x_of, y_of = -label_offset, label_offset if ax == 'y': y_of = int(-i1 * tick_step) else: x_of = int(i1 * tick_step) if draw: self.c.create_text(tick_x + x_of, tick_y + y_of, text=tick, anchor=tick_anchor) x_mini, y_mini = 0, 0 x_maxi, y_maxi = 0, 0 if ax == 'y': x_of += label_offset x_mini, x_maxi = 8, self.w - st_offset * 2 # Remember what y coord this grid line is at. if i1 == 0: self.y_grid = [] self.y_grid.append(tick_y + y_of) else: y_of -= label_offset y_mini, y_maxi = -8, st_offset * 2 - self.h # Remember what x coord this grid line is at. if i1 == 0: self.x_grid = [] self.x_grid.append(tick_x + x_of) if draw: # Draw the little solid tick, next to the axis. self.c.create_line(tick_x + x_of, tick_y + y_of, tick_x + x_of + x_mini, tick_y + y_of + y_mini) # Draw a dashed grid line, across the entire graph. self.c.create_line(tick_x + x_of, tick_y + y_of, tick_x + x_of + x_maxi, tick_y + y_of + y_maxi, dash=(1, 3)) def car_points(self, draw=True): "Plot the cars themselves." # 199 215 151 151 199 224 230 162 157 250 224 167 178 165 192 249 200 216 204 204 204 191 173 158 color_order = ['#c7d797', '#97c7e0', '#e6a29d', '#fae0a7', '#b2a5c0', '#f9c8d8', '#bfad9e', '#cccccc'] #color_order = ['#98df8a', '#dbdb8d', '#aec7e8', '#c9acd4', '#f7b6d2', # '#ffbb80', '#dc9b8d', '#e9ab17', '#dddddd'] # Those colors above aren't saturated enough. Saturate them more. color_order = map(lambda x: resaturate(x, -80), color_order) # Change color depending on year. cy = dict() for i1, year in enumerate(reversed(sorted(set(self.u.all_year)))): cy[year] = color_order[-1] if i1 < len(color_order): cy[year] = color_order[i1] i1 = -1 # Tuples of (index into self.u.all_* arrays, x position, y position). self.ov_dict = dict() if draw: self.c.focus_set() self.c.bind('<Button-1>', func=self.zoom) self.c.bind('<Button-2>', func=self.unzoom) self.c.bind('<Left>', func=self.left_key) self.c.bind('<Right>', func=self.right_key) self.c.bind('<Up>', func=self.up_key) self.c.bind('<Down>', func=self.down_key) legend = set() osz = 3 + self.zoom_level * 1 # Total vehicle count, and vehicles which pass the filter count. self.vcount = self.fcount = 0 for year, km, price in zip(self.u.all_year, self.u.all_km, self.u.all_price): x, y = self.xyp(km, price) i1 += 1 if x < self.x_grid[0] or x > self.x_grid[-1] or \ y > self.y_grid[0] or y < self.y_grid[-1]: continue self.vcount += 1 legend.add((year, cy[year])) filtered = False if not re.search(self.filter, self.u.all_descr[i1], re.I): filtered = True # If a data point is filtered out, make its outline reflect its # model year, and fill it with white. # # Else, make its outline and fill color reflect the model year, and # upon mouseover, make it entirely red. ov = self.c.create_oval(x-osz, y-osz, x+osz, y+osz, outline=cy[year], activeoutline=['red', cy[year]][filtered], fill=[cy[year], 'white'][filtered], activefill=['red', 'white'][filtered], ) self.ov_dict[ov] = (i1, x, y, cy[year], filtered) # If a data point is filtered out, mousing over it does nothing, # and also, lower it behind everything else. if filtered: self.c.lower(ov) else: self.fcount += 1 if draw: use_tag = 'Tag %d' % i1 self.c.addtag_withtag(use_tag, ov) self.c.tag_bind(use_tag, sequence='<Enter>', func=self.mouseover) self.c.tag_bind(use_tag, sequence='<Leave>', func=self.mouseoff) self.c.tag_bind(use_tag, sequence='<Button-1>', func=self.select) if draw: # OK, add a legend for every year that's displayed. i1 = 0 for yr, color in reversed(sorted(legend)): xp, yp = self.x_grid[-1] + 10, self.y_grid[-1] + 15 * i1 self.c.create_oval(xp-osz, yp-osz, xp+osz, yp+osz, outline=color, fill=color) self.c.create_text(xp + 8, yp, text=str(yr), anchor=W) i1 += 1 # And, add a title. tistr = 'Vehicle count: %d' % self.vcount if self.fcount != self.vcount: tistr = 'Filtered vehicle count: %d' % self.fcount xp = (self.x_grid[0] + self.x_grid[-1]) / 2 yp = self.y_grid[-1] - 30 self.c.create_text(xp, yp, text=tistr, font=('Helvetica', '16')) zstr1 = 'Click on a blank graph location to zoom in' zstr2 = 'Right click to zoom out' if self.zoom_level == 0: zstr = zstr1 elif self.zoom_level == 2: zstr = zstr2 else: zstr = zstr1 + ', or r' + zstr2[1:] self.c.create_text(xp, yp + 16, text=zstr, font=('Helvetica', '14')) def mouseover(self, event): oval = event.widget.find_closest(event.x, event.y)[0] # XXX Sometimes, the closest widget is an axis grid line, not an oval. # Need to handle this correctly eventually. if oval not in self.ov_dict: return self.is_hovering = True ind, x, y, color, filtered = self.ov_dict[oval] # Figure out how high the box needs to be by creating the text off- # graph, then getting its bbox and deleting it. w = 200 de_text = self.u.all_descr[ind] deobj = self.c.create_text(self.w + 3, self.h + 3, text=de_text, anchor=N+W, width=w-6, font=('Helvetica', '14')) bbox = self.c.bbox(deobj) self.c.delete(deobj) h = 18 + bbox[3] - bbox[1] border = 5 if x > self.xmid: x -= (w + border) else: x += border if y > self.ymid: y -= (h + border) else: y += border self.re = list() self.re.append(self.c.create_rectangle(x, y, x + w, y + h, fill=resaturate(color, 50))) pr_text = '$%s' % self.u.commafy(self.u.all_price[ind]) self.re.append(self.c.create_text(x + 3, y + 3, text=pr_text, anchor=N+W, font=('Helvetica', '10'))) km_text = '%skm' % self.u.commafy(self.u.all_km[ind]) self.re.append(self.c.create_text(x + w - 3, y + 3, text=km_text, anchor=N+E, font=('Helvetica', '10'))) wh_text = self.u.all_wherestr[ind] if wh_text[0].isdigit(): wh_text += ' away' self.re.append(self.c.create_text(x + w/2, y + 3, text=wh_text, anchor=N, font=('Helvetica', '10'))) self.re.append(self.c.create_text(x + 3, y + 16, text=de_text, anchor=N+W, width=w-6, font=('Helvetica', '14'))) def set_filter(self, st): "Given a string 'st', filter ovals whose description doesn't match." self.filter = st self.replot() def mouseoff(self, event): "Code for mousing off a data point." # The tooptip rectangle and all its sub-objects need to be destroyed. map(self.c.delete, self.re) # Also, need to note that we're no longer over an oval -- that way, # Button-1 events will cause a zoom, rather than launching a web page. self.is_hovering = False def _zoom_animation(self): import time from math import tanh scale = 5 for i1 in range(-scale, scale+1): self.replot(zlfrac=0.5 + 0.5*tanh(i1*2.0/scale)/tanh(2.0)) self.c.update() def zoom(self, event): # Only zoom in if we're actually within the graph boundaries. if event.x <= self.x_grid[0] or event.x > self.x_grid[-1]: return if event.y >= self.y_grid[0] or event.y < self.y_grid[-1]: return # Don't zoom if we're hovering over a data point: let the web browser # event handler operate. if self.is_hovering: return # Don't zoom in more than twice. if self.zoom_level >= 2: return # Find the grid square which we're inside. for i1 in range(len(self.x_grid) - 1): if event.x <= self.x_grid[i1 + 1]: xgrid = i1 + 1 break for i1 in range(len(self.y_grid) - 1): if event.y >= self.y_grid[i1 + 1]: ygrid = i1 + 1 break self.zoom_level += 1 zl = self.zoom_level # Make the limits of the new graph be those of the grid square which # was clicked inside. self.km[zl] = (self.xtick[xgrid-1], self.xtick[xgrid]) self.price[zl] = (self.ytick[ygrid-1], self.ytick[ygrid]) if zl == 1: self.zoom_price_start = self.u.axis(*self.price[0])[:2] self.zoom_km_start = self.u.axis(*self.km[0])[:2] else: self.zoom_price_start = self.price[zl - 1] self.zoom_km_start = self.km[zl - 1] self.zoom_price_end = self.price[zl] self.zoom_km_end = self.km[zl] self._zoom_animation() self.replot() def unzoom(self, event): # If already at maximum zoom, nothing to be done. if self.zoom_level == 0: return # If not clicking inside graph boundaries, don't unzoom. if event.x <= self.x_grid[0] or event.x > self.x_grid[-1]: return if event.y >= self.y_grid[0] or event.y < self.y_grid[-1]: return self.zoom_level -= 1 zl = self.zoom_level self.zoom_price_start = self.price[zl + 1] self.zoom_km_start = self.km[zl + 1] if zl == 0: self.zoom_price_end = self.u.axis(*self.price[0])[:2] self.zoom_km_end = self.u.axis(*self.km[0])[:2] else: self.zoom_price_end = self.price[zl] self.zoom_km_end = self.km[zl] self._zoom_animation() self.replot() def left_key(self, event): zl = self.zoom_level if zl == 0: return # If at left edge already, don't scroll. kz = self.km[zl] if self.km[0][0] > kz[0]: return self.zoom_price_start = self.zoom_price_end = self.price[zl] self.zoom_km_start = kz self.km[zl] = (kz[0] - (kz[1] - kz[0]), kz[0]) self.zoom_km_end = self.km[zl] self._zoom_animation() self.replot() def right_key(self, event): zl = self.zoom_level if zl == 0: return # If at right edge already, don't scroll. kz = self.km[zl] if self.km[0][1] < kz[1]: return self.zoom_price_start = self.zoom_price_end = self.price[zl] self.zoom_km_start = kz self.km[zl] = (kz[1], kz[1] + (kz[1] - kz[0])) self.zoom_km_end = self.km[zl] self._zoom_animation() self.replot() def down_key(self, event): zl = self.zoom_level if zl == 0: return # If at bottom edge already, don't scroll. pz = self.price[zl] if self.price[0][0] > pz[0]: return self.zoom_km_start = self.zoom_km_end = self.km[zl] self.zoom_price_start = pz self.price[zl] = (pz[0] - (pz[1] - pz[0]), pz[0]) self.zoom_price_end = self.price[zl] self._zoom_animation() self.replot() def up_key(self, event): zl = self.zoom_level if zl == 0: return # If at top edge already, don't scroll. pz = self.price[zl] if self.price[0][1] < pz[1]: return self.zoom_km_start = self.zoom_km_end = self.km[zl] self.zoom_price_start = pz self.price[zl] = (pz[1], pz[1] + (pz[1] - pz[0])) self.zoom_price_end = self.price[zl] self._zoom_animation() self.replot() def select(self, event): "Open a web page, when a data point has been clicked on." oval = event.widget.find_closest(event.x, event.y)[0] # XXX As above, sometimes the closest widget is a grid line, not an # oval. Need to handle this correctly, eventually. if oval not in self.ov_dict: return ind, xp, yp, color, filtered = self.ov_dict[oval] webbrowser.open(self.u.all_alink[ind])
class SurfaceManipulator(Frame): r""" A translation surface editor in tk. """ # STATIC METHODS AND OBJECTS current = None # boolean variable to remember if the hook was run! _clear_hook_was_run = 0 @staticmethod def launch(geometry="800x700+10+10"): r"""Prefered way to gain access to a SurfaceManipulator window.""" if SurfaceManipulator.current is None: SurfaceManipulator._clear_hook() root = Tk() root.geometry(geometry) SurfaceManipulator.current = SurfaceManipulator(root) return SurfaceManipulator.current @staticmethod def _window_destroyed(surface_manipulator): if SurfaceManipulator.current is surface_manipulator: SurfaceManipulator.current = None @staticmethod def _clear_hook(): if not SurfaceManipulator._clear_hook_was_run: # Hack due to Nathan Dunfield (http://trac.sagemath.org/ticket/15152) import IPython.lib.inputhook as ih ih.clear_inputhook() SurfaceManipulator._clear_hook_was_run = 1 # NORMAL METHODS def __init__(self, parent, surface=None, surfaces=[]): r""" INPUT: - ``surfaces`` -- a list of surfaces that the editor may modify - ``surface`` -- surface selected by default - ``parent`` -- parent Tk window """ Frame.__init__(self, parent) self._parent = parent self.pack(fill="both", expand=1) # Run something when closing self._parent.wm_protocol("WM_DELETE_WINDOW", self.exit) # Surface currently being manipulated self._surface = None # List of surfaces in editor self._surfaces = [] # More variables to initialize self._currentActor = None # Initialization of GUI self._init_menu() self._init_gui() # Setup surface list for s in surfaces: self.add_surface(s) # Setup initial surface if surface is not None: self.add_surface(surface) self.set_surface(surface) def __repr__(self): return "Surface manipulator" def add_mega_wollmilchsau(self): from geometry.mega_wollmilchsau import MegaWollmilchsau s = MegaWollmilchsau() sm, sb = s.get_bundle() self.set_surface(sb) def add_octagon(self): from geometry.similarity_surface_generators import TranslationSurfaceGenerators ss = TranslationSurfaceGenerators.regular_octagon() ss.edit() def _init_menu(self): self._menubar = Menu(self._parent) menubar = self._menubar self._parent.config(menu=menubar) #new_menu = Menu(menubar, tearoff=0) #new_menu.add_command(label="Billiard Table", command=self.on_new_similarity_surface) file_menu = Menu(menubar, tearoff=0) #file_menu.add_cascade(label="New", menu=new_menu) file_menu.add_command(label="Octagon", command=self.add_octagon) file_menu.add_command(label="MegaWollmilchsau", command=self.add_mega_wollmilchsau) file_menu.add_separator() file_menu.add_command(label="About", command=self.on_about) file_menu.add_command(label="Export PostScript", command=self.on_export) file_menu.add_command(label="Exit", command=self.exit, accelerator="Alt+F4") menubar.add_cascade(label="File", underline=0, menu=file_menu) self._surface_menu = Menu(menubar, tearoff=0) self._selected_surface = IntVar() self._selected_surface.set(-1) menubar.add_cascade(label="Surface", underline=0, menu=self._surface_menu) self._surface_menu.add_radiobutton(label="None", command=self.menu_select_surface, variable=self._selected_surface, value=-1) def _init_gui(self): self._parent.title("FlatSurf Editor") self._canvas = Canvas(self, bg="#444", width=300, height=200) self._canvas.pack(fill="both", expand=1) self.bottom_text = Label(self, text="Welcome to FlatSurf.", anchor="w") self.bottom_text.pack(fill="x", expand=0) self.set_actor(None) def add_surface(self, newsurface): r""" Add a surface to the display list for the window. Returns the index of the new surface in the surface list. """ if (newsurface == None): return -1 i = 0 for s in self._surfaces: if (s == newsurface): return i i = i + 1 self._surfaces.append(newsurface) newsurface.zoom_fit_nice_boundary() self._reset_surface_menu() return len(self._surfaces) - 1 def exit(self): SurfaceManipulator._window_destroyed(self) self._parent.destroy() def find_bundle(self, surface): for surface_bundle in self._surfaces: if surface is surface_bundle.get_surface(): return surface_bundle return None def get_bundle(self): return self._surface def get_bundles(self): return self._surfaces def get_canvas(self): return self._canvas def get_center(self): r""" Return the center of the canvas as a pair of integers. """ return (self.get_width() / 2, self.get_height() / 2) def get_height(self): r""" Return the height of the canvas (an integer). """ return self.get_canvas().winfo_height() def get_parent(self): return self._parent def get_surface_bundle(self): r""" Get the current surface bundle, or None if there is none. """ return self._surface def get_width(self): r""" Return the width of the canvas (an integer). """ return self.get_canvas().winfo_width() def menu_select_surface(self): r""" Called when a surface is selected from a menu. """ i = self._selected_surface.get() if i == -1: self.set_surface(None) else: self.set_surface(self._surfaces[i]) def on_about(self): self.set_text("Written by Vincent Delecroix and Pat Hooper.") def on_delete_junk(self): self._canvas.delete("junk") def on_export(self): r""" Export image as postscript file. """ myFormats = [('PostScript', '*.ps')] fileName = tkFileDialog.asksaveasfilename(parent=self, filetypes=myFormats, title="Save image as...") if len(fileName) > 0: self._canvas.update() self._canvas.postscript(file=fileName) self.set_text("Wrote image to " + fileName) # def on_new_similarity_surface(self): # s = CreateSimilaritySurfaceBundle(len(self._surfaces),self) # if s is not None: # i = self.set_surface(s) # self.set_text("Created new surface `"+self._surfaces[i].get_name()+"'.") def _on_no_surface(self): self._canvas.delete("all") def _on_zoom(self): self.set_actor(ZoomActor(self)) def _on_zoom_box(self): self.set_actor(ZoomBoxActor(self)) def _on_redraw_all(self): if self._surface is not None: self._surface.redraw_all() def _on_recenter(self): self.set_actor(RecenterActor(self)) def _reset_menus(self): r""" Reset all menus except the file and surface menu """ # The following loop removes all but the first two menus (File and Surface). num = len(self._menubar.children) for i in range(num, 2, -1): self._menubar.delete(i) if self._surface != None: self._surface.make_menus(self._menubar) def _reset_surface_menu(self): r""" Reset the surface menu. """ ### This is a hack to get the number of items in the menu: num = self._surface_menu.index(100) + 1 # First we remove everything but the first entry ("None") for i in range(num - 1, 0, -1): #print("removing a child2: "+str(i)+" of "+str(num)) self._surface_menu.delete(i) # Add an entry for every surface in the list. for i in range(len(self._surfaces)): surface = self._surfaces[i] self._surface_menu.add_radiobutton( label=surface.get_name(), command=self.menu_select_surface, variable=self._selected_surface, value=i) def set_text(self, text): self.bottom_text["text"] = text def set_actor(self, actor): r""" Set the current mode of user interaction. """ if (actor != self._currentActor): if self._currentActor != None: self._currentActor.on_deactivate() if (actor == None): self.set_text("Nothing going on.") # Event bindings self._canvas.unbind('<Button-1>') self._canvas.unbind('<Button-2>') self._canvas.unbind('<Button-3>') self._canvas.unbind('<Double-Button-1>') self._canvas.unbind('<Shift-Button-1>') self._canvas.unbind('<Motion>') self.unbind('<FocusIn>') self.unbind('<FocusOut>') #self._canvas.unbind('<ButtonPress-1>') self._canvas.unbind('<ButtonRelease-1>') self._canvas.unbind('<B1-Motion>') self._parent.unbind('<Key>') self._parent.unbind('<KeyRelease>') else: # Event bindings self._canvas.bind('<Button-1>', actor.single_left_click) self._canvas.bind('<Double-Button-1>', actor.double_left_click) self._canvas.bind('<Triple-Button-1>', actor.double_left_click) self._canvas.bind('<Button-2>', actor.single_middle_click) self._canvas.bind('<Double-Button-2>', actor.double_middle_click) self._canvas.bind('<Triple-Button-2>', actor.double_middle_click) self._canvas.bind('<Button-3>', actor.single_right_click) self._canvas.bind('<Double-Button-3>', actor.double_right_click) self._canvas.bind('<Triple-Button-3>', actor.double_right_click) self._canvas.bind('<Shift-Button-1>', actor.shift_click) self._canvas.bind('<Motion>', actor.mouse_moved) #self._canvas.bind('<ButtonPress-1>', actor.left_mouse_pressed) self._canvas.bind('<ButtonRelease-1>', actor.left_mouse_released) self._canvas.bind('<B1-Motion>', actor.left_dragged) self.bind('<FocusIn>', actor.focus_in) self.bind('<FocusOut>', actor.focus_out) self._parent.bind('<Key>', actor.key_press) self._parent.bind('<KeyRelease>', actor.key_release) self._currentActor = actor self._currentActor.on_activate() def set_surface(self, surface_bundle): r""" Set the current surface to the one given by surface_bundle """ i = self.add_surface(surface_bundle) if surface_bundle != self._surface: self._canvas.delete("all") self._surface = surface_bundle self._surface_menu.invoke(i + 1) if i >= 0: self.set_text("Switched to `" + self._surface.get_name() + "'.") self._parent.title(self._surface.get_name()) self._reset_menus() # stop the actor (was a bug). self.set_actor(None) if isinstance(self._surface, EditorRenderer): self._surface.initial_render() else: self.set_text("No surface selected.") self._parent.title("FlatSurf Editor") self._reset_menus() self.set_actor(None) return i def surface_renamed(self): if self._surface is not None: self._parent.title(self._surface.get_name()) self._reset_surface_menu()
class ConsumablePinball(Domain): """ RL NOTES: Pinball Domain has a ballmodel and environment object. Statespace augmentation will be only done in the _DOMAIN_. The goal of this domain is to maneuver a small ball on a plate into a hole. The plate may contain obstacles which should be avoided. **STATE:** The state is given by a 4-dimensional vector, consisting of position and velocity of the ball. **ACTIONS:** There are 5 actions, standing for slanting the plat in x or y direction or a horizontal position of the plate. **REWARD:** Slanting the plate costs -4 reward in addition to -1 reward for each timestep. When the ball reaches the hole, the agent receives 10000 units of reward. **REFERENCE:** .. seealso:: G.D. Konidaris and A.G. Barto: *Skill Discovery in Continuous Reinforcement Learning Domains using Skill Chaining.* Advances in Neural Information Processing Systems 22, pages 1015-1023, December 2009. """ #: default location of config files shipped with rlpy default_config_dir = os.path.join(__rlpy_location__, "Domains", "PinballConfigs") # seems to only have one reasonable goalfn def __init__(self, goalArray, noise=.1, episodeCap=1000, configuration=os.path.join(default_config_dir, "pinball_simple_single.cfg"), goalfn=None, rewardFunction=None, encodingFunction=allMarkovEncoding): """ configuration: location of the configuration file episodeCap: maximum length of an episode noise: with probability noise, a uniformly random action is executed """ self.NOISE = noise self.configuration = configuration self.screen = None self.episodeCap = episodeCap self.actions_num = 5 self.actions = [ PinballModel.ACC_X, PinballModel.DEC_Y, PinballModel.DEC_X, PinballModel.ACC_Y, PinballModel.ACC_NONE ] self.statespace_limits = np.array([[0.0, 1.0], [0.0, 1.0], [-2.0, 2.0], [-2.0, 2.0]]) self.goalArray0 = np.array(goalArray) self.prev_states = [] # TODO fix initial state # statespace augmentation self.encodingFunction = encodingFunction encodingLimits = [] for i in range(0, len(self.encodingFunction(self.prev_states))): encodingLimits.append([0, 1]) self.statespace_limits = np.vstack( (self.statespace_limits, encodingLimits)) self.state_space_dims = len(self.statespace_limits) self.continuous_dims = np.arange(self.state_space_dims) self.DimNames = [ "Dim: " + str(k) for k in range(0, 2 + len(self.encodingFunction(self.prev_states))) ] self.rewardFunction = rewardFunction super(ConsumablePinball, self).__init__() self.environment = PinballModel(self.configuration, goalArray, goalfn=goalfn, random_state=self.random_state) def showDomain(self, a): if self.screen is None: master = Tk() master.title('RLPY Pinball') self.screen = Canvas(master, width=500.0, height=500.0) self.screen.configure(background='LightGray') self.screen.pack() self.environment_view = PinballView(self.screen, 500.0, 500.0, self.environment) self.environment_view.blit() self.screen.pack() self.screen.update() def step(self, a): s = self.state[:4] [ self.environment.ball.position[0], self.environment.ball.position[1], self.environment.ball.xdot, self.environment.ball.ydot ] = s if self.random_state.random_sample() < self.NOISE: # Random Move a = self.random_state.choice(self.possibleActions()) reward = self.environment.take_action(a) self.environment._check_bounds() state = np.array(self.environment.get_state()) self.prev_states.append(state[:4]) state = self.augment_state(state) self.state = state terminal = self.isTerminal() if not terminal and self.rewardFunction: sr = self.environment.STEP_PENALTY gr = self.environment.END_EPISODE reward = reward + self.rewardFunction(self.prev_states, self.goalArray(), sr, gr) return reward, state, terminal, self.possibleActions() def s0(self): #TODO reset this initial state; move logic into PinballModel self.environment.ball.position[0], self.environment.ball.position[ 1] = self.environment.start_pos self.environment.ball.xdot, self.environment.ball.ydot = 0.0, 0.0 self.state = np.array([ self.environment.ball.position[0], self.environment.ball.position[1], self.environment.ball.xdot, self.environment.ball.ydot ]) self.prev_states = [] self.state = self.augment_state(self.state) self.environment.goalArray = np.array(self.goalArray0) return self.state, self.isTerminal(), self.possibleActions() def possibleActions(self, s=0): return np.array(self.actions) def isTerminal(self): return self.environment.episode_ended() or len( self.prev_states) == self.episodeCap def augment_state(self, state): return np.concatenate((state, self.encodingFunction(self.prev_states))) def goalArray(self): return self.environment.goalArray
class Wall(object): MIN_RED = MIN_GREEN = MIN_BLUE = 0x0 MAX_RED = MAX_GREEN = MAX_BLUE = 0xFF PIXEL_WIDTH = 50 def __init__(self, width, height): self.width = width self.height = height self._tk_init() self.pixels = [(0, 0, 0) for i in range(self.width * self.height)] def _tk_init(self): self.root = Tk() self.root.title("ColorWall %d x %d" % (self.width, self.height)) self.root.resizable(0, 0) self.frame = Frame(self.root, bd=5, relief=SUNKEN) self.frame.pack() self.canvas = Canvas(self.frame, width=self.PIXEL_WIDTH * self.width, height=self.PIXEL_WIDTH * self.height, bd=0, highlightthickness=0) self.canvas.pack() self.root.update() def set_pixel(self, x, y, hsv): self.pixels[self.width * y + x] = hsv def get_pixel(self, x, y): return self.pixels[self.width * y + x] def draw(self): self.canvas.delete(ALL) for x in range(len(self.pixels)): x_0 = (x % self.width) * self.PIXEL_WIDTH y_0 = (x / self.width) * self.PIXEL_WIDTH x_1 = x_0 + self.PIXEL_WIDTH y_1 = y_0 + self.PIXEL_WIDTH hue = "#%02x%02x%02x" % self._get_rgb(self.pixels[x]) self.canvas.create_rectangle(x_0, y_0, x_1, y_1, fill=hue) self.canvas.update() def clear(self): for i in range(self.width * self.height): self.pixels[i] = (0, 0, 0) def _hsv_to_rgb(self, hsv): rgb = colorsys.hsv_to_rgb(*hsv) red = self.MAX_RED * rgb[0] green = self.MAX_GREEN * rgb[1] blue = self.MAX_BLUE * rgb[2] return (red, green, blue) def _get_rgb(self, hsv): red, green, blue = self._hsv_to_rgb(hsv) red = int(float(red) / (self.MAX_RED - self.MIN_RED) * 0xFF) green = int(float(green) / (self.MAX_GREEN - self.MIN_GREEN) * 0xFF) blue = int(float(blue) / (self.MAX_BLUE - self.MIN_BLUE) * 0xFF) return (red, green, blue)