Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Adjust the following script to simulate the movement of a billiard ball to work

ID: 3663985 • Letter: A

Question

Adjust the following script to simulate the movement of a billiard ball to work for rectangular pool tables.

from tkinter import Tk, Canvas, Button, W, E
import random
from math import pi, sin, cos

class BilliardBall(object):
    """
    GUI to simulate billiard ball movement.
    """
    def __init__(self, wdw, dimension, increment, delay):
        """
        Determines the layout of the GUI.
        wdw : top level widget, the main window,
        dimension : determines the size of the canvas,
        increment : step size for a billiard move,
        delay : time between updates of canvas.
        """
        wdw.title('a pool table')
        self.dim = dimension # dimension of the canvas
        self.inc = increment
        self.dly = delay
        self.togo = False # state of animation
        # initial coordinates of the ball
        self.xpt = random.randint(10, self.dim-10)
        self.ypt = random.randint(10, self.dim-10)
        self.cnv = Canvas(wdw, width=self.dim,
            height=self.dim, bg='green')
        self.cnv.grid(row=0, column=0, columnspan=2)
        self.bt0 = Button(wdw, text='start',
            command=self.start)
        self.bt0.grid(row=1, column=0, sticky=W+E)
        self.bt1 = Button(wdw, text='stop',
            command=self.stop)
        self.bt1.grid(row=1, column=1, sticky=W+E)

    def map2table(self, pnt):
        """
        Keeps the ball on the pool table.
        """
        if pnt < 0:
            (quo, rest) = divmod(-pnt, self.dim)
        else:
            (quo, rest) = divmod(pnt, self.dim)
        if quo % 2 == 1:
            rest = self.dim - rest
        return rest

    def drawball(self):
        """
        Draws the ball on the pool table.
        """
        xpt = self.map2table(self.xpt)
        ypt = self.map2table(self.ypt)
        self.cnv.delete('dot')
        self.cnv.create_oval(xpt-6, ypt-6, xpt+6, ypt+6,
            width=1, outline='black', fill='red', tags='dot')

    def animate(self):
        """
        Performs the animation.
        """
        self.drawball()
        angle = random.uniform(0, 2*pi)
        vcx = cos(angle)
        vsy = sin(angle)
        while self.togo:
            (xpt, ypt) = (self.xpt, self.ypt)
            self.xpt = xpt + vcx*self.inc
            self.ypt = ypt + vsy*self.inc
            self.cnv.after(self.dly)
            self.drawball()
            self.cnv.update()

    def start(self):
        """
        Starts the animation.
        """
        self.togo = True
        self.animate()

    def stop(self):
        """
        Stops the animation.
        """
        self.togo = False

def main():
    """
    Defines the dimensions of the canvas
    and launches the main event loop.
    """
    top = Tk()
    dimension = 400 # dimension of pool table
    increment = 10 # increment for coordinates
    delay = 60      # how much sleep before update
    BilliardBall(top, dimension, increment, delay)
    top.mainloop()

if __name__ == "__main__":
    main()

Explanation / Answer

from tkinter import Tk, Canvas, Button, W, E
import random
from math import pi, sin, cos

class BilliardBall(object):
    """
    GUI to simulate billiard ball movement.
    """
    def __init__(self, wdw, dimension, increment, delay):
        """
        Determines the layout of the GUI.
        wdw : top level widget, the main window,
        dimension : determines the size of the canvas,
        increment : step size for a billiard move,
        delay : time between updates of canvas.
        """
        wdw.title('a pool table')
        self.dim = dimension # dimension of the canvas
        self.inc = increment
        self.dly = delay
        self.togo = False # state of animation
        # initial coordinates of the ball
        self.xpt = random.randint(10, self.dim-10)
        self.ypt = random.randint(10, self.dim-10)
        self.cnv = Canvas(wdw, width=self.dim,
            height=self.dim, bg='green')
        self.cnv.grid(row=0, column=0, columnspan=2)
        self.bt0 = Button(wdw, text='start',
            command=self.start)
        self.bt0.grid(row=1, column=0, sticky=W+E)
        self.bt1 = Button(wdw, text='stop',
            command=self.stop)
        self.bt1.grid(row=1, column=1, sticky=W+E)

    def map2table(self, pnt):
        """
        Keeps the ball on the pool table.
        """
        if pnt < 0:
            (quo, rest) = divmod(-pnt, self.dim)
        else:
            (quo, rest) = divmod(pnt, self.dim)
        if quo % 2 == 1:
            rest = self.dim - rest
        return rest

    def drawball(self):
        """
        Draws the ball on the pool table.
        """
        xpt = self.map2table(self.xpt)
        ypt = self.map2table(self.ypt)
        self.cnv.delete('dot')
        self.cnv.create_oval(xpt-6, ypt-6, xpt+6, ypt+6,
            width=1, outline='black', fill='red', tags='dot')

    def animate(self):
        """
        Performs the animation.
        """
        self.drawball()
        angle = random.uniform(0, 2*pi)
        vcx = cos(angle)
        vsy = sin(angle)
        while self.togo:
            (xpt, ypt) = (self.xpt, self.ypt)
            self.xpt = xpt + vcx*self.inc
            self.ypt = ypt + vsy*self.inc
            self.cnv.after(self.dly)
            self.drawball()
            self.cnv.update()

    def start(self):
        """
        Starts the animation.
        """
        self.togo = True
        self.animate()

    def stop(self):
        """
        Stops the animation.
        """
        self.togo = False

def main():
    """
    Defines the dimensions of the canvas
    and launches the main event loop.
    """
    top = Tk()
    dimension = 400 # dimension of pool table
    increment = 10 # increment for coordinates
    delay = 60      # how much sleep before update
    BilliardBall(top, dimension, increment, delay)
    top.mainloop()

if __name__ == "__main__":
    main()

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote