#### Howdy, Stranger!

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

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

Mod
edited January 2015 Posts: 2,020

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

Tagged:

• Mod
edited January 2015 Posts: 5,396

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

• Mod
Posts: 8,394

@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

``````
• Posts: 1,595

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

• Mod
Posts: 2,020

@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