#### Howdy, Stranger!

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

# Phyisc balls and distance joints

Posts: 31

Hi,
I've a rather stupid question.
I create two physic bodies CIRCLE of radius R=10 and link them with a physics joint DISTANCE anchored at each ball's body.position with a distance length of 2body.radius
Then I draw these bodies as ellipse(0,0,2

However, the two circles are (just) not touching each other. Why?

Tagged:

• Posts: 31

And furthermore, what is wrong with my code (below) that it doesn't update the balls based on the parameter?
(If I use math.random() instead, the updates first work and then suddenly stop.)

• Posts: 31
``````-- My Test

function setup()

b1 = physics.body(CIRCLE,10)
b1.x = 300
b1.y = 300
b2 = physics.body(CIRCLE,50)
b2.x = 400
b2.y = 300
physics.gravity(0,0)

li = physics.joint(DISTANCE,b1,b2,b1.position,b2.position)
end

function draw()
--li.length = math.random(100,500)
print(li.length)
background(212, 211, 212, 255)
drawBody(b1)
drawBody(b2)
end

function drawBody(body)
pushStyle()
pushMatrix()

stroke(31, 75, 31, 255)
translate(body.x, body.y)
rotate(body.angle)
if ( body.shapeType == CIRCLE) then
strokeWidth(1.0)
end

popMatrix()
popStyle()
end

pushStyle()
pushMatrix()
stroke(0,0,0)
strokeWidth(2)

popMatrix()
popStyle()

end
``````
• Posts: 7,923

@Bejoscha Add this line at the end of draw to give one of the balls a little velocity. Then try the parameter slider.

``````b2.linearVelocity=vec2(0,1)
``````
• Posts: 7,923

@Bejoscha I haven't played with the physics joints for a long time. I think the purpose of the DISTANCE joint is to keep 2 objects connected at some distance. As one of the objects moves, the other will follow at the connected distance.

• Posts: 31

Yes, I wanted to use it as a spring-type connection. Essentially I want to recreate some code I once did in Processing, just to learn Luna. I could recreate my Ball and Spring classes from scratch but I thought if there is already a physics library it would be better to use that.
Your code line did fix the parameter. However, does this mean the distance link acts only if one of the bodies is moving? It seems so. (Is it event triggered?)

The other issue - the “not quite touching” drawing is also annoying. Is it a rounding issue? Or am I missing something?

• Posts: 31

Ha! My own comment make me remember that I ‘be seen some body parameter that might be related. And indeed, setting `sleepingAllowed = false` Does the trick.

• Posts: 31

Remains the drawing issue... Any comment here?

• Posts: 7,923

@Bejoscha sleepingAllowed, I remember it well, now. Like I said, I haven't played with the physics code for quite awhile and totally forgot about that. As for the ellipse drawing, the size of the ellipse isn't quite what gets set. I don't remember if something can be set or if you just have to add 1 or 2 to the size. I would have to play with some collision code to see if collisions happen at the correct sizes or if that's off a little.

• Posts: 31

It seems the collisions with FLAT surfaces are spot-on. It is the collisions between two circles which is off. (Also in the other example code.) But that's a bit of a shame, because it means I cannot simply draw a little larger - it would look funky with flat surfaces.

Hmm, maybe I port my own code. But it feels kind of like reinventing the wheel if there is already some library - with possibly more speed optimized code than I have.

• Posts: 7,923

@Bejoscha In the below code, even though the circle sizes aren't correct, when the code runs you can't tell there is a slight difference.

``````function setup()
fill(255, 0, 0, 255)
b1 = physics.body(CIRCLE,10)
b1.position=vec2(300,400)
b1.restitution=1
b2 = physics.body(CIRCLE,50)
b2.type=STATIC
b2.position=vec2(300,100)
end

function draw()
background(212, 211, 212, 255)
drawBody(b1)
drawBody(b2)
end

function drawBody(body)
end
``````
• Posts: 31

Yes, the problem comes when they come to a rest like in the modified physics example below

• Posts: 31
``````-- Simple Physics

-- Use this function to perform your initial setup
function setup()
print("Hello Physics!")

print("Touch the screen to make boxes")
parameter.boolean("Circle")
-- Table to store our physics bodies
bodies = {}

-- Create some static boxes (not effected by gravity or collisions)
local left = makeBox(WIDTH/4, HEIGHT/2, WIDTH/3, 15, -30)
left.type = STATIC

local right = makeBox(WIDTH - WIDTH/4, HEIGHT/2, WIDTH/3, 15, 30)
right.type = STATIC

local floor = maeekeBox(WIDTH/2, 10, WIDTH, 20, 0)
floor.type = STATIC

table.insert(bodies, left)
table.insert(bodies, right)
table.insert(bodies, floor)
end

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

-- Draw all our physics bodies
for k,body in pairs(bodies) do
drawBody(body)
end
end

function touched(touch)
-- When you touch the screen, create a random box
if touch.state == BEGAN then
if Circle then
table.insert(bodies, makeCircle(touch.x, touch.y, math.random(10, 25)))
else
table.insert(bodies, makeBox(touch.x, touch.y, math.random(25, 50), math.random(25, 50), 0))
end
end
end

-- Helper function to create a box using a polygon body
function makeBox(x,y,w,h,r)
-- Points are defined in counter-clockwise order
local body = physics.body(POLYGON,vec2(-w/2, h/2),
vec2(-w/2, -h/2), vec2(w/2, -h/2), vec2(w/2, h/2))

-- Set the body's transform (position, angle)
body.x = x
body.y = y
body.angle = r

-- Make movement smoother regardless of framerate
body.interpolate = true

return body
end

function makeCircle(x,y,r)
local circle = physics.body(CIRCLE, r)
-- enable smooth motion
circle.interpolate = true
circle.x = x
circle.y = y
circle.restitution = 0.25
circle.sleepingAllowed = false
return circle
end

-- Helper function to draw a physics body
function drawBody(body)
-- Push style and transform matrix so we can restore them after
pushStyle()
pushMatrix()

strokeWidth(5)
stroke(148, 224, 135, 255)
translate(body.x, body.y)
rotate(body.angle)

-- Draw body based on shape type
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)
end

-- Restore style and transform
popMatrix()
popStyle()
end
``````
• Posts: 7,923

@Bejoscha You can do something like this. Multiply the radius by 2.15 or whatever value gives the best view. It doesn't affect the collision distance, just the display for the circle.

``````    elseif body.shapeType == CIRCLE then
strokeWidth(3.0)