• Advertisement
Sign in to follow this  

Rotating a ship

This topic is 2396 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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:

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


And this is the turning 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


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
Advertisement
I'll continue on my line of advocating unit-length complex numbers instead of angles. In C++:
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;
}


And here's a complete program that uses that function:
#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';
}
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement