2
\$\begingroup\$

I'm creating a simple game with space ships made of blocks that are all the same size. After having looked at this: Calculating the rotational force of a 2D sprite I have created the following code for applying a force

public void AddForceAtBlock(Vector2 force, Block block)
    {
        float mass = 1F*blocks.Count;
        this.velocity.X += force.X/mass;
        this.velocity.Y += force.Y/mass;
        Vector2 momentArm = GetGameWorldCoordinates(block) - centerOfMass;
        Vector2 parallelComponent = momentArm * (Vector2.Dot(force, momentArm) / Vector2.Dot(momentArm, momentArm));
        Vector2 angularForce = force - parallelComponent;
        Vector2 torque = angularForce * momentArm.Length();
        float momentOfInertia = 10000F*blocks.Count;
        float angularAcceleration = torque.Length()/momentOfInertia;
        this.rotationalVelocity += angularAcceleration;
    }

However this code is unable to create negative rotational acceleration so I think I did it wrong. Will someone point out to me what's wrong here?

All blocks are 50 units wide, this is the output for a 3 block ship like so: TST where T are thrusters and S is a dull forceless block. Floats are slightly imprecise as is shown in the debug log but it shouldn't matter for videogames.

Right Thruster Stop 1: force = (0, 0.951147) momentArm = (50,0) parallelComponent = (0,0) torque= (0, 47.55) angularAcceleration = 0.001585 centerOfMass = (0,0)

Left Thruster Stop 2: force = (0, 0.951147) momentArm = (-50, 0) parallelComponent = (-8.315191E-08, 7.269371E-15) torque = (4.157595E-06, 47.55735) angularAcceleration = 0.001585245 centerOfMass = (0,0)

As you can see the equation seems to be working but it fails to make the right thruster's angular acceleration negative.

\$\endgroup\$
3
  • \$\begingroup\$ Could you describe what's happening more? \$\endgroup\$ – Ben Apr 21 '14 at 22:23
  • \$\begingroup\$ Certainly, let me make some edits. \$\endgroup\$ – Jake Kiesel Apr 21 '14 at 22:31
  • \$\begingroup\$ There I made some edits. Let me know if you need more \$\endgroup\$ – Jake Kiesel Apr 21 '14 at 22:47
1
\$\begingroup\$

The path of fewest changes involves keeping your rotation sign as another variable in the function scope. You can acquire it by taking the cross product of the force and your moment arm.

After your momentArm assignment, add the following:

Vector3 rotation = Vector3.Cross(
    new Vector3(momentArm, 0),  // the Vector3(Vector2 v, float z) constructor
    new Vector3(force, 0));
float rotationDirection = Math.Sign(rotation.Z);

Then modify the last line of your method:

this.rotationalVelocity += angularAcceleration * rotationDirection;

From Wikipedia's Cross product article:

enter image description here

\$\endgroup\$
7
  • \$\begingroup\$ Thanks! I'll try this when I get home and if it works I'll mark this correct \$\endgroup\$ – Jake Kiesel Apr 22 '14 at 0:33
  • \$\begingroup\$ Seems like that did the trick but it still only works from -90 to 90 degrees. I'll play with it some more but if you have any thoughts let me know. \$\endgroup\$ – Jake Kiesel Apr 22 '14 at 5:10
  • \$\begingroup\$ Cross product is definitionally guaranteed to yield the correct direction of rotation. So, if you're having some symptom where it only works in a given range, there must be some other part of your code that is still a problem. \$\endgroup\$ – Seth Battin Apr 22 '14 at 12:51
  • \$\begingroup\$ Thanks, I'll bet the problem is in the function input, I'll check that out. \$\endgroup\$ – Jake Kiesel Apr 22 '14 at 16:37
  • \$\begingroup\$ Yeah it turns out the input force is way wonky. Thank you for directing me there, if I had enough rep I would upvote you \$\endgroup\$ – Jake Kiesel Apr 22 '14 at 22:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.