Saturday, November 17, 2018

2d - Restricting Maximum Velocity in Space


I'm making a top-down 2D space ship game in which you rotate and thrust. I'd like to impose a maximum velocity for different engine types, meaning that a certain engine can only get you going up to a certain speed.


But I'd also like the ship to be able to travel faster than that maximum velocity, say if it were sent flying by a collision with a fast-moving asteroid.


I can't naively have the engines only apply impulse if the ship is moving at less than its maximum speed -- otherwise if an asteroid sent you flying to the right, you couldn't deliberately slow down because that would involve applying an impulse to the left.


But I'm not restricted to cardinal directions. If the ship is moving too fast to the right, I don't want it to accelerate to the right, but I would like it to be able to curve upward, which might involve applying some kind of impulse at say a 15 degree angle.


My other thought was to cap the maximum velocity of the ship at the maximum velocity of the engine, but then an asteroid collision could send you flying no faster than you engine's maximum speed, and that's undesirable as well.


How might I go about designing a system that allows one to reach velocities no higher than a set maximum from their own impulse, but still be able to steer their ship at higher velocities and still actually attain those higher velocities from external means?


Edit



Let's say my maximum velocity is 50 m/s. I'm traveling at 50 m/s at a 15 degree angle, which means my x velocity is 48.3 and my y velocity is 12.9. The ship is facing at a 30 degree angle (even though it's traveling along a 15 degree vector).


When I press the thrust button, I want the ship to trend toward that 30 degree angle of travel. Which means that its current angle of travel must be altered in some fashion. Right now I do so by applying impulses. But if I apply an impulse at a 30 degree angle, the ship's velocity will exceed is maximum (a good portion of that impulse is in the same direction as we're already going).


If I don't allow that impulse to be applied, the player can't adjust their course at all while they're moving too fast. And I'm not sure how to determine which components of an impulse would change a ship's velocity's angle without increasing its length.



Answer



This problem is a bit difficult to think about because it's unphysical -- engines have a thrust which equates to acceleration and not top speed. So I think to fully answer this question, you need to remove it from a physical framework and just think of it in terms of vectors.


To be clear, I will use "speed" whenever I am talking about the overall quantity of movement of the ship, and "velocity" when there is some directionality associated with it.


You can use the directionality of velocity to your advantage here. Your engine impulse can only add velocity in the direction of impulse if the velocity in the direction of impulse is below the "engine speed" rating. You need to consider vector addition here for this to work the way you want it to. If the player impulses in a direction that is not orthogonal to direction of motion, then ONLY the amount of impulse applied in the orthogonal direction will actually increase the velocity in that direction, which means that you can change direction. To disallow the player from actually increasing speed in this situation, you need to remove velocity from the previous direction of motion so that the speed stays the same (using that you can calculate speed by adding the orthogonal velocities in quadrature).


This would allow for maneuvers at higher than engine speed given that your original speed is over engine speed due to some external mechanism, but it would not allow for acceleration past engine speed in any given direction.


EDIT


Here's an example of what I mean (using the conditions you included in your edit):



You would presumably have an acceleration value of some sort from your engine specifications. Let's just say it's 1 m/s/s for the sake of argument. Let's say you press the thrust key and hold it down for 1s at 30 degrees while your ship is travelling at 50 m/s at 15 degrees (giving vx = 48.296 m/s and vy = 12.941 m/s). You would then need to apply a 1 m/s change somehow, while still maintaining 50 m/s overall speed. So, first we must figure out what part of that 1m/s is orthogonal to your original direction and then decompose the 1 m/s along that basis.


If you draw it out (I'm not sure how to draw here) you can see that you just need to undergo a 15 degree rotation, so the direction of thrust along your current vector is 1 m/s * cos(15)=0.966 m/s and the direction orthogonal is 1 m/s * sin(15)=0.259 m/s. Here comes the "difficult" part: you now need to calculate the new direction based on these values. We already determined that the thrust along the vector will not affect anything, so we can discard the 0.966 m/s change and just apply a 0.259 m/s change in the orthogonal direction.


Since we have forced acceleration to only be orthogonal, we know that this is a "circular" change in velocity (it only changes direction and NOT speed -- exactly what you want!). In this case, the orthogonal direction is 15 + 90 = 105 degrees, so decompose that into your original x-y basis and you get that dvx = 0.259 m/s * cos(105) = -0.067 m/s and dvy = 0.259 m/s * sin(105) = 0.250 m/s. It's important that you get your angles right, because that negative sign in dvx is how the magnitude stays the same! Put this together and your resulting velocity after 1s of thrust at 1 m/s/s is vx = 48.296 m/s - 0.067 m/s = 48.229 m/s and vy = 12.941 m/s + 0.259 m/s = 13.200 m/s which gives you vt = sqrt(48.229*48.229 + 13.200*13.200) m/s = 50.003 m/s which is 50 up to the precision we calculated (3 decimal places). The computer will maintain float or double precision, but you still might want to cap it at previous speed manually or those rounding errors will accumulate.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...