Determine angular momentum from angular velocity for SKSpriteNode
Asked Answered
A

3

6

I have an node in space (no angular dampening, no friction, no gravity) and I apply a torque to it (20 newton meters) over 1 second. It begins to spin and will continue forever. If I apply an inverse force (-20 newton meters) it comes to a complete stop.

If I don't know how much angular torque was applied initially (for instance it collided with another object), how can I determine what the inverse torque to apply would be in order to bring the object to a stop? I tried angularVelocity*mass, and this is close... but always a little shy (like I'm missing something):

-physicsBody!.angularVelocity*physicsBody!.mass

How can I determine Angular Momentum (torque) to use to remove all object rotation?

Abiogenetic answered 21/10, 2015 at 17:59 Comment(3)
I think it may have something to do with not factoring in the duration... Though I have the same problem if I use applyImpulseAbiogenetic
Wouldn't it be enough to set the friction of the node at 1(and its mass to something really heavy) when you want to stop it and then reset it to 0 when it stopped?Grodno
@Boby_Wan don't want it to effect other interactions.Abiogenetic
G
1

In my games I use active braking to manage stopping a node's motion over time. I do this in the update() function. For your requirements, I present this answer:

let X = -0.2  // This needs to be customized by your needs .. how fast you want to stop.
var need_braking_list : [SKSpriteNode] = []   // Append your spinning nodes here

override func update() {
    for (index,node) in need_braking_list {
        // We're almost stopped, so force a stop or this goes on forever.
        if node.physicsBody?.angularVelocity < 0.1 &&
               node.physicsBody?.angularVelocity > (-0.1)
        {
             node.physicsBody?.angularVelocity = 0
             need_braking_list.removeAtIndex(index)
        // Apply some braking ... screeech
        } else {
            let impulse_factor = node.physicsBody?.angularVelocity * (X)
            node.physicsBody?.applyAngularImpulse(impulse_factor)
        }
    } 
}

Hope this helps!

Glomerulus answered 7/6, 2016 at 18:28 Comment(0)
G
0

How about whenever torque is applied (like during collision detection), save the value in the nodes's .userData for future reference?

edit: Do you need to apply an opposing impulse, or can you just stop the rotation by setting angularVelocity to zero? Or potentially slowly reducing it toward zero through SKActions?

Gummous answered 22/10, 2015 at 14:39 Comment(0)
G
0

In space there is no drag, so if you apply a force to an object the object will continue accelerating for as long as the force is applied. Similarly, the force you need to apply to stop your object needs to have a certain magnitude and be applied for a specific time in order to stop your object, because if you just apply the force continuously then the object will start to go back from where it came. So, you'd need to know the force and the time during which it was applied (almost instantly) in order to create an equal force to cancel its effects. I don't think this is the right approach.

What you need to do is to determine the direction of your moving object (I'll call this the speed vector, which is determined by the object's position now and its position one frame earlier) and apply a force opposed to that vector with, say, module 1 (or bigger if you want to slow your object earlier). And keep applying that force until the speed of your object (the speed vector) is zero. If you want a smooth reduction of speed and better results, linearly decrease the module of your opposing force as time advances.

Was this what you needed?

Grodno answered 23/10, 2015 at 1:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.