@dave1707 can you provide an example? When I try to make precise movements with linear velocity I always mess it up.
Here’s your code modified a little to use appleForce instead of linearVelocity. I changed the gravity so the square falls. I also made the lower square static so it doesn’t fall. To move the upper square, with your finger below mid screen, slide your finger near the left side to move it left and right side to move it right. To move it up, slide your finger anywhere above mid screen.
It looks like all that’s happening is the black background is just the max size of the square as it rotates.
viewer.mode=FULLSCREEN
function boundsOf(body)
local ll, ur = body.position, body.position
if body.shapeType == CIRCLE then
ll = body.position - vec2(body.radius, body.radius)
ur = body.position + vec2(body.radius, body.radius)
else
for _, thisPoint in ipairs(body.points) do
local worldPoint = body:getWorldPoint(thisPoint)
if worldPoint.x <= ll.x then ll.x = worldPoint.x end
if worldPoint.y <= ll.y then ll.y = worldPoint.y end
if worldPoint.x >= ur.x then ur.x = worldPoint.x end
if worldPoint.y >= ur.y then ur.y = worldPoint.y end
end
end
return ll, ur
end
function tableHas(targetTable, candidate)
if not targetTable or not candidate then return end
for key, element in pairs(targetTable) do
if element == candidate then return key end
end
end
function setup()
rectMode(CENTER)
stroke(74)
strokeWidth(2)
physics.gravity(vec2(0,-5))
s1=physics.body(CIRCLE,60)
s1.x=WIDTH/2
s1.y=HEIGHT/2+200
s1.type=STATIC
r1=physics.body(POLYGON,vec2(-40,40),vec2(-40,-40),vec2(40,-40),vec2(40,40))
r1.x=WIDTH/2
r1.y=300
r1.type=STATIC
tx,ty=WIDTH/2-300,HEIGHT-300
r2=physics.body(POLYGON,vec2(-40,40),vec2(-40,-40),vec2(40,-40),vec2(40,40))
r2.x=tx
r2.y=ty
end
function drawAABB()
local all = physics.queryAABB(vec2(0,0),vec2(WIDTH, HEIGHT))
for _, body in ipairs(all) do
local ll, ur = boundsOf(body)
if ll and ur then
local foundUpper, foundLower, foundRight, foundLeft, foundBounds
while not foundBounds do
local yUp, yDown, xLeft, xRight = 0, 0, 0, 0
--find left edge
while not foundLeft do
local bodiesToLeft = physics.queryAABB(vec2(0,0), vec2(ll.x - xLeft, HEIGHT))
if tableHas(bodiesToLeft, body) then
xLeft = xLeft + 1
else
xLeft = xLeft - 1
foundLeft = true
end
end
--find right edge
while not foundRight do
local bodiesToRight = physics.queryAABB(vec2(ur.x + xRight, 0), vec2(WIDTH, HEIGHT))
if tableHas(bodiesToRight, body) then
xRight = xRight + 1
else
xRight = xRight - 1
foundRight = true
end
end
--find top
while not foundUpper do
local bodiesAbove = physics.queryAABB(vec2(0, ur.y + yUp), vec2(WIDTH, HEIGHT))
if tableHas(bodiesAbove, body) then
yUp = yUp + 1
else
yUp = yUp - 1
foundUpper = true
end
end
--find bottom
while not foundLower do
local bodiesBelow = physics.queryAABB(vec2(0, 0), vec2(WIDTH, ll.y - yDown))
if tableHas(bodiesBelow, body) then
yDown = yDown + 1
else
yDown = yDown - 1
foundLower = true
end
end
ur.x = ur.x + xRight
ur.y = ur.y + yUp
ll.x = ll.x - xLeft
ll.y = ll.y - yDown
foundBounds = true
end
pushStyle()
rectMode(CORNER)
fill(0)
rect(ll.x, ll.y, ur.x - ll.x, ur.y - ll.y)
popStyle()
end
end
end
function draw()
background(233, 218, 80)
drawAABB()
q=physics.queryAABB(vec2(tx-40,ty-40),vec2(tx+40,ty+40))
if #q > 1 then
fill(0,255,0)
end
bodiesDraw({r1, r2, s1})
end
function touched(t)
if t.state==BEGAN or t.state==CHANGED then
if t.y<HEIGHT/2 then
if t.x>r2.position.x then
r2:applyForce(vec2(10,0))
elseif t.x<r2.position.x then
r2:applyForce(vec2(-10,0))
end
else
if t.y>r2.position.y then
r2:applyForce(vec2(0,10))
end
end
end
end
function bodiesDraw(bodies)
for i,body in ipairs(bodies) do
pushMatrix()
translate(body.x, body.y)
rotate(body.angle)
if body.type == STATIC then
stroke(255,255,255,255)
elseif body.type == DYNAMIC then
stroke(150,255,150,255)
elseif body.type == KINEMATIC then
stroke(150,150,255,255)
end
if body.shapeType == POLYGON then
strokeWidth(3.0)
local points = body.points
for j = 1,#points do
a = points[j]
b = points[(j % #points)+1]
line(a.x, a.y, b.x, b.y)
end
elseif body.shapeType == CHAIN or body.shapeType == EDGE then
strokeWidth(3.0)
local points = body.points
for j = 1,#points-1 do
a = points[j]
b = points[j+1]
line(a.x, a.y, b.x, b.y)
end
elseif body.shapeType == CIRCLE then
strokeWidth(3.0)
line(0,0,body.radius-3,0)
ellipse(0,0,body.radius*2)
end
popMatrix()
end
end
This version has the AABB drawing routine applied to all the physics lab tests.
Usually if you run the “sensors” test, and sometimes when you run the “filtering” test, once everything is still you can see an aabb region that isn’t a product of rotation and that exceeds the regular rectangular boundary of the shape (screenshot included).
I’m still not clear if you’re doubting that aabb sometimes incorporates momentum.
@UberGoober When an object is falling, I can see the bounding area increase in size above and below the object. I also see as the object rotates that the bounding area increases or decreases to keep a rotating object enclosed in it. I agree with you that it increases depending on its speed and direction. It’s just that in your one example it was increasing in size by a lot on all 4 sides even though it was barely moving. So I don’t have a problem with it.
If the aabb function is used just to determine collisions, I’ll just let the collide function determine the collision. It takes care of the collisions with any shaped object.
In the sensor example you can see the aabb area stretch out behind the box as it falls, and then once it hits the ground the aabb box (usually) stays extended beyond the boundaries of the physics body even though the physics body has stopped moving.
Honestly I don’t know what aabb boundaries are for, but they do seem to be working the way they’re supposed to, and most importantly the way they work is a lot different from the way the documentation says they work.
@UberGoober They had me confused too. I didn’t know that the bounding area stretched in front and behind a moving object. I guess that’s the fun part of Codea, trying to figure out what’s really happening and creating examples to show it.
@dave1707 clearly we have vastly different ideas of fun
Kudos to Codea for being a good tool for both of us.
@dave1707 I want to see what happens to aabb boundaries around a circle that’s rapidly moving in an elliptical orbit.
I am no good at all the sine and cosine stuff to make that kind of motion happen—but you’re a pro at that right? Would you be willing to share some basic code for describing a circular orbit?
viewer.mode=FULLSCREEN
function setup()
fill(255)
physics.gravity(vec2(0,0))
s1=physics.body(CIRCLE,50)
s1.x=0
s1.y=0
ang=0
speed=1
radius=math.min(WIDTH/2,HEIGHT/2)-50
end
function draw()
background(0)
ang=ang+1
s1.x=math.cos(math.rad(ang))*radius+WIDTH/2
s1.y=math.sin(math.rad(ang))*radius+HEIGHT/2
ellipse(s1.x,s1.y,100)
ang=ang+speed
end
@dave1707 further somewhat-interesting results.
I applied your code to a physics body, and at the same time I made a circle that uses a REVOLUTE
joint and angular velocity to achieve elliptical motion—in other words, a body that achieves circular motion just using the physics engine.
Of note:
- the aabb rect of the manually-positioned circle actually lags behind the circle as it travels, meaning the circle is often outside its own aabb rect… which is odd…
- the aabb rect of the manually-positioned circle never changes size—it’s always the size of the minimum rect needed to enclose the circle, no matter how fast it goes
- the aabb rect of the circle moved by the physics engine never lags behind—even at the same or greater speeds than the manually-positioned one, it always fully encloses the circle
- the aabb rect of the circle moved by the physics engine does change size as the circle moves, and the faster it moves the larger it gets.