physics joint problem

I’ve been playing around with the physics.joint commands and have a problem. I can’t get the DISTANCE joint to work properly. Here is an example showing what I ran into. The rectangle is locked into a PRISMATIC joint with a point in the center of the screen and can only move right or left. The circle is KINEMATIC and able to move up, down, left, or right. The circle and rectangle are locked together with the DISTANCE joint. So as the circle moves right or left, it either pushes or pulls the rectangle with it because of the joint between them. But if the circle moves up or down, strange thing happen. What I think should happen is, as the circle moves up or down the connecting point of the rectangle should move left so it’s either directly above or below the circle as the DISTANCE joint gets stretched. When the circle moves down, the rectangle starts to move correctly to the left, but after awhile it moves right and starts to oscillate. When the circle goes up, the rectangle moves right and starts to oscillate. Press a button to make the circle move in a direction. Restart the program between key presses. @Simeon, can you look at this. Is there a problem with the joint or am I doing something wrong.

EDIT: The DISTANCE joint requires 4 parameters. I originally had it as REVOLUTE and changed it to DISTANCE without realizing I needed to add another parameter. The below code was updated and now works correctly.


displayMode(FULLSCREEN)

function setup()
    rectMode(CENTER)
    dx=0
    dy=0
    
    -- center point
    c1=physics.body(CIRCLE,0)
    c1.x=WIDTH/2
    c1.y=HEIGHT/2
    c1.type=STATIC
    
    -- moving circle
    c2=physics.body(CIRCLE,0)
    c2.x=WIDTH/2-200
    c2.y=HEIGHT/2
    c2.type=KINEMATIC

    -- rectangle
    s2=physics.body(POLYGON,vec2(0,-15),vec2(0,15),
            vec2(100,15),vec2(100,-15),vec2(0,-15))
    s2.x=WIDTH/2
    s2.y=HEIGHT/2
    
    -- joint to lock rectangle into right or left movement with c1 point
    j1=physics.joint(PRISMATIC,c1,s2,c1.position,vec2(1,0))  
    -- joint to lock moving circle c2 and rectangle s2 together
    j2=physics.joint(DISTANCE,c2,s2,c2.position,s2.position)
end

function draw()
    background(40, 40, 50)   
    noFill()
    stroke(255)
    strokeWidth(2)

    -- draw point, circle and rectangle
    ellipse(c1.x,c1.y,5)
    ellipse(c2.x,c2.y,20) 
    drawPoints(s2)
    
    -- draw connection between c2 and s2
    line(j2.bodyA.x,j2.bodyA.y,j2.bodyB.x,j2.bodyB.y)

    -- change velocity of c2
    c2.linearVelocity = vec2(dx,dy)
    
    -- draw buttons
    rect(WIDTH/2,HEIGHT-200,100,50)
    rect(WIDTH/2,200,100,50)
    rect(100,HEIGHT/2,100,50)
    rect(WIDTH-100,HEIGHT/2,100,50)
    fill(255,0,0)
    text("UP",WIDTH/2,HEIGHT-200)
    text("DOWN",WIDTH/2,200)
    text("LEFT",100,HEIGHT/2)
    text("RIGHT",WIDTH-100,HEIGHT/2)
end

function drawPoints(s)
    -- draw lines for rectangle
    for z=2,#s.points do
        line(s.x+s.points[z-1].x,s.y+s.points[z-1].y,
        s.x+s.points[z].x,s.y+s.points[z].y)
    end          
end

function touched(t)
    if t.state==BEGAN then
        dx=0
        dy=0
        -- check which button was pressed
        if t.x>WIDTH-150 and t.x<WIDTH-50 and
                t.y>HEIGHT/2-25 and t.y<HEIGHT/2+25 then
            dx=30
        end
        if t.x>50 and t.x<150 and
                t.y>HEIGHT/2-25 and t.y<HEIGHT/2+25 then
            dx=-30
        end
        if t.x>WIDTH/2-50 and t.x<WIDTH/2+50 and
                t.y>150 and t.y<250 then
            dy=-30
        end
        if t.x>WIDTH/2-50 and t.x<WIDTH/2+50 and
                t.y>HEIGHT-225 and t.y< HEIGHT-175 then
            dy=30
        end
    end
end


I’m not sure why this is happening but I have a project where a DISTANCE joint acts like a ROPE joint

Dave distance takes two anchors I think, I haven’t ran your code but I’ll double check.

Edit: it does take 2 anchors, it’s like a socket joint (elbow to wrist is a good example) you need to define to positions where it will rotate the body from (although it would make sense to default to center of mass without an anchor…)

@Luatee You’re correct. I think I started out with the REVOLUTE joint and changed it to DISTANCE later on without realizing that DISTANCE needed a fourth parameter. I modified the above program to include the fourth parameter and it now works the way it should.

@Simeon The DISTANCE joint problem was my fault. I guess I didn’t look at the documentation close enough to realize I didn’t have it set up correct.

@dave1707 Can’t tell you how much time it took me to get to know box2D in Codea, but it’s very powerful.

I’d just like to say a big thanks to @Simeon and @John for the improvements to speed in the latest version. I had 40fps before with 100 balls on the screen in my building game, but if I moved a ball that moved more balls then that became a chain reaction resulting in moving all the balls (they’re in a ditch so they all have collision with each other when box2D brings them out of ‘rest’ stage) then the FPS dropped to about 4! But now… Well now I have 100 balls in a ditch, and one huge square and I dropped that baby right in the ditch and boom 40fps to 34-36fps! I say this thank you because you have improved my games potential massively. Thanks! I can now create that piston engine I was thinking about as I can have many moving parts.