Physics Problem

Hi.I recently learned about collision detection between circles. However, How can I detect a collision between the edge of the circle and a circle inside that circle? In my case I am using 2 ellipses to create a circular track. However, I want to know when a ellipse between those circles collides with one of the edges. Here is what my situation looks like:

(Note the ball can be dragged with your finger)

  supportedOrientations(LANDSCAPE_RIGHT)
  -- Use this function to perform your initial setup
  function setup()
      print("Hello World!")
      start=0
      lastx = 0
      lasty = 0
      initx = WIDTH/2+3
      inity = 690
      ellipsepositionx = 0
      ellipsepositiony = 0
  

 
     end

   -- This function gets called once every frame
  function draw()
      -- This sets a dark background color 
      background(40, 40, 50)

      -- This sets the line thickness
      strokeWidth(5)

   drawboard()
   drawcharacter()



 end

   function drawcharacter()
     if(start==1)then
       ellipse(CurrentTouch.x,CurrentTouch.y,55)
       lastx = CurrentTouch.x
       lasty = CurrentTouch.y
    
       ellipsepositionx = CurrentTouch.x
       ellipsepositiony = CurrentTouch.y
     end
     if(start==0)then
       ellipse(initx,inity,55)
       ellipsepositionx = initx
       ellipsepositiony = inity
     end
     if(start==-1)then
       ellipse(lastx,lasty,55)
       ellipsepositionx = lastx
       ellipsepositiony = lasty
     end


  end


  function touched(touch)
   if(CurrentTouch.state==BEGAN)then
       if(start==0 and CurrentTouch.x>initx-20 and CurrentTouch.x<initx+20 and CurrentTouch.y<inity+20 and    CurrentTouch.y>inity-20)then
           start=1
       end
   end

   if(CurrentTouch.state==ENDED and start==1)then
       start=-1
   end
  end


  function drawboard()
   fill(0, 196, 255, 255)
   -- Do your drawing here

   ellipse(WIDTH/2,HEIGHT/2,770)
   ellipse(WIDTH/2,HEIGHT/2,500)

   fill(30, 255, 0, 255)
   noStroke()
   smooth()
   rect(WIDTH/2,HEIGHT/2+248.5,5,130.7)
  end

Touch between the 2 circles and drag the smaller circle. If you touch the inside or outside circle a message will appear in the center of the screen. You don’t need to use physics for this.


supportedOrientations(LANDSCAPE_ANY)

function setup()
    w=WIDTH/2
    h=HEIGHT/2
end

function draw()
    background(40, 40, 50)
    noFill()
    stroke(255)
    strokeWidth(4)
    ellipse(w,h,WIDTH)
    ellipse(w,h,WIDTH-300)
    x=CurrentTouch.x
    y=CurrentTouch.y
    ellipse(x,y,60)
    checkSmall(x,y,w,h,(WIDTH-240)/2)
    checkLarge(x,y,w,h,(WIDTH-60)/2)
    fill(255,0,0)
    if small or large then
        text("outside track",w,h)
    end
end

function checkSmall(x,y,xc,yc,a)
    small=false
    if (x-xc)^2/a^2+(y-yc)^2/a^2 <= 1 then 
        small=true     
    end  
end

function checkLarge(x,y,xc,yc,a)
    large=false
    if (x-xc)^2/a^2+(y-yc)^2/a^2 >= 1 then
        large=true  
    end  
end

@dave1707 - it doesn’t matter for this simple example, but power functions can really hurt your speed when you’re using them so many time a second. Also, it is neater to use a single function when the two of them are so similar. So how about this (untested)?

    -- in draw....
    small = IsInside(x,y,w,h,(WIDTH-240)/2)
    large = not IsInside(x,y,w,h,(WIDTH-60)/2)

--using this function
function IsInside(x,y,xc,yc,a)
    local xx,yy=x-xc, y-yc
    return (xx*xx+yy*yy) / (a*a) <=1
end

@Ignatz I agree with you about the power functions and you’re right that a simple program like this won’t be affected that much. I was also thinking about combining the 2 functions, but I was just pulling code from existing programs I have and didn’t feel like changing anything.

Hi,

Thank you for responding. I will test this code.

This works great! Physics would slow down the game anyways. Thanks!

@austinmccoy - something you should look at is using the vec2 functions (they are just pairs of numbers used to store x,y positions). There are several special functions for them, such as distance.

So you can test for collisions by measuring the distance between the centre and the centre of the moving ellipse, and if it is less than (the radius of the inner circle plus its own radius) or greater than (the radius of the outer circle less its own radius), then you have collided.

I know this is pretty much what you are doing, but here is how it looks with vec2’s (untested). You can see the rest of the special vec2 functions in the vectors section of the Codea reference. The advantage is partly simplicity, also they are faster and more efficient than writing your own code.

    --using dave's code
    ellipse(w,h,WIDTH)
    ellipse(w,h,WIDTH-300)
    x=CurrentTouch.x
    y=CurrentTouch.y
    ellipse(x,y,60)
    --now the test
    vecCentre=vec2(w,h) --put this in setup if it's not going to change
    local d = vecCentre:dist(vec2(x,y))  --calculate distance between ellipse centres
    if d < (WIDTH-240)/2 or d > (WIDTH-60)/2) then
        --collision
    end

I’ve been busy lately and just got around to reading your post, but this looks interesting! I’ll definitely test out the use of vec2 functions to determine collisions between objects.

Thanks!