Is it possible to rotate a physics.queryAABB bounding box?

Is it possible to rotate a physics.queryAABB bounding box? i.e. To check a rectangle that is rotated at an angle. My initial tests seem to show that it isn’t. The query isn’t affected by rotate() - and I guess we shouldn’t expect it to be, as rotate() only affects drawing operations. But is there any other work-around, or is AABB only good for areas perpendicular to the screen axis?

One option is to set a physics body as a sensor, but AABB should be faster, right? Am I missing something?

It’s for a fan object in a game. If other bodies pass in front of the path of the fan, they get blown away

@yojimbo2000 - It looks as though this function doesn’t work with a rotated box.

However, you might be able to do this another way.

If you treat your fan rectangle as being a very fat line, you could use this thread

http://codea.io/talk/discussion/5931/distance-from-line-segment#Item_21

to calculate the distance from any object to your fan. It is then a simple matter to calculate whether they overlap at all (in fact, you could pre-calculate the minimum separation distance for each object, so that you just do a lookup to see if there is an overlap).

@yojimbo2000 Here’s some code I have, maybe you could use something like this.


displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
    -- non moving polygon
    verts1={vec2(500,100),vec2(800,400),vec2(300,600),
            vec2(100,400)}
    
    -- moving polygon or point
    verts2={vec2(700,200),vec2(720,260),vec2(750,260),vec2(800,230)}    -- polygon
    -- verts2={vec2(700,200)}  -- point
    
    tx=0
    ty=0  
end

function draw()
    background(40, 40, 50)
    stroke(255,0,0)
    strokeWidth(4)
    fill(255,0,0)
    text("fan area",400,400)
    
    local j=#verts1    -- draw 1st polygon at a fixed location
    for z=1,#verts1 do
        line(verts1[z].x,verts1[z].y,verts1[j].x,verts1[j].y)
        j=z
    end
    
    stroke(255)
    local j=#verts2    -- draw 2nd polygon moving with touch x,y
    for z=1,#verts2 do
        line(verts2[z].x+tx,verts2[z].y+ty,verts2[j].x+tx,verts2[j].y+ty)
        j=z
    end
    
    check2()    -- check if polygons are colliding
    
    fill(255)
    text(str,WIDTH/2,HEIGHT/2)  
    text("drag you finger around to move the smaller object",WIDTH/2,HEIGHT-100)
end

function check2()    -- calculate x,y points for collision
    local j=#verts2
    if j==1 then
        str=""
        if check(tx+verts2[j].x,ty+verts2[j].y) then
            str="collision"
        end
        return
    end
    for z=1,#verts2 do
        local m=(verts2[j].y-verts2[z].y)/(verts2[j].x-verts2[z].x)
        local b=verts2[z].y-m*verts2[z].x
        local dir=1
        if verts2[j].x>verts2[z].x then
            dir=-1
        end
        str=""
        for x=verts2[j].x,verts2[z].x,dir do
            local y=m*x+b
            if check(tx+x,ty+y) then
                str="collision"
                return
            end
        end
        j=z
    end
end  
        
function check(px,py)    -- check if points px,py are within polygon
    local j=#verts1
    local c=-1
    for i=1,#verts1 do
        local a1=false
        if verts1[i].y>py then
            a1=true
        end
        local a2=false
        if verts1[j].y>py then
            a2=true
        end
        local b1=verts1[j].x-verts1[i].x
        local b2=py-verts1[i].y
        local b3=(verts1[j].y-verts1[i].y)
        if a1~=a2 and px<(b1*b2/b3+verts1[i].x) then
            c = c *-1
        end
        j=i
    end 
    if c==1 then
        return true
    else
        return false
    end
end

function touched(t)    -- used just to move 2nd polygon around
    tx=tx+t.deltaX
    ty=ty+t.deltaY
end

@yojimbo2000 There’s not much use for a rotatable AABB function outside of using the actual physics engine. It’s faster to use a method along the lines of creating a square polygon body and using body:testPoint(p) depending on how you use it.

@Luatee yeah, I’ve been experimenting with a polygon body (with type set to sensor). One slight annoyance is that the collide function only runs on BEGAN and ENDED events, there’s no MOVING or other form of continuous collision state (to keep the number of collision events down I suppose). This means that for every class of object in the game I also need to add bits of helper code, namely a switch set to on after BEGAN and off after ENDED, and applyForce if it is on. I suppose to prevent code repetition I should make (or should have made) every movable object in the game inherit the properties of a master “dynamic object” class. (I didn’t know about class inheritance when I started the project 2 months ago…)

That’s partly why an AABB call in the draw loop is appealing for this type of collision event, where it’s a state that I’m interested in (of being in the path of the fan).

I’m tempted to redesign my levels to only have horizontal and vertical fans (no diagonal ones), just for the sake of some simplicity…

I will explore the other options that people have posted above though first