For about a week or two now I am trying to get the curves right. That is, the path the ship takes when it is moving to the next hex. At the moment I have a version that works quite well when there are no obstacles in the hex. I just wanted to write a few words about the approach, so that anyone who need to do something similar can learn from my mistakes.
So, let's start with the basic situation:
We have a ship, that is moving in a direction, and a target point, which is where we want the ship to go and a desired orientation at the target point. Moving is simply calculated by adding the current speed to the current location, multiplied by the time elapsed since the last movement. We can change the speed and the rotation of the ship, but we must use the proper formulas for acceleration and turning. Also, the ship can't turn around while it is stationary. For speed, I started with a simple approach: try to maximize the speed when we can freely move, and start deceleration as late as possible. This is a simple strategy, but it good enough.
For turning the ship, my first, kind of native approach was the following: let's find the vector pointing towards the closest point on the line determined by the goal parameters. Take that vector and add it to the target point, and use this virtual point as the moving target. That way the ship will move toward the actual target on a nice curve, illustrated below.
This is actually a fairly good solution, almost good enough to be the final solution. Except for one thing: At the beginning, the ship will start turning almost at once, instead of acceleration. The screenshot below captured one such attempt. A short explanation: The green spots are marking the currently selected virtual target, and the grey lines show the current direction and speed of the ship.
The ship starts at the closest point of the grey lines, and that scalpel shaped ending shows that it started turning instead of acceleration. At this point I tried several different simple ways to fix it, but I realized fairly soon that I will need to change my approach.
I decided to introduce a mixed strategy: While we are a bit further away from the line, we will approach the line itself. When we are closer than a set limit, we change to the previously described behaviour, and when we are really close, we will use the target point as a target, so that we prevent the ship moving to and back around the lines. I also introduced a hysteresis effect, so that the behaviour won't oscillate between two of these states if we are close to the limit distance. Simple illustration below:
This, again, was fairly close to what I wanted. Except for the following setup:
When the ship is not looking "towards" the target, it will follow the red curve. As a fix, I introduced a piece of code that determined whether the closest point or the current movement intersection point is closer to the target, and used that vector to approach the line, before it swapped to the virtual target chasing behaviour, as shown with the green curve.
At this point, we covered about half of the issues I solved along the way. But we are not there yet..
The situation above shows why I needed to add a checking whether the given vector is behind the target point. If not, then the ship will have a very interesting and long way around the target.
I will not show every issue I faced, just list some of them here: The target can be behind the ship, or inside the ships turning curve, or we have an obstacle in between us an the target that we shouldn't get too close to.
Please find a few funny screenshots which I take while I was experimenting with this: