Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Physics Problem

edited July 2014 in Questions Posts: 145

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
Tagged:

Comments

  • dave1707dave1707 Mod
    edited July 2014 Posts: 7,522

    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
  • IgnatzIgnatz Mod
    Posts: 5,396

    @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
    
  • dave1707dave1707 Mod
    Posts: 7,522

    @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.

  • Posts: 145

    Hi,

    Thank you for responding. I will test this code.

  • Posts: 145

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

  • IgnatzIgnatz Mod
    Posts: 5,396

    @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!

Sign In or Register to comment.