Physics2D rotation question maybe solvable with joints I think (SIMPLIFIED-ER)

@dave1707 , @West this works Ok:


viewer.mode=STANDARD

function setup()
    parameter.integer("angle",-360,360,0)
    parameter.integer("speed",0,30,1)
    parameter.watch("e_angle")
    parameter.watch("e1_angle")
    parameter.watch("absDiff")
    e=physics.body(POLYGON,vec2(-80,80),vec2(-80,-80),vec2(80,-80),vec2(80,80))
    e.gravityScale = 0
    e.type=DYNAMIC 
    e.x=WIDTH/2
    e.y=200    
    e1=physics.body(POLYGON,vec2(-80,80),vec2(-80,-80),vec2(80,-80),vec2(80,80)) 
    e1.gravityScale = 0
    e1.type=DYNAMIC 
    e1.x=WIDTH/2
    e1.y=500
end

function draw()
    background(40, 40, 50)
    stroke(255)
    strokeWidth(2)
    noFill()    
    pushMatrix()
    translate(e.x,e.y)
    rotate(-angle)
    rect(-80,-80,160,160)
    ellipse(0,80,20)
    popMatrix()   
    pushMatrix()
    translate(e1.x,e1.y)
    
    --[[
    adapted from the following code
    from http://www.iforce2d.net/b2dtut/rotate-to-angle:
    float nextAngle = bodyAngle + body->GetAngularVelocity() / 60.0;
    float totalRotation = desiredAngle - nextAngle;//use angle in next time step
    body->ApplyTorque( totalRotation < 0 ? -10 : 10 );
    ]]
    
    diff = ((angle - e1.angle) % 360) 
    absDiff = math.floor(math.abs(diff))
    if absDiff > 180 then absDiff = 180 - absDiff end
    if absDiff ~= 0 then
        local nextAngle = e1.angle + (e1.angularVelocity / 3)
        local totalRotation 
        if diff > 0 then
            totalRotation = angle - nextAngle
        else
            totalRotation = nextAngle - angle
        end
        local torque = 1000
        if totalRotation < 0 then torque = torque * -1 end
        e1:applyTorque(torque*speed)      
    end
    rotate(-e1.angle)
    rect(-80,-80,160,160)
    ellipse(0,80,20)
    popMatrix()
    
    e_angle = angle
    e1_angle = e1.angle
    angularVelocity = e1.angularVelocity
end

I adapted it from the website that is mentioned in the comments in the code. It’s not perfect, but I think it avoids the situation where it rotates forever it never stops.

@UberGoober I modified my above code to this. It moves the second square in the direction of the smallest rotation.

function setup()
    parameter.integer("angle",-360,360,0)
    parameter.integer("speed",1,30)
    e=physics.body(POLYGON,vec2(-80,80),vec2(-80,-80),vec2(80,-80),vec2(80,80))
    e.type=KINEMATIC 
    e.x=WIDTH/2
    e.y=200    
    e1=physics.body(POLYGON,vec2(-80,80),vec2(-80,-80),vec2(80,-80),vec2(80,80)) 
    e1.type=KINEMATIC 
    e1.x=WIDTH/2
    e1.y=500
end

function draw()
    background(40, 40, 50)
    stroke(255)
    strokeWidth(2)
    noFill()    
    
    pushMatrix()
    translate(e.x,e.y)
    rotate(-angle)
    rect(-80,-80,160,160)
    ellipse(0,80,20)
    popMatrix()  
     
    pushMatrix()
    translate(e1.x,e1.y)
    if angle%360~=e1.angle%360 then
        vel=angle%360-e1.angle%360
        if math.abs(vel)>=180 then
            vel=vel*-1
        end
        vel=math.min(50,math.max(-50,vel))
        e1.angularVelocity=vel*speed
    else
        e1.angularVelocity=0
    end
    rotate(-e1.angle)
    rect(-80,-80,160,160)
    ellipse(0,80,20)
    popMatrix()
end

@dave1707 that’s some sweet code, I tried to figure that trick out myself and couldn’t do it.

I incorporated it into my version, which uses dynamic bodies and torque, and I think it improved it.


viewer.mode=STANDARD

function setup()
    parameter.integer("angle",-360,360,0)
    parameter.integer("speed",0,30,1)
    e=physics.body(POLYGON,vec2(-80,80),vec2(-80,-80),vec2(80,-80),vec2(80,80))
    e.gravityScale = 0
    e.type=DYNAMIC 
    e.x=WIDTH/2
    e.y=200    
    e1=physics.body(POLYGON,vec2(-80,80),vec2(-80,-80),vec2(80,-80),vec2(80,80)) 
    e1.gravityScale = 0
    e1.type=DYNAMIC 
    e1.x=WIDTH/2
    e1.y=500
end

function draw()
    background(40, 40, 50)
    stroke(255)
    strokeWidth(2)
    noFill()    
    pushMatrix()
    translate(e.x,e.y)
    rotate(-angle)
    rect(-80,-80,160,160)
    ellipse(0,80,20)
    popMatrix()   
    pushMatrix()
    translate(e1.x,e1.y)
    
    if angle % 360 ~= e1.angle % 360 then
        local nextAngle = e1.angle + (e1.angularVelocity / 3)
        diff = angle % 360 - nextAngle % 360
        if math.abs(diff) >= 180 then diff = diff * -1 end
        diff=math.min(50,math.max(-50,diff))        
        local torque = 1000
        if diff < 0 then torque = torque * -1 end
        e1:applyTorque(torque*speed)         
    end
    
    rotate(-e1.angle)
    rect(-80,-80,160,160)
    ellipse(0,80,20)
    popMatrix()
end

Of course, it’s not really my version, it’s a hybrid of your version and the code I got from that other website.

I have to admit I’m not totally sure how this hybrid version works, because it seems it does all these calculations, and the only result is it either applies 1000 or -1000 as torque.

Your version I understand, because it changes the velocity based on the calculations, but this version doesn’t seem to do much at all with the calculations, it just sometimes adds a negative sign, but still, somehow, it works.