Rigid body with both normal and tangental forces Shows how the tangental force causes the object to sping roll down the slope versus just a normal fforce Try it Comment out the line for the addForce for the tangental force it still works but doesn t spin slides down the slope without spinning const canvas document createElement canvas document body appendChild canvas canvas width canvas height 700 canvas style border 1px solid gray const ctx canvas getContext 2d Simulation parameters const gravity 9 81 const timeStep 1 30 60 FPS let bodies const createBody p r bodies push radius r linear position x p x y p y linearVelocity x 0 y 0 force x 0 y 0 mass 1 angular angle 0 angularVelocity 0 0 torque 0 inertia 0 5 1 r r Sphere moment of inertia I 0 5 m r 2 createBody x 320 y 50 20 createBody x 150 y 50 20 const drawBody ctx body drawSphere body position body radius body angle const integrateBody body dt Integrate linear velocity body linearVelocity x body force x body mass dt body linearVelocity y body force y body mass dt Integrate angular velocity body angularVelocity body torque body inertia dt Update position and angle body position x body linearVelocity x dt body position y body linearVelocity y dt body angle body angularVelocity dt Damping body linearVelocity x 0 995 body linearVelocity y 0 995 body angularVelocity 0 995 Clear accumulated forces and torque for the next step body force x 0 y 0 body torque 0 const applyForceBody body force worldLocation Accumulate linear force body force x force x body force y force y Calculate the torque r worldLocation sphere position const r x worldLocation x body position x y worldLocation y body position y Torque r x F cross product in 2D r_x F_y r_y F_x const torque r x force y r y force x body torque torque const groundHeight position normal for let segment of groundSegments if position x segment startX position x segment endX const slope segment endY segment startY 0 001 segment endX segment startX const groundY segment startY slope position x segment startX let d subtract x segment endX y segment endY x segment startX y segment startY let n perpendicular d n normalize n normal x n x normal y n y return groundY return 1 height information outside range var addPower 0 0 const updateAllBodies for let i 0 i 10 i for let body of bodies bodies 0 angularVelocity addPower applyForceBody body x 0 y 2 body position integrateBody body 0 1 let normal x 0 y 1 const yh groundHeight body position normal body radius const penetration yh body position y body radius if penetration 0 0 resolvePenaltyCollision body x body position x y yh normal penetration resolveImpulseCollision body x body position x y yh normal penetration The impulse magnitude along the collision normal is calculated using the formula text impulseMagnitude frac 1 text restitution times text relativeVelocityAlongNormal frac 1 text body mass frac r times n 2 text body inertia const resolveImpulseCollision body contactPoint contactNormal penetrationDepth Calculate the radial vector from the center of mass to the contact point const offsetVector x contactPoint x body position x y contactPoint y body position y Calculate the velocity at the contact point linear rotational const contactPointVelocity x body linearVelocity x body angularVelocity offsetVector y y body linearVelocity y body angularVelocity offsetVector x Calculate the relative velocity along the collision normal const relativeVelocityAlongNormal contactPointVelocity x contactNormal x contactPointVelocity y contactNormal y If separating or very small impact skip impulse resolution if relativeVelocityAlongNormal 0 0 return If there is a tangential velocity due to angular motion convert some of it into linear motion const spinToLinearFactor 0 001 Adjust this factor to control how much spin converts to linear motion const spinFeedbackImpulse x body angularVelocity offsetVector y spinToLinearFactor y body angularVelocity offsetVector x spinToLinearFactor Apply the spin feedback impulse to linear velocity body linearVelocity x spinFeedbackImpulse x body mass body linearVelocity y spinFeedbackImpulse y body mass Restitution coefficient bounciness const restitution 0 2 Calculate normal impulse magnitude const impulseMagnitude 1 restitution relativeVelocityAlongNormal 1 body mass Math pow offsetVector x contactNormal y offsetVector y contactNormal x 2 body inertia Calculate the impulse vector const normalImpulse x impulseMagnitude contactNormal x y impulseMagnitude contactNormal y Apply the normal impulse to the linear velocity body linearVelocity x normalImpulse x body mass body linearVelocity y normalImpulse y body mass Apply the normal impulse to the angular velocity body angularVelocity offsetVector x normalImpulse y offsetVector y normalImpulse x body inertia Calculate the tangential direction and relative tangential velocity at the contact point const contactTangent x contactNormal y y contactNormal x const relativeVelocityAlongTangent contactPointVelocity x contactTangent x contactPointVelocity y contactTangent y const frictionCoefficient 0 3 const maxFrictionImpulse frictionCoefficient impulseMagnitude Calculate friction impulse clamped by maxFrictionImpulse const frictionImpulseMagnitude Math max maxFrictionImpulse Math min relativeVelocityAlongTangent maxFrictionImpulse const frictionImpulse x frictionImpulseMagnitude contactTangent x y frictionImpulseMagnitude contactTangent y Apply the friction impulse to linear velocity body linearVelocity x frictionImpulse x body mass body linearVelocity y frictionImpulse y body mass Apply the friction impulse to angular velocity body angularVelocity offsetVector x frictionImpulse y offsetVector y frictionImpulse x body inertia Set Angular Velocity to Match Linear Velocity for Rolling Calculate the tangential speed due to linear velocity at the contact point const tangentialSpeed relativeVelocityAlongTangent Update angular velocity to match the tangential speed for rolling const radius Math sqrt offsetVector x offsetVector x offsetVector y offsetVector y body angularVelocity 0 5 tangentialSpeed radius Optional Position adjustment to resolve penetration body position x contactNormal x penetrationDepth 1 001 body position y contactNormal y penetrationDepth 1 001 onmousedown addPower 0 001 onmouseup addPower 0 0 const resolvePenaltyCollision body contactPoint contactNormal penetrationDepth Calculate the radial vector from the center of mass to the contact point const offsetVector x contactPoint x body position x y contactPoint y body position y Total contact point velocity is the sum of linear and angular components const contactPointVelocity x body linearVelocity x body angularVelocity offsetVector y y body linearVelocity y body angularVelocity offsetVector x if dot contactPointVelocity contactNormal 0 01 return const penaltyStiffness 10 Penalty force constant Normal force penalty force to push the sphere out const normalForce x contactNormal x penetrationDepth penaltyStiffness y contactNormal y penetrationDepth penaltyStiffness Tangential direction and friction const contactTangent perpendicular contactNormal const relativeVelocity dot body linearVelocity contactTangent Static friction threshold if relative velocity is very small stop the rotation const frictionThreshold 0 1 let tangentialForce x 1 y 0 if Math abs relativeVelocity frictionThreshold Static friction stop motion body angularVelocity 0 tangentialForce x body linearVelocity x 1 Stops motion but causes spin friction y body linearVelocity y 1 else Dynamic friction case const frictionCoefficient 1 0 const tangentialForceMagnitude relativeVelocity frictionCoefficient tangentialForce x contactTangent x tangentialForceMagnitude 0 1 y contactTangent y tangentialForceMagnitude 0 1 Add forces at the contact point applyForceBody body normalForce contactPoint Normal force at contact point applyForceBody body tangentialForce contactPoint Tangential force friction at contact point Move the sphere out of penetration depth to avoid sinking body position x contactNormal x penetrationDepth 1 01 body position y contactNormal y penetrationDepth 1 01 Ground segments const groundSegments startX 0 startY 300 endX 100 endY 250 startX 100 startY 250 endX 200 endY 300 startX 200 startY 300 endX 300 endY 200 startX 300 startY 200 endX 400 endY 250 startX 400 startY 250 endX 500 endY 300 startX 500 startY 300 endX 600 endY 280 startX 600 startY 280 endX 700 endY 200 startX 700 startY 200 endX 800 endY 250 Utility function subtract vectors function subtract v1 v2 return x v1 x v2 x y v1 y v2 y Utility function normalize vector function normalize v const length Math sqrt v x v x v y v y return x v x length y v y length Utility function dot product function dot v1 v2 return v1 x v2 x v1 y v2 y Utility function perpendicular in 2D rotate 90 degrees function perpendicular v return x v y y v x Utility function length of vector function length v return Math sqrt v x v x v y v y Drawing functions function drawSphere position radius 20 0 angle 0 0 Draw the sphere ctx beginPath ctx arc position x position y radius 0 2 Math PI ctx fillStyle blue ctx fill ctx stroke Draw the rotation marker line from center to edge based on angle const markerLength radius Length of the marker to the edge of the sphere const markerX position x markerLength Math cos angle const markerY position y markerLength Math sin angle ctx beginPath ctx moveTo position x position y ctx lineTo markerX markerY Draw the rotating line ctx strokeStyle white Color of the rotation marker ctx lineWidth 2 ctx stroke function drawBodies ctx for let body of bodies drawBody ctx body function drawGroundLines ctx ctx lineWidth 2 ctx strokeStyle black Draw ground ctx strokeStyle black for let segment of groundSegments ctx beginPath ctx moveTo segment startX segment startY ctx lineTo segment endX segment endY ctx stroke function drawContactDetails contactPoint normal tangent Draw contact point ctx beginPath ctx arc contactPoint x contactPoint y 5 0 2 Math PI ctx fillStyle red ctx fill Draw normal ctx strokeStyle green ctx beginPath ctx moveTo contactPoint x contactPoint y ctx lineTo contactPoint x normal x 50 contactPoint y normal y 50 ctx stroke Draw tangential direction ctx strokeStyle red ctx beginPath ctx moveTo contactPoint x 8 contactPoint y ctx lineTo contactPoint x 8 tangent x 50 contactPoint y tangent y 50 ctx stroke Animation loop function animate ctx clearRect 0 0 canvas width canvas height Draw everything drawGroundLines ctx drawBodies ctx Simulation updateAllBodies Loop requestAnimationFrame animate Start the animation animate
tyAlongTangent maxFrictionImpulse const frictionImpulse x frictionImpulseMagnitude contactTangent x y frictionImpulseMagnitude contactTangent y Apply the friction impulse to linear velocity body linearVelocity x frictionImpulse x body mass body linearVelocity y frictionImpulse y body mass Apply the friction impulse to angular velocity body angularVelocity offsetVector x frictionImpulse y offsetVector y frictionImpulse x body inertia Set Angular Velocity to Match Linear Velocity for Rolling Calculate the tangential speed due to linear velocity at the contact point const tangentialSpeed relativeVelocityAlongTangent Update angular velocity to match the tangential speed for rolling const radius Math sqrt offsetVector x offsetVector x offsetVector y offsetVector y body angularVelocity 0 5 tangentialSpeed radius Optional Position adjustment to resolve penetration body position x contactNormal x penetrationDepth 1 001 body position y contactNormal y penetrationDepth 1 001 onmousedown addPower 0 001 onmouseup addPower 0 0 const resolvePenaltyCollision body contactPoint contactNormal penetrationDepth Calculate the radial vector from the center of mass to the contact point const offsetVector x contactPoint x body position x y contactPoint y body position y Total contact point velocity is the sum of linear and angular components const contactPointVelocity x body linearVelocity x body angularVelocity offsetVector y y body linearVelocity y body angularVelocity offsetVector x if dot contactPointVelocity contactNormal 0 01 return const penaltyStiffness 10 Penalty force constant Normal force penalty force to push the sphere out const normalForce x contactNormal x penetrationDepth penaltyStiffness y contactNormal y penetrationDepth penaltyStiffness Tangential direction and friction const contactTangent perpendicular contactNormal const relativeVelocity dot body linearVelocity contactTangent Static friction threshold if relative velocity is very small stop the rotation const frictionThreshold 0 1 let tangentialForce x 1 y 0 if Math abs relativeVelocity frictionThreshold Static friction stop motion body angularVelocity 0 tangentialForce x body linearVelocity x 1 Stops motion but causes spin friction y body linearVelocity y 1 else Dynamic friction case const frictionCoefficient 1 0 const tangentialForceMagnitude relativeVelocity frictionCoefficient tangentialForce x contactTangent x tangentialForceMagnitude 0 1 y contactTangent y tangentialForceMagnitude 0 1 Add forces at the contact point applyForceBody body normalForce contactPoint Normal force at contact point applyForceBody body tangentialForce contactPoint Tangential force friction at contact point Move the sphere out of penetration depth to avoid sinking body position x contactNormal x penetrationDepth 1 01 body position y contactNormal y penetrationDepth 1 01 Ground segments const groundSegments startX 0 startY 300 endX 100 endY 250 startX 100 startY 250 endX 200 endY 300 startX 200 startY 300 endX 300 endY 200 startX 300 startY 200 endX 400 endY 250 startX 400 startY 250 endX 500 endY 300 startX 500 startY 300 endX 600 endY 280 startX 600 startY 280 endX 700 endY 200 startX 700 startY 200 endX 800 endY 250 Utility function subtract vectors function subtract v1 v2 return x v1 x v2 x y v1 y v2 y Utility function normalize vector function normalize v const length Math sqrt v x v x v y v y return x v x length y v y length Utility function dot product function dot v1 v2 return v1 x v2 x v1 y v2 y Utility function perpendicular in 2D rotate 90 degrees function perpendicular v return x v y y v x Utility function length of vector function length v return Math sqrt v x v x v y v y Drawing functions function drawSphere position radius 20 0 angle 0 0 Draw the sphere ctx beginPath ctx arc position x position y radius 0 2 Math PI ctx fillStyle blue ctx fill ctx stroke Draw the rotation marker line from center to edge based on angle const markerLength radius Length of the marker to the edge of the sphere const markerX position x markerLength Math cos angle const markerY position y markerLength Math sin angle ctx beginPath ctx moveTo position x position y ctx lineTo markerX markerY Draw the rotating line ctx strokeStyle white Color of the rotation marker ctx lineWidth 2 ctx stroke function drawBodies ctx for let body of bodies drawBody ctx body function drawGroundLines ctx ctx lineWidth 2 ctx strokeStyle black Draw ground ctx strokeStyle black for let segment of groundSegments ctx beginPath ctx moveTo segment startX segment startY ctx lineTo segment endX segment endY ctx stroke function drawContactDetails contactPoint normal tangent Draw contact point ctx beginPath ctx arc contactPoint x contactPoint y 5 0 2 Math PI ctx fillStyle red ctx fill Draw normal ctx strokeStyle green ctx beginPath ctx moveTo contactPoint x contactPoint y ctx lineTo contactPoint x normal x 50 contactPoint y normal y 50 ctx stroke Draw tangential direction ctx strokeStyle red ctx beginPath ctx moveTo contactPoint x 8 contactPoint y ctx lineTo contactPoint x 8 tangent x 50 contactPoint y tangent y 50 ctx stroke Animation loop function animate ctx clearRect 0 0 canvas width canvas height Draw everything drawGroundLines ctx drawBodies ctx Simulation updateAllBodies Loop requestAnimationFrame animate Start the animation animate