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?

edited January 2015 in Questions Posts: 2,011

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

Comments

  • IgnatzIgnatz 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).

  • dave1707dave1707 Mod
    Posts: 6,486

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

  • Posts: 2,011

    @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

Sign In or Register to comment.