Source code for concepts.simulator.tk.drawing_window

#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# File   : drawing_window.py
# Author : Zhezheng Luo
# Email  : ezzluo@mit.edu
# Date   : 04/23/2021
#
# This file is part of Project Concepts.
# Distributed under terms of the MIT license.

# DrawingWindow.py - Michael Haimes, Leslie Kaelbling                      #
# Hacked by LPK to be independent of SoaR                                  #
############################################################################
#    MIT SoaR 2.0 - A Python abstraction layer for MobileRobots            #
#    Pioneer3DX robots, and a simulator to simulate their operation        #
#    in a python environment (for testing)                                 #
#                                                                          #
#    Copyright (C) 2006-2007 Michael Haimes <mhaimes@mit.edu>              #
#                                                                          #
#   This program is free software; you can redistribute it and/or modify   #
#   it under the terms of the GNU General Public License as published by   #
#   the Free Software Foundation; either version 2 of the License, or      #
#   (at your option) any later version.                                    #
#                                                                          #
#   This program is distributed in the hope that it will be useful,        #
#   but WITHOUT ANY WARRANTY; without even the implied warranty of         #
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          #
#   GNU General Public License for more details.                           #
#                                                                          #
#   You should have received a copy of the GNU General Public License along#
#   with this program; if not, write to the Free Software Foundation, Inc.,#
#   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.            #
############################################################################

__all__ = ['DrawingWindow']


from tkinter import *
import math


[docs]class Thing: pass
[docs]class DrawingWindow:
[docs] def __init__(self, windowWidth, windowHeight, xMin, xMax, yMin, yMax, title, parent=None): self.title = title if parent: self.parent = parent self.top = parent.getWindow(title) else: self.tk = Tk() self.tk.withdraw() self.top = Toplevel(self.tk) self.top.wm_title(title) self.top.protocol('WM_DELETE_WINDOW', self.top.destroy) self.windowWidth = windowWidth self.windowHeight = windowHeight self.canvas = Canvas(self.top, width=self.windowWidth, height=self.windowHeight, background="white") self.canvas.pack() # multiply an input value by this to get pixels self.xScale = windowWidth / float(xMax - xMin) self.yScale = windowHeight / float(yMax - yMin) self.drawingframe = Thing() self.drawingframe.width_px = windowWidth self.xMin = xMin self.yMin = yMin self.xMax = xMax self.yMax = yMax
[docs] def scaleX(self, x): return self.xScale * (x - self.xMin)
[docs] def scaleY(self, y): return self.windowHeight - self.yScale * (y - self.yMin)
[docs] def drawPoint(self, x, y, color="blue", radius=1): windowX = self.scaleX(x) windowY = self.scaleY(y) return self.canvas.create_rectangle( windowX - radius, windowY - radius, windowX + radius, windowY + radius, fill=color, outline=color )
[docs] def drawRobotWithNose(self, x, y, theta, color="blue", size=6): rawx = math.cos(theta) rawy = math.sin(theta) hx, hy = 0.15, 0.0 noseX = x + rawx * hx - rawy * hy noseY = y + rawy * hx + rawx * hy return self.drawRobot(x, y, noseX, noseY, color=color, size=size)
[docs] def drawRobot(self, x, y, noseX, noseY, color="blue", size=8): windowX = self.scaleX(x) windowY = self.scaleY(y) hsize = int(size) / 2 # For once, we want the int division! return ( self.canvas.create_rectangle( windowX - hsize, windowY - hsize, windowX + hsize, windowY + hsize, fill=color, outline=color ), self.canvas.create_line( windowX, windowY, self.scaleX(noseX), self.scaleY(noseY), fill=color, width=2, arrow="last" ), )
[docs] def drawText(self, x, y, label): windowX = self.scaleX(x) windowY = self.scaleY(y) # font="Arial 20",fill="#ff0000" return self.canvas.create_text(windowX, windowY, text=label)
[docs] def drawPolygon(self, verts, color="black", outline="black"): return self.canvas.create_polygon( [(self.scaleX(point.x), self.scaleY(point.y)) for point in verts], fill=color, outline=outline )
[docs] def drawRect(self, x1, y1, x2, y2, color="black"): return self.canvas.create_rectangle( self.scaleX(x1), self.scaleY(y1), self.scaleX(x2), self.scaleY(y2), fill=color )
[docs] def drawOval(self, x1, y1, x2, y2, color="black"): return self.canvas.create_oval(self.scaleX(x1), self.scaleY(y1), self.scaleX(x2), self.scaleY(y2), fill=color)
[docs] def drawLineSeg(self, x1, y1, x2, y2, color="black", width=2): return self.canvas.create_line( self.scaleX(x1), self.scaleY(y1), self.scaleX(x2), self.scaleY(y2), fill=color, width=width )
[docs] def drawUnscaledLineSeg(self, x1, y1, xproj, yproj, color="black", width=1): return self.canvas.create_line( self.scaleX(x1), self.scaleY(y1), self.scaleX(x1) + xproj, self.scaleY(y1) - yproj, fill=color, width=width )
[docs] def drawUnscaledRect(self, x1, y1, xproj, yproj, color="black"): return self.canvas.create_rectangle( self.scaleX(x1) - xproj, self.scaleY(y1) + yproj, self.scaleX(x1) + xproj, self.scaleY(y1) - yproj, fill=color, )
[docs] def drawLine(self, a, b, c, color="black"): if abs(b) < 0.001: startX = self.scaleX(-c / a) endX = self.scaleX(-c / a) startY = self.scaleY(self.yMin) endY = self.scaleY(self.yMax) else: startX = self.scaleX(self.xMin) startY = self.scaleY(-(a * self.xMin + c) / b) endX = self.scaleX(self.xMax) endY = self.scaleY(-(a * self.xMax + c) / b) return self.canvas.create_line(startX, startY, endX, endY, fill=color)
[docs] def delete(self, thing): self.canvas.delete(thing)
[docs] def clear(self): self.canvas.delete("all")
[docs] def update(self): self.canvas.update()