Physics: rotate two bodies towards a given angle?

The physics math is puzzling me.

I have two bodies, each of which will have their own unknown rotation to start, and I want to see both of them animate rotation towards an arbitrary angle that I can set on the fly.

It seems like I’d want to use angularVelocity and torque somehow but I can’t figure it.

@UberGoober Here’s something I wrote a long time ago. I’m not sure if this is what you’re after. Adjusting the friction value in circ:init affects how the rotate/move.

viewer.mode=FULLSCREEN

function setup()
    tab={}
    table.insert(tab,circ(50,500))
    table.insert(tab,circ(WIDTH-50,600))
    e1=physics.body(EDGE,vec2(0,400),vec2(WIDTH/2,100)) 
    e2=physics.body(EDGE,vec2(WIDTH/2,100),vec2(WIDTH,150))  
end


function draw()
    background(40, 40, 50)
    for a,b in pairs(tab) do
        b:draw()
    end
end

circ = class()

function circ:init(x,y)
    self.a=physics.body(CIRCLE,50)
    self.a.x=x
    self.a.y=y
    self.a.restitution=.2
    self.a.angle=0
    self.a.friction=1
end

function circ:draw()
    pushMatrix() 
    line(0,400,WIDTH/2,100) 
    line(WIDTH/2,100,WIDTH,150)     
    translate(self.a.x,self.a.y)  
    stroke(255)
    strokeWidth(1)
    noFill()
    ellipse(0,0,100,100) 
    strokeWidth(4)
    rotate(self.a.angle)
    line(0,0,0,47)
    popMatrix()
end 

I would use a tween, set your script to have a function or reference to the body.angle

Then your tween would go from a to b for that reference or function, passing the new value.

Are tweens part of the physics engine?

If not I think tweening might be something I’d stay away from.

I’d strongly prefer to only work with one system at a time for controlling where things are drawn.

@dave1707 your demo doesn’t seem to involve enforcing any given direction, just adjusting the matrix to match the given physics boy’s rotation.

I want to actually enforce a rotation of my choice.

Something like this:


function rotateBodiesTowardsAngle(bodiesTable, angle)
      for k,v in pairs(bodiedTable) do
            —some code that applies a rotational force in the direction of the 
            —angle passed in the parameters
      end
end

How would I do that?

You are of course free to work as you please and are comfortable with.

So far for me the real power of Codea is through combining systems.
The physics system itself does not have ways to create point to point animations.
Physics bodies basically exist in their world and are influenced by gravity, impulses and each other. If you are a math wizard it might be possible to know the exact impulses to use to get the movements and rotations that’s you want.

You can also set certain body properties directly, like angle.

Tweens can be simplified into a function that turns one number into another number over a set period of time. It doesn’t have to be ‘x’ or ‘angle’, it can be any reference to a number.

So really it’s working with 2 data systems and draw is a separate singular system.

@skar, I’m not trying to create point to point animations.

Maybe the simplest way to ask this question would be “if I want to make a physics body rotate clockwise slowly, do I use applyTorque, and if so, how?”

Can anyone here help me out by telling me how that function works?

@UberGoober Is this closer to what you want.

PS. There maybe more code here than you need. I pulled this out of another project so I just left it.

viewer.mode=FULLSCREEN

function setup()
    c3=physics.body(CIRCLE,5)
    c3.x=370
    c3.y=HEIGHT/2
    c3.type=STATIC
    
    p3=physics.body(CIRCLE,50)
    p3.x=370
    p3.y=HEIGHT/2
    p3.friction=10
    p3.angularDamping=.2

    j1=physics.joint(REVOLUTE,c3,p3,c3.position,p3.position)
end

function draw()
    background(40, 40, 50)
    
    pushMatrix()
    stroke(255)
    strokeWidth(4)
    noFill()
    translate(p3.x,p3.y)
    rotate(p3.angle)
    line(0,0,0,-50)
    ellipse(0,0,100)
    popMatrix()   
    
    fill(255)
    text("swipe up or down to rotate the wheel",WIDTH/2,HEIGHT-100)
end

function touched(t)
    if t.state==MOVING then
        if t.deltaY>0 then
            p3.angularVelocity=p3.angularVelocity+5
        end
        if t.deltaY<0 then
            p3.angularVelocity=p3.angularVelocity-5
        end
        if t.state==ENDED then
            p3.angularVelocity=0
        end
    end
end

@dave1707 i think this definitely gets me headed the right direction. Thanks!

@UberGoober Here’s another version with gravity turned off. I don’t know what you’re going to do so I thought I’d show you code with and without gravity.

viewer.mode=FULLSCREEN

function setup()
    physics.gravity(0,0)
    p3=physics.body(CIRCLE,200)
    p3.x=WIDTH/2
    p3.y=HEIGHT/2
    p3.friction=1
    p3.angularDamping=.2
end

function draw()
    background(40, 40, 50)
    fill(255)
    text("swipe up or down to rotate the wheel",WIDTH/2,HEIGHT-100)  
    text(p3.angularVelocity//1,WIDTH/2,HEIGHT-150)  
    stroke(255)
    strokeWidth(4)
    noFill()
    translate(p3.x,p3.y)
    rotate(p3.angle)
    line(0,0,0,196)
    ellipse(0,0,400)
end

function touched(t)
    if t.state==CHANGED then
        if t.deltaY>0 then
            p3.angularVelocity=p3.angularVelocity+5
        end
        if t.deltaY<0 then
            p3.angularVelocity=p3.angularVelocity-5
        end
        if t.state==ENDED then
            p3.angularVelocity=0
        end
    end
end

Thanks again!