0
\$\begingroup\$

Wikipedia says:

In two dimensions, angular acceleration is a number with plus or minus sign indicating orientation, but not pointing in a direction. The sign is conventionally taken to be positive if the angular speed increases in the counter-clockwise direction or decreases in the clockwise direction, and the sign is taken negative if the angular speed increases in the clockwise direction or decreases in the counter-clockwise direction.

But how do I find out if the angular speed increases in clockwise or counter-clockwise direction?

For example, I have a torque of {<-0.49497476, 0.070710614>} and a moment arm of {<-0.5, -3.5>}. This should lead to a counter-clockwise spin. On the other hand, a torque of {<0.49497476, 0.070710614>} and a moment arm of {<0.5, -3.5>} should lead to a clockwise spin. What I'm missing is probably the right combination of signs here?

My code currently looks like this:

public void Accelerate()
{
    float mass = Mass();
    foreach (Thruster thruster in thrusters)
    {
        Vec momentArm = (Vec)MomentArm(thruster);
        Vec force = MathUtil.Smooth(MathUtil.PolarToCartesian(thruster.CurrentForce, -thruster.OutputAngle));
        Vec parallelForce = momentArm * (Vec.Dot(force, momentArm) / Vec.Dot(momentArm, momentArm));
        Vec angularForce = force - parallelForce;
        Vec torque = angularForce * momentArm.Length();
        Velocity += parallelForce / mass;
        RotationVelocity += torque.Length() / mass; // I always get a positive value here
    }
    foreach (Gyroscope gyroscope in gyroscopes)
    {
        RotationVelocity += gyroscope.CurrentAcceleration;
    }
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

There are a few errors here:

  1. You do not need to separate the force into a parallel and perpendicular component. A force acting completely perpendicular to the moment arm will still impart a change to the object's linear momentum.

    Think of this using conservation of linear momentum. If your thruster ejects a particle of exhaust gas with linear momentum p, the ship's linear momentum must change by -p for the conservation law to be satisfied - no matter what direction p is pointing.

  2. Torque in 2D is just a scalar (a single float in this context), not the vector you've computed here.

    We can get this scalar by pretending our moment arm and force are 3D vectors in the xy plane (with z = 0), taking the 3D cross product there, then keeping the only non-zero component (z), which will have a positive or negative sign as desired.

    Depending on your coordinate conventions, you might need to reverse the sign here to get the rotation to occur in the desired direction.

  3. You're missing a delta time term. Force divided by mass gives you an acceleration, measured in \$\frac m {s^2}\$. To get a delta-V we can add to a velocity measured in \$\frac m s\$, we need the units to match first. So we need to multiply this by the duration of time we're accelerating for in this simulation tick.

    Even if you're using a fixed time step so this value is always the same, it's still worth defining it as a constant somewhere and multiplying it through. That way, if you ever need to change your simulation step size, you can change it in one place and most of your physics will just work, rather than needing to go re-tune every thrust value in your game.

  4. To go from a torque to an angular acceleration, you need to divide by the object's moment of inertia. This accounts for not only the object's total mass, but also how that mass is distributed around the pivot.

The corrected code would look something like this:

Vec momentArm = (Vec)MomentArm(thruster);
Vec force = MathUtil.Smooth(MathUtil.PolarToCartesian(thruster.CurrentForce, -thruster.OutputAngle));

// 2D "cross product" is just a scalar.
float torque = momentArm.x * force.y - momentArm.y * force.x;

Velocity += force * deltaTime / mass;
RotationVelocity += torque * deltaTime / momentOfInertia;
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.