Collision

Quick question: How do I check if a rectangle is colliding with an ellipse? I believe it’s super easy but i can’t find out…

Are you using physics.body for the rectangle and ellipse or just drawing them yourself.

@dave1707 just drawing them myself.

Then the next questions are, how accurate do you want to be and do you do any rotations of the rectangle and ellipse.

@dave1707 no the rectangle is just falling down on the ellipse, no rotations.

Here’s my attempt at it, sorry if it’s a bit confusing:

-- Square Ellipse Collision

-- Use this function to perform your initial setup
function setup()
    sq = vec2(300, 400)
    sqSize = 200
    el = vec2(600, 200)
    elSize = 100
    
    moving = 1
end

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

    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    fill(0, 255, 0)
    if math.sqrt(math.abs(el.x - (math.max(sq.x - sqSize / 2, math.min(sq.x + sqSize / 2, el.x)))) ^ 2 + math.abs(el.y - (math.max(sq.y - sqSize / 2, math.min(sq.y + sqSize / 2, el.y)))) ^ 2) <= elSize / 2 then
        fill(255, 0, 0)
    end
    rect(sq.x, sq.y, sqSize)
    ellipse(el.x, el.y, elSize)
end

function touched(touch)
    if touch.state == MOVING then
        if moving == 0 then
            sq = sq + vec2(touch.deltaX, touch.deltaY)
        elseif moving == 1 then
            el = el + vec2(touch.deltaX, touch.deltaY)
        end
    end
    
    if touch.state == ENDED or touch.state == CANCELLED then
        moving = 1 - moving
    end
end

Yeah, it’s kind of tough because the redius of the circle is always the same, but the distance from center of the rectangle to the edge changes depending on where on the edge you choose. If you can live without perfect collision, would be easier to treat both as circles or both as rectangles. Or create a physics body for both and use physics engine for collision.

@SkyTheCoder Wow, I don’t think i’m gonna use that one haha, it’s way too hard for me. Thanks for explaining though, i now get the idea.

@wildcat_JK Here’s a version for a collision between a rectangle and an ellipse. A random sized rectangle and ellipse will be created each time. The rectangle will fall and when the rectangle collides with the ellipse, the rectangle will turn red.

EDIT:If speed is an issue, the for loops can have a step value added.

displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
    rectMode(CENTER)
    createRectEllipse()
end

function draw()
    background(40, 40, 50)    
    noFill()
    stroke(255)
    strokeWidth(2)
    ellipse(xc,yc,a*2,b*2) 
    if checkCollision() then
        fill(255,0,0)
    end
    rect(rx,ry+dy,rw,rh)
    dy=dy-3
    if ry+dy<-100 then
        createRectEllipse()
    end
end

function createRectEllipse()
    dy=0
    -- create random position of the rectangle
    rx=math.random(100,WIDTH-100)
    ry=HEIGHT-100    
    -- create a random sized ellipse
    a=math.random(200,400)
    b=math.random(50,200)
    -- center of ellipse
    xc=WIDTH/2
    yc=300
    -- create a random sized rectangle
    rw=math.random(25,200)
    rh=math.random(25,200)
    -- define the 4 corners of the rectangle
    rx1=rx-rw/2
    ry1=ry-rh/2
    rx2=rx+rw/2
    ry2=ry-rh/2
    rx3=rx+rw/2
    ry3=ry+rh/2
    rx4=rx-rw/2
    ry4=ry+rh/2
end

function checkCollision()
    for z=rx1,rx2 do 
        if (z-xc)^2/a^2+(ry1+dy-yc)^2/b^2 <= 1 then 
            return true
        end
    end
    for z=rx4,rx3 do 
        if (z-xc)^2/a^2+(ry4+dy-yc)^2/b^2 <= 1 then 
            return true
        end
    end
    for z=ry2,ry3 do 
        if (rx2-xc)^2/a^2+(z+dy-yc)^2/b^2 <= 1 then 
            return true
        end
    end
    for z=ry1,ry4 do 
        if (rx1-xc)^2/a^2+(z+dy-yc)^2/b^2 <= 1 then 
            return true
        end
    end
end

@wildcat_JR Here’s a simplified version of my code. I cut the checkCollision almost in half and I don’t need the values of the 4 rectangle corners, just the lower left corner.

displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
    rectMode(CENTER)
    createRectEllipse()
end

function draw()
    background(40, 40, 50)    
    noFill()
    stroke(255)
    strokeWidth(2)
    ellipse(xc,yc,a*2,b*2) 
    if checkCollision() then
        fill(255,0,0)
    end
    rect(rx,ry+dy,rw,rh)
    dy=dy-3
    if ry+dy<-100 then
        createRectEllipse()
    end
end

function createRectEllipse()
    dy=0
    -- create random position of the rectangle
    rx=math.random(100,WIDTH-100)
    ry=HEIGHT-100    
    -- create a random sized ellipse
    a=math.random(200,400)
    b=math.random(50,200)
    -- center of ellipse
    xc=WIDTH/2
    yc=300
    -- create a random sized rectangle
    rw=math.random(25,200)
    rh=math.random(25,200)
    -- calculate the lower left corner values
    rx1=rx-rw/2
    ry1=ry-rh/2
end

function checkCollision()
    for z=rx1,rx1+rw do 
        if (z-xc)^2/a^2+(ry1+dy-yc)^2/b^2 <= 1 or 
                (z-xc)^2/a^2+(ry1+rh+dy-yc)^2/b^2 <= 1 then 
            return true
        end
    end
    for z=ry1,ry1+rh do 
        if (rx1+rw-xc)^2/a^2+(z+dy-yc)^2/b^2 <= 1 or
                (rx1-xc)^2/a^2+(z+dy-yc)^2/b^2 <= 1 then 
            return true
        end
    end
end