Sign in to follow this  
Canning

Rotating a ship

Recommended Posts

I have a ship, and am wanting to rotate it to a destination angle.

When I want to start turning, this is the code I run:

[code] Ship.DestAngle = System.Math.Atan2(Ship.Target.y - Ship.msngY, Ship.Target.x - Ship.msngX) + PI / 2
Ship.turning = True[/code]

And this is the turning code:

[code] If Ship.turning = True Then

a = System.Math.Sin(Ship.msngHeading + PI)
b = System.Math.Cos(Ship.msngHeading + PI)
c = System.Math.Sin(Ship.msngFacing)
d = System.Math.Cos(Ship.msngFacing)

det = a * d - b * c

If det > 0 Then
Ship.msngFacing = Ship.msngFacing + Ship.ROTATION_RATE * PI / 180
If Ship.msngFacing > Ship.DestAngle Then
Ship.msngFacing = Ship.DestAngle
Ship.turning = False
End If
Else
Ship.msngFacing = Ship.msngFacing - Ship.ROTATION_RATE * PI / 180
If Ship.msngFacing < Ship.DestAngle Then
Ship.msngFacing = Ship.DestAngle
Ship.turning = False
End If
End If
End If[/code]

Sometimes the ship turns nicely, other times it 'jumps' to the destination angle. I think this has something to do with the sign changing. Can I have some advice please on how to fix this?

thanks

Canning

Share this post


Link to post
Share on other sites
I'll continue on my line of advocating unit-length complex numbers instead of angles. In C++:
[code]Complex rotate_partially(Complex current, Complex goal, Complex max_rotation) {
Complex rotation = goal / current;

if (std::real(rotation) < std::real(max_rotation))
rotation = std::imag(rotation) > 0 ? max_rotation : conj(max_rotation);

return current * rotation;
}
[/code]

And here's a complete program that uses that function:
[code]#include <iostream>
#include <complex>

typedef std::complex<double> Complex;

const double deg = std::atan(1.0)/45.0;

Complex rotate_partially(Complex current, Complex goal, Complex max_rotation) {
Complex rotation = goal / current;

if (std::real(rotation) < std::real(max_rotation))
rotation = std::imag(rotation) > 0 ? max_rotation : conj(max_rotation);

return current * rotation;
}

int main() {
double current_angle = 45*deg;
double goal_angle = -45*deg;

Complex current = std::polar(1.0, current_angle);
Complex goal = std::polar(1.0, goal_angle);
Complex max_rotation = std::polar(1.0, 4*deg);

for (int i=0; i<30; ++i) {
current = rotate_partially(current, goal, max_rotation);
current /= abs(current); // Enforce unit length
std::cout << arg(current)/deg << '\n';
}
}

[/code]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this