Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411593 Posts in 69386 Topics- by 58444 Members - Latest Member: FightingFoxGame

May 07, 2024, 11:21:58 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Problem with my code to control a spaceship
Pages: [1]
Print
Author Topic: Problem with my code to control a spaceship  (Read 1174 times)
RCIX
Guest
« on: August 10, 2010, 09:37:50 PM »

I've written some code for a player controlling a space ship:

Code:
                Vector2 currentPositionNormal = this.Position;
                currentPositionNormal.Normalize();

                Vector2 demandedDirectionNormal = _input.LeftStickPosition;
                demandedDirectionNormal.Normalize();

                Vector2 velocity = Body.LinearVelocity;
                float currentRotationRadians = (float)Math.Atan2(velocity.Y, velocity.X);

                float demandedRotationRadians = (float)Math.Atan2(demandedDirectionNormal.Y, demandedDirectionNormal.X);
                float rotationDelta = demandedRotationRadians - currentRotationRadians;
                Vector2 targetVelocity = Vector2.Zero;
                if (rotationDelta < (Info.TurnRate * deltaTime) &&
                    rotationDelta > -(Info.TurnRate * deltaTime))
                {
                    targetVelocity = new Vector2(
                        (float)Math.Cos(demandedRotationRadians),
                        (float)Math.Sin(demandedRotationRadians));
                }
                else if (rotationDelta > Math.PI)
                {
                    targetVelocity = TurnLeft(currentRotationRadians, deltaTime);
                }
                else if (rotationDelta < -(float)Math.PI)
                {
                    targetVelocity = TurnRight(currentRotationRadians, deltaTime);
                }
                else if (rotationDelta > 0)
                {
                    targetVelocity = TurnRight(currentRotationRadians, deltaTime);
                }
                else if (rotationDelta < 0)
                {
                    targetVelocity = TurnLeft(currentRotationRadians, deltaTime);
                }
                targetVelocity *= _input.LeftStickPosition.Length();
                Body.LinearVelocity = targetVelocity;
                Body.Rotation = (float)Math.Atan2(targetVelocity.Y, targetVelocity.X) + (float)(Math.PI / 2); //done because we treat 0 radians as straight up but the engine treats 0 radians as straight right
                Body.AngularVelocity = 0;

However, in the case that the player points the control stick straight left, the ship "vibrates". I know it has something to do with the fact that the transition between negative and positive radians happens at the left, but I'm stumped as to what to patch to fix it. Anyone mind helping?
« Last Edit: August 10, 2010, 09:45:59 PM by RCIX » Logged
Sam
Level 3
***



View Profile WWW
« Reply #1 on: August 11, 2010, 03:30:57 AM »

I don't follow everything that's going on in your code, but I think you can get your rotationDelta value to be neater.  If your demandedRotation is 359 degrees (I know, it's in radians really) and currentRotation is 2 degrees then rotationDelta will come out at 357.  But of course you want the ship to turn -3 degrees rather than an almost full circle.

Code:
function shortestDifferenceBetweenRadianAngles(start:Number, end:Number):Number
{
var diff:Number = end - start;
while (diff > onePi)
{
diff -= twoPi;
}
while (diff < -onePi)
{
diff += twoPi;
}
return diff;
}

While loops are used instead of just If statements in case it's given crazy angles that need multiple corrections to get into the right range.  If you're regularly getting such angles, it'd probably be better to do that in a smart arithmetic way rather than looping.
« Last Edit: August 11, 2010, 03:34:25 AM by Salt » Logged
RCIX
Guest
« Reply #2 on: August 11, 2010, 02:26:55 PM »

I probably should have been doing that off the bat, thanks!
Logged
dcarrigg
Level 0
***

Software Neurosurgeon


View Profile WWW
« Reply #3 on: August 11, 2010, 07:17:51 PM »

I don't follow everything that's going on in your code, but I think you can get your rotationDelta value to be neater.  If your demandedRotation is 359 degrees (I know, it's in radians really) and currentRotation is 2 degrees then rotationDelta will come out at 357.  But of course you want the ship to turn -3 degrees rather than an almost full circle.

Code:
function shortestDifferenceBetweenRadianAngles(start:Number, end:Number):Number
{
var diff:Number = end - start;
while (diff > onePi)
{
diff -= twoPi;
}
while (diff < -onePi)
{
diff += twoPi;
}
return diff;
}

While loops are used instead of just If statements in case it's given crazy angles that need multiple corrections to get into the right range.  If you're regularly getting such angles, it'd probably be better to do that in a smart arithmetic way rather than looping.

Out of curiosity, is there a better/faster way to compute that? One that avoids the two while loops?
Logged

Check it out! www.retroaffect.com
___
Vice President of Marketing, Romeo Pie Software
Level 10
*


View Profile
« Reply #4 on: August 11, 2010, 10:20:54 PM »

You could avoid crazy angles by just doing angle % 360, couldn't you?
Logged
Glaiel-Gamer
Guest
« Reply #5 on: August 11, 2010, 11:16:11 PM »

shortest distance between radian angles would be much better suited treating them as vectors.


Angle between 2 vectors = acos(v1•v2/(|v1||v2|)) (don't need to divide by length if the vectors are normalized, • = dotproduct. v1•v2 = v1.x*v2.x+v1.y*v2.y)

this will get you the angle between 2 vectors.

Now to find the DIRECTIONAL angle between 2 vectors, you multiply that by the sign of the cross product, which is kinda reverse of the dot product.

sign(v1.x*v2.y-v1.y*v2.x)

acos((v1.x*v2.x+v1.y*v2.y)/(v1.length*v2.length)) * sign(v1..x*v2.y-v1.y*v2.x)

^^ that should do the trick

Logged
RCIX
Guest
« Reply #6 on: August 12, 2010, 02:02:10 AM »

(aside from the fact that the libraries i use use radians as well) ...aaaand that's why i don't do it that way Tongue
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic