Reputation: 9251
I have a naval warfare game and I'm trying to show my user the course which his boat will take based on speed and rotation speed. Namely, I try to achieve something similar to the image below. As you can see, a ship that's able to take the red route, has a faster rotation speed than the blue one. Now, I somehow need to find a way to calculate the final movement vector based on speed, rotation speed and desired direction, but I don't know how yet. Any ideas appreciated!
Upvotes: 1
Views: 1534
Reputation: 3047
I will guess that since this is for a game and not an accurate maritime simulation, that you are simply looking for a way to create a trajectory plot.
This will best be handled with a simple iterative / parametric method, assuming a small enough time step it will make a decent curve. Keep in mind there is no simple functional form of the curve, and it must be represented by an array of points.
Given: StartX, StartY, StartHeading, EndX, EndY, MaxSpeed, MaxRotationRate
-----------------------------------------------------------------------------
MaxDisplacement = Max Speed * deltaT
MaxRotation = MaxRotationRate * deltaT
CurrentX = StartX
CurrentY = StartY
CurrentHeading = StartHeading
Trajectory = []
While [CurrentX, CurrentY] != [EndX, EndY]
% Store the Current Position by appending to results
Trajectory = [Trajectory; [CurrentX, CurrentY, CurrentHeading]]
% Get the vector form of the current heading and the straight-line path
HeadingVector = [cos(CurrentHeading),sin(CurrentHeading)]
DirectVector = [EndX - CurrentX, EndY - CurrentY]
% Some simple vector math here using dot products and cross products
RequiredRotation = arccos(dotP(HeadingVector,DirectVector)/abs((HeadingVector)*abs(DirectVector))
RotationDirection = sign(crossP(HeadingVector,DirectVector))
% Clip the rotation rate based on the maximum allowed rotation
if RequiredRotation > MaxRotation
RequiredRotation = MaxRotation
% Update the position based on the heading information
CurrentX = CurrentX + cos(RequiredRotation) * MaxDisplacement
CurrentY = CurrentY + sin(RequiredRotation) * MaxDisplacement
CurrentHeading = CurrentHeading + RequiredRotation * RotationDirection
Loop
Return Trajectory
This code has a few problems with reaching the endpoint, and I'll leave it up to you to decide how best to handle it. Two obvious problems: the ship will overshoot the endpoint as-written since the ship is always moving at max speed; and the ship may get stuck 'orbiting' a point if the endpoint is too close for it to steer into. There are multiple work-arounds for this, and it depends on how you want your game to handle this.
The other approach is to do some more hard-core geometry calculations (exact solution).
First, you need to calculate the turning radius instead of maximum turning rate. From there, given the ship's current position and heading it is possible to identify two 'turning circles' the ship could take. Choose the correct center point, C, and then calculate the correct tangency point, T, on the circle. The final path will be an arc (start, end, center) followed by a line segment.
Upvotes: 3
Reputation: 2216
This may not be the exact answer for you but I believe the formula you want is this:
Here U is the object's four-velocity, and Γ represents the coordinate system's 64 connection coefficients or Christoffel symbols. Note that the Greek subscripts take on four possible values, namely 0 for the time-axis and 1-3 for spatial coordinate axes, and that repeated indices are used to indicate summation over all values of that index.
The left hand side of this set of four equations (one each for the time-like and three spacelike values of index λ) is the object's proper-acceleration 3-vector combined with a null time component as seen from the vantage point of a reference or book-keeper coordinate system. The first term on the right hand side lists the rate at which the time-like (energy/mc) and space-like (momentum/m) components of the object's four-velocity U change, per unit time τ on traveler clocks.
As you can see, it is not QUITE linear algebra. :)
Upvotes: 1