CSC111 Homework 6 Solution Programs 2011

From dftwiki3
Revision as of 15:33, 7 November 2011 by Thiebaut (talk | contribs) (Created page with "--~~~~ ---- =Moving Balls= ==Program 1== <br /> <br /> <source lang="python"> </source> <br /> <br /> <br /> ==Program 2== * This version implements fully elastic collision a...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

--D. Thiebaut 15:33, 7 November 2011 (EST)


Moving Balls

Program 1







Program 2

  • This version implements fully elastic collision and respects the laws of physics, even giving the two balls a mass proportional to their radii.





[15:32:56] ~/classes/111/Submitted/2011/hw6/111a-ar$: cat hw6a.py

  1. hw6a.py
  2. 111a-ar
  3. Gavi Levy Haskell
  4. This program is an adaptation of the hw6a Demo Program.
  5. Two balls, one turquoise and one blue, bounce off the
  6. walls, each other, and a white box, and stop if they
  7. completely enter one of three black boxes, or if the
  8. program goes through 1000 steps.
  9. NOTE: The circles bounce "realistically" assuming that:
  10. The speeds never exceed those which Newton's equations
  11. work for
  12. All collisions occur along the x-y axis (not true for
  13. virtually any collision, but a fair approximation for
  14. most blows, less good for glancing blows)
  15. The masses of the circles are relative to each other,
  16. imagining them to be 2D representations of 3D figures
  17. (spheres, to be precise)
  18. The world has no friction, either between objects or
  19. with the ground
  20. The collisions are perfectly elastic


from graphics import * import random

def distance(P1, P2):

   """distance formula
   """
   return (( (P1.getX() - P2.getX())**2 +
            (P1.getY() - P2.getY())**2)**.5)

def velocity():

   """picks a random velocity
      between -5 and 5, not 0
   """
   v = 0
   while True:
       v = random.randrange(-5, 5)
       if v!=0:
           return v

def main():

   #sets up graphics window
   w   = 600
   h   = 300
   win = GraphWin("111a-ar: Ten to the Fifteenth", w, h)
   win.setBackground("black")
   #picks random radii
   r1  = random.randrange(10, 20) #radius
   r2  = random.randrange(10, 20) #radius
   #calls velocity for all four velocities of the
   #circle
   vx1 = velocity()
   vy1 = velocity()
   vx2 = velocity()
   vy2 = velocity()


   #draws circles at random locations
   c1  = Circle(Point(random.randrange(r1, w//2),
                      random.randrange(r1, h//2 - r1)),
                r1)
   c1.setWidth(0)
   c1.setFill("turquoise")
   c1.draw(win)
   c2  = Circle(Point(random.randrange(r2, w//2),
                      random.randrange(h//2, h - r2)),
                r2)
   c2.setWidth(0)
   c2.setFill("blue")
   c2.draw(win)
   #draws white box
   rw = Rectangle(Point(400, 200),
                  Point(500, 250))
   rw.setWidth(0)
   rw.setFill("white")
   rw.draw(win)
   #draws three black boxes
   boxes = [[10, 240, 80, 290],
            [250, 80, 350, 130],
            [520, 40, 570, 120]]
   
   for i in range(3):
       a, b, c, d = boxes[i]
       rb = Rectangle(Point(a,b), Point(c,d))
       rb.setOutline("white")
       rb.setWidth(2)
       rb.draw(win)


   #loop to move circles
   for i in range(1000):
       #assigns locations of circles to variables
       x1 = c1.getCenter().getX()
       y1 = c1.getCenter().getY()
       x2 = c2.getCenter().getX()
       y2 = c2.getCenter().getY()
       #variable to allow for turning off inter-
       #action between circles when in black box
       n = 0


       #traps circles in black boxes
       for j in range(3):
           a,b,c,d = boxes[j]
           
           #margin for circle 1
           xl1 = a + r1
           yu1 = b + r1
           xr1 = c - r1
           yb1 = d - r1
           #if circle is inside box
           if xl1 < x1 < xr1 and yu1 < y1 < yb1:
               vx1 = 0   #set velocities
               vy1 = 0   #to zero
               n   = 1   #indicates circle is in box
               
           #margin for circle 2
           xl2 = a + r2
           yu2 = b + r2
           xr2 = c - r2
           yb2 = d - r2
           #if circle is inside box
           if xl2 < x2 < xr2 and yu2 < y2 < yb2:
               vx2 = 0   #set velocities
               vy2 = 0   #to zero
               n   = 1   #indicates circle is in box


       #breaks if circles have been trapped
       if vx1 == 0 and vy1 == 0 and vx2 == 0 and vy2 == 0:
           break


       #lets circles bounce off white box
       #FIRST CIRCLE
       lb1 = 400 - r1 #left bound for first circle
       rb1 = 500 + r1 #right bound
       ub1 = 200 - r1 #upper bound
       bb1 = 250 + r1 #lower bound
       if lb1 < x1 < rb1 and ub1 < y1 < bb1:
           if 400 > x1:        #on left side
               vx1 = -abs(vx1) #bounce left
           if 500 < x1:        #on right side
               vx1 = abs(vx1)  #bounce right
           if 200 > y1:        #above
               vy1 = -abs(vy1) #bounce up
           if 250 < y1:        #below
               vy1 = abs(vy1)  #bounce down
               
       #SECOND CIRCLE
       lb2 = 400 - r2 #left bound for second circle
       rb2 = 500 + r2 #right bound
       ub2 = 200 - r2 #upper bound
       bb2 = 250 + r2 #lower bound
       if lb2 < x2 < rb2 and ub2 < y2 < bb2:
           if 400 > x2:        #on left side
               vx2 = -abs(vx2) #bounce left
           if 500 < x2:        #on right side
               vx2 = abs(vx2)  #bounce right
           if 200 > y2:        #above
               vy2 = -abs(vy2) #bounce up
           if 250 < y2:        #below
               vy2 = abs(vy2)  #bounce down
               
       #lets circles bounce off walls (w/o sticking)
       #circle 1
       if x1 < r1 + 5: #left side
           vx1 = abs(vx1)
       if x1 > w - r1: #right side
           vx1 = -abs(vx1)
       if y1 < r1 + 5: #top
           vy1 = abs(vy1)
       if y1 > h - r1: #bottom
           vy1 = -abs(vy1)
       #circle 2
       if x2 < r2 + 5: #left side
           vx2 = abs(vx2)
       if x2 > w - r2: #right side
           vx2 = -abs(vx2)
       if y2 < r2 + 5: #top
           vy2 = abs(vy2)
       if y2 > h - r2: #bottom
           vy2 = -abs(vy2)
       #lets circles bounce off each other
       #distance between circles
       dc = distance(c1.getCenter(), c2.getCenter())
       
       if dc <= (r1 + r2) and n == 0:
           #"masses" of circles (relative, 3D)
           m1  = r1*r1*r1
           m2  = r2*r2*r2
           
           #elastic collisions
           a1 = (vx1*(m1 - m2) + 2*m2*vx2)/(m1 + m2)
           a2 = (vx2*(m2 - m1) + 2*m1*vx1)/(m1 + m2)
           b1 = (vy1*(m1 - m2) + 2*m2*vy2)/(m1 + m2)
           b2 = (vy2*(m2 - m1) + 2*m1*vy1)/(m1 + m2)
           vx1 = a1
           vx2 = a2
           vy1 = b1
           vy2 = b2
       #moves circles
       c1.move(vx1, vy1)
       c2.move(vx2, vy2)


   text = Text(Point(w//2, h//2), "Click to quit")
   text.setFill("white")
   text.draw(win)
   win.getMouse()
   win.close()

main() [xgridmac] [15:33:04] ~/classes/111/Submitted/2011/hw6/111a-ar$: