Glitches when implementing physics

Hello everyone,

The code was written in my early stages of learning Lua and Corona and so no finishing will be observed apologies for any inconvenience 

What I have done is when touch happens, the object starts revolving around a fixed point and when released it starts moving in direction where the object is released.

The code was written in my early stages of learning Lua and Corona so not finishing will be observed

local physics = require( "physics" ) physics.start() physics.setDrawMode( "hybrid" ) physics.setGravity(0,0) -- r1=rotator, r2=rotator , b1=ball bg=display.newImage("Sky.png") bg:scale(1,2) vw=display.viewableContentWidth vh=display.viewableContentHeight r1=display.newImage("rotator.png",170,100) r1:scale(0.12,0.12) r2=display.newImage("rotator.png",380,200) r2:scale(0.12,0.12) b1 = display.newImage( "ab.png",100,200) b1:scale(0.031,0.031) physics.addBody( r1,"static",{radius=9}) physics.addBody( b1,"kinematics",{radius=9} ) physics.addBody( r2,"static",{radius=9}) b1:applyForce( 0.5, 0, b1.x, b1.y ) function tap( event ) if ( "began" == event.phase ) then transition.cancel( b1 ) if(r1.x\>b1.x and r1.y\<b1.y) then d1=((r1.x-b1.x)^2+(r1.y-b1.y)^2)^0.5 ms=100 else d1=((b1.x-r1.x)^2+(b1.y-r1.y)^2)^0.5 ms=-100 end if(r2.x\>b1.x and r2.y\<b1.y) then d2=((r2.x-b1.x)^2+(r2.y-b1.y)^2)^0.5 ms=100 else d2=((b1.x-r2.x)^2+(b1.y-r2.y)^2)^0.5 ms=-100 end if(d1\<d2) then myJoint = physics.newJoint( "pivot", r1,b1, r1.x, r1.y ) myJoint.isMotorEnabled = true myJoint.motorSpeed = ms myJoint.maxMotorTorque = 10000 myJoint.lineardamping=1 else myJoint = physics.newJoint( "pivot", r2,b1,r2.x, r2.y ) myJoint.isMotorEnabled = true myJoint.motorSpeed = ms myJoint.maxMotorTorque = 10000 myJoint.lineardamping=1 end elseif("ended"==event.phase) then display.remove(myJoint) end end bg:addEventListener("touch",tap)

I have done it successfully but when initially revolving starts it give glitches.

Please see if you all intelligent brains can help me by any means.

Every advices,opinions and help is welcome.

Thanks in advance.

couple things quickly (ie, didn’t run your code, just glanced at it):

in general, your whole simulation would probably work better if you simply got rid of all the motor stuff - just add a pivot and “b1” would “spin” around “r1” or “r2”.  (unless “b1” is at a relative “angular stop” (linear velocity implies no angular velocity wrt r1/r2) – you’d want to find a way to kick-start it then i guess, perhaps that’s why the motors, but I’d then turn them off right away after using them)

you should set focus on began phase else you’re not guaranteed to get an ended phase

“kinematics” is not a body type, so might as well type “dynamic” since that’s what it’ll default to

just style:  confusing that touch event uses tap listener

Sir,  @davebollinger thanks for your reply I implemented your suggestion and the glitches have been removed but now I am facing a different issue the speed is varying depending on distances can you help me with something

local physics = require( "physics" ) physics.start() physics.setDrawMode( "hybrid" ) physics.setGravity(0,0) -- r1=rotator, r2=rotator , b1=ball bg=display.newImage("Sky.png") bg:scale(1,2) vw=display.viewableContentWidth vh=display.viewableContentHeight r1=display.newImage("rotator.png",170,100) r1:scale(0.12,0.12) r2=display.newImage("rotator.png",380,200) r2:scale(0.12,0.12) b1 = display.newImage( "ab.png",100,200) b1:scale(0.031,0.031) physics.addBody( r1,"static",{radius=9}) physics.addBody( b1,"dynamic",{radius=9} ) physics.addBody( r2,"static",{radius=9}) b1:applyForce( 1, 0, b1.x, b1.y ) function tap( event ) if ( "began" == event.phase ) then if(r1.x\>b1.x and r1.y\<b1.y) then d1=((r1.x-b1.x)^2+(r1.y-b1.y)^2)^0.5 else d1=((b1.x-r1.x)^2+(b1.y-r1.y)^2)^0.5 b1:applyForce( -2, -1, b1.x, b1.y ) end if(r2.x\>b1.x and r2.y\<b1.y) then d2=((r2.x-b1.x)^2+(r2.y-b1.y)^2)^0.5 else d2=((b1.x-r2.x)^2+(b1.y-r2.y)^2)^0.5 b1:applyForce( -2, -1, b1.x, b1.y ) end if(d1\<d2) then myJoint = physics.newJoint( "pivot", r1,b1, r1.x, r1.y ) else myJoint = physics.newJoint( "pivot", r2,b1,r2.x, r2.y ) end elseif("ended"==event.phase) then display.remove(myJoint) end end bg:addEventListener("touch",tap)

The above is the improved code after your suggestion Sir.

no time for a more-complete answer, but…  you’re unlikely to get what (it seems) you want with a pivot joint if the bodies don’t overlap.

one solution is to create an additional “swing-arm” body to connect your r and b.  make it invisible, make it a sensor, center it on your r, joint it to r with a pivot, make it (doubly) long enough to reach b while still centered on r, put a weld joint between swing-arm and b.  (downside is you may get a bit of extra slop from the extra weld)

or, use a distance joint between r and b - might serve as a replacement for a “pivot arm” if you don’t need pivot’s motor.

hth

Sir @davebollinger,

Thanks for your precious input, I have implemented your solution on a side project and it worked well, now I will implement it on my main project and will let you know about the final outcome.

I have implemented the first method of including a “pivot-arm” and motors.

What I have just not understood is regarding using a distance joint. When I used a distance joint, after some revolutions around fixed points " r " the " b " revolution speeds decrease and then it stops completing a revolution around " r ". 

local physics = require( "physics" ) physics.start() physics.setDrawMode( "hybrid" ) local myRect = display.newRect( display.contentWidth/2, 100, 50, 50 ) myRect:setFillColor( 1, 0, 0 ) local myCircle = display.newCircle( display.contentWidth/2, 200, 20 ) myCircle:setFillColor( 0, 0, 1 ) local myRect1 = display.newRect( display.contentWidth/2, 100,80, 80 ) physics.addBody( myRect, "static" ) physics.addBody( myRect1, "dynamic" ) physics.addBody( myCircle ) myCircle.isFixedRotation=true local myJoints = physics.newJoint( "pivot",myRect,myRect1,myRect.x,myRect.y ) myJoints.isMotorEnabled=true myJoints.maxMotorTorque=100000 myJoints.motorSpeed=-300 myJoint=physics.newJoint("weld",myRect1,myCircle,myRect1.x,myRect1.y)

The above is the code applied on side project now i will use a sensor rectangle to detect the b and to create a joint rather than maths.

a distance joint’s only constraint is distance, so it may alter velocity in order to accomplish that.

it sounds like you also want a “constant velocity constraint” applied.  there isn’t a built-in one, but you could enforce it manually through a frame listener, fe:

-- manual constant velocity constraint: local VELOCITY = 500 theThing.enterFrame = function(self,e) local lvx,lvy = self:getLinearVelocity() local mag = math.sqrt(lvx\*lvx+lvy\*lvy) if (mag==0.0) then self:setLinearVelocity(VELOCITY,0) -- kick-start else self:setLinearVelocity(lvx/mag\*VELOCITY, lvy/mag\*VELOCITY) -- normalize end end Runtime:addEventListener("enterFrame", theThing)

those two constraints will (necessarily) fight each other a bit, but ought to be relatively stable (or you could increase the number of velocity/position iterations if needed)

Sir @davebollinger,

Thanks for your time and such a detailed answer, I got a new approach to look over things from above methods.

In the above answer the self and theThing they both are same right? Every other thing is clear to me.

Thanks and Regards,

Swanand Thakur

replace “theThing” with your “b1” (or whatever it’s now called), leave “self” as is.

(note:  i edited my previous post to fix a use of “theThing” instead of “self” mixup - would have worked as written, but it’s cleaner now)

Sir @davebollinger,

Thank you Sir, for coming back to this, the code has got cleared.

Thanks and Regards,

Swanand Thakur

couple things quickly (ie, didn’t run your code, just glanced at it):

in general, your whole simulation would probably work better if you simply got rid of all the motor stuff - just add a pivot and “b1” would “spin” around “r1” or “r2”.  (unless “b1” is at a relative “angular stop” (linear velocity implies no angular velocity wrt r1/r2) – you’d want to find a way to kick-start it then i guess, perhaps that’s why the motors, but I’d then turn them off right away after using them)

you should set focus on began phase else you’re not guaranteed to get an ended phase

“kinematics” is not a body type, so might as well type “dynamic” since that’s what it’ll default to

just style:  confusing that touch event uses tap listener

Sir,  @davebollinger thanks for your reply I implemented your suggestion and the glitches have been removed but now I am facing a different issue the speed is varying depending on distances can you help me with something

local physics = require( "physics" ) physics.start() physics.setDrawMode( "hybrid" ) physics.setGravity(0,0) -- r1=rotator, r2=rotator , b1=ball bg=display.newImage("Sky.png") bg:scale(1,2) vw=display.viewableContentWidth vh=display.viewableContentHeight r1=display.newImage("rotator.png",170,100) r1:scale(0.12,0.12) r2=display.newImage("rotator.png",380,200) r2:scale(0.12,0.12) b1 = display.newImage( "ab.png",100,200) b1:scale(0.031,0.031) physics.addBody( r1,"static",{radius=9}) physics.addBody( b1,"dynamic",{radius=9} ) physics.addBody( r2,"static",{radius=9}) b1:applyForce( 1, 0, b1.x, b1.y ) function tap( event ) if ( "began" == event.phase ) then if(r1.x\>b1.x and r1.y\<b1.y) then d1=((r1.x-b1.x)^2+(r1.y-b1.y)^2)^0.5 else d1=((b1.x-r1.x)^2+(b1.y-r1.y)^2)^0.5 b1:applyForce( -2, -1, b1.x, b1.y ) end if(r2.x\>b1.x and r2.y\<b1.y) then d2=((r2.x-b1.x)^2+(r2.y-b1.y)^2)^0.5 else d2=((b1.x-r2.x)^2+(b1.y-r2.y)^2)^0.5 b1:applyForce( -2, -1, b1.x, b1.y ) end if(d1\<d2) then myJoint = physics.newJoint( "pivot", r1,b1, r1.x, r1.y ) else myJoint = physics.newJoint( "pivot", r2,b1,r2.x, r2.y ) end elseif("ended"==event.phase) then display.remove(myJoint) end end bg:addEventListener("touch",tap)

The above is the improved code after your suggestion Sir.

no time for a more-complete answer, but…  you’re unlikely to get what (it seems) you want with a pivot joint if the bodies don’t overlap.

one solution is to create an additional “swing-arm” body to connect your r and b.  make it invisible, make it a sensor, center it on your r, joint it to r with a pivot, make it (doubly) long enough to reach b while still centered on r, put a weld joint between swing-arm and b.  (downside is you may get a bit of extra slop from the extra weld)

or, use a distance joint between r and b - might serve as a replacement for a “pivot arm” if you don’t need pivot’s motor.

hth

Sir @davebollinger,

Thanks for your precious input, I have implemented your solution on a side project and it worked well, now I will implement it on my main project and will let you know about the final outcome.

I have implemented the first method of including a “pivot-arm” and motors.

What I have just not understood is regarding using a distance joint. When I used a distance joint, after some revolutions around fixed points " r " the " b " revolution speeds decrease and then it stops completing a revolution around " r ". 

local physics = require( "physics" ) physics.start() physics.setDrawMode( "hybrid" ) local myRect = display.newRect( display.contentWidth/2, 100, 50, 50 ) myRect:setFillColor( 1, 0, 0 ) local myCircle = display.newCircle( display.contentWidth/2, 200, 20 ) myCircle:setFillColor( 0, 0, 1 ) local myRect1 = display.newRect( display.contentWidth/2, 100,80, 80 ) physics.addBody( myRect, "static" ) physics.addBody( myRect1, "dynamic" ) physics.addBody( myCircle ) myCircle.isFixedRotation=true local myJoints = physics.newJoint( "pivot",myRect,myRect1,myRect.x,myRect.y ) myJoints.isMotorEnabled=true myJoints.maxMotorTorque=100000 myJoints.motorSpeed=-300 myJoint=physics.newJoint("weld",myRect1,myCircle,myRect1.x,myRect1.y)

The above is the code applied on side project now i will use a sensor rectangle to detect the b and to create a joint rather than maths.

a distance joint’s only constraint is distance, so it may alter velocity in order to accomplish that.

it sounds like you also want a “constant velocity constraint” applied.  there isn’t a built-in one, but you could enforce it manually through a frame listener, fe:

-- manual constant velocity constraint: local VELOCITY = 500 theThing.enterFrame = function(self,e) local lvx,lvy = self:getLinearVelocity() local mag = math.sqrt(lvx\*lvx+lvy\*lvy) if (mag==0.0) then self:setLinearVelocity(VELOCITY,0) -- kick-start else self:setLinearVelocity(lvx/mag\*VELOCITY, lvy/mag\*VELOCITY) -- normalize end end Runtime:addEventListener("enterFrame", theThing)

those two constraints will (necessarily) fight each other a bit, but ought to be relatively stable (or you could increase the number of velocity/position iterations if needed)

Sir @davebollinger,

Thanks for your time and such a detailed answer, I got a new approach to look over things from above methods.

In the above answer the self and theThing they both are same right? Every other thing is clear to me.

Thanks and Regards,

Swanand Thakur

replace “theThing” with your “b1” (or whatever it’s now called), leave “self” as is.

(note:  i edited my previous post to fix a use of “theThing” instead of “self” mixup - would have worked as written, but it’s cleaner now)

Sir @davebollinger,

Thank you Sir, for coming back to this, the code has got cleared.

Thanks and Regards,

Swanand Thakur