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, 2014 at 22:23
  • \$\begingroup\$ Certainly, let me make some edits. \$\endgroup\$ Apr 21, 2014 at 22:31
  • \$\begingroup\$ There I made some edits. Let me know if you need more \$\endgroup\$ Apr 21, 2014 at 22:47

1 Answer 1

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\$ Apr 22, 2014 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\$ Apr 22, 2014 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\$ Apr 22, 2014 at 12:51
  • \$\begingroup\$ Thanks, I'll bet the problem is in the function input, I'll check that out. \$\endgroup\$ Apr 22, 2014 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\$ Apr 22, 2014 at 22:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .