title: PyGame Circular Collision Issues - Circle Interior
body: <p>I'm making a puzzle game that requires the user to 'draw' circles onto a background to get a ball to the exit. They create circles by holding their mouse button, the circle grows; when it is big enough, they let go and it is 'punched' into the physical space and balls then react to it.</p>
  
  <p>I have a problem, however, that when two circles are intersecting (so a ball <em>should</em> pass through), if the intersection is not larger than the diameter of the ball the ball collides with the interior of the circle as usual.</p>
  
  <p>This may be a little hard to comprehend, so here's a link to the screencast showing the problem (You can't embed videos on Stack Overflow): <a href="http://www.youtube.com/watch?v=3dKyPzqTDhs" rel="nofollow">http://www.youtube.com/watch?v=3dKyPzqTDhs</a></p>
  
  <p>Hopefully that made my problem clear. Here is the Python / PyGame code for the <code>Ball</code> and <code>Circle</code> classes:</p>
  
  <pre><code>class Ball():
      def __init__(self, (x,y), size, colourID):
          """Setting up the new instance"""
          self.x = x
          self.y = y
          self.size = size
          self.exited = False
          self.colour = setColour(colourID)
          self.thickness = 0
          self.speed = 0.01
          self.angle = math.pi/2
  
      def display(self, surface):
          """Draw the ball"""
          # pygame.gfxdraw.aacircle(screen,cx,cy,new_dist,settings['MINIMAP_RINGS'])
          if self.exited != True:
              pygame.draw.circle(surface, self.colour, (int(self.x), int(self.y)), self.size, self.thickness)
  
      def move(self):
          """Move the ball according to angle and speed"""
          self.x += math.sin(self.angle) * self.speed
          self.y -= math.cos(self.angle) * self.speed
          (self.angle, self.speed) = module_physicsEngine.addVectors((self.angle, self.speed), gravity)
          self.speed *= drag
  </code></pre>
  
  <p>And the <code>Circle</code> class:</p>
  
  <pre><code>class Circle():
      def __init__(self, (x,y), size, colourID):
          """Set up the new instance of the Circle class"""
          self.x = x
          self.y = y
          self.size = size
          self.colour = setColour(colourID)
          self.thickness = 2
          self.angle = 0 # Needed for collision...
          self.speed = 0 # detection against balls
  
      def display(self, surface):
          """Draw the circle"""
          pygame.draw.circle(surface, self.colour, (int(self.x), int(self.y)), self.size, self.thickness)
  </code></pre>
  
  <p>Within the main loop of the game (<code>while running == True:</code> etc.), this code is used to perform actions on each ball:</p>
  
  <pre><code>for b in balls:
      b.move()
      for i, ball in enumerate(balls):
          for ball2 in balls[i+1:]:
              collideBalls(ball, ball2)
          collideCircle(b) #      &lt;---------------- This is the important line
          collideExit(b)
          b.display(screen)
  </code></pre>
  
  <p>And finally, the <code>collideCircle(b)</code> function, which is called once per ball to check for collisions with the interior of a circle, and also to check if the circles are intersecting.</p>
  
  <pre><code>def collideCircle(ball):
      """Check for collision between a ball and a circle"""
  
      hit = False
      closestDist = 0
  
      for c in circles:
          # Code cannot be replaced with physicsEngine.collideTest because it
          # is slightly differnt, testing if ball [ball] inside a circle [c]
          dx = c.x - ball.x
          dy = c.y - ball.y
          distance = math.hypot(dx, dy)
  
          if distance &lt;= c.size - ball.size:
              # If BALL inside any CIRCLE
              hit = False
              break
          else:
              # If we're outside of a circle.
              if closestDist &lt; c.size - (distance - ball.size):
                  hit = c
                  closestDist = (c.size - (distance - ball.size))
  
      if hit:
  
          module_physicsEngine.circleBounce(hit, ball)
  </code></pre>
  
  <p>Ok, so I know that this has been a bit of a long and talky question, but I think you have all the information needed. Is the solution to make the balls interact correctly something to do with the line <code>if distance &lt;= c.size - ball.size:</code>?</p>
  
  <p>Anyway, thanks in advance!</p>
  
  <p>Nathan out.</p>
  
  <p><strong>TL;DR - Watch the youtube video, and let me know why it's not working.</strong></p>