Vector math problem

BlitzMax Forums/BlitzMax Programming/Vector math problem

Tibit(Posted 2005) [#1]
I have implended vectors for movement and such, but I found a problem in my way of setting the speed limit. Each Tank in my game has a force which makes it accelerate. Right now I limit this force to only apply If Tank.Speed.Length() < Tank.MaxSpeed. But the tank could in an explosion be thrown much faster than it's max speed. The side effect is that when the tank goes faster than MaxSpeed because of "outside" factors, it can't break or use it's thrusters/engine force. I need a way to handle this but I'm unsure how to attack the problem. Somehow I would want to project the speed vector on the tank's thruster vector and check if the speed forward is greater than the maxspeed. Does anyone know how to solve this?


xlsior(Posted 2005) [#2]
How about instead of just keeping track of the total speed, keep track of the actual propulsion speed 'generated' by the the tank itself?

In real life a car can also go faster downhill than it can on a flat surface... When going down hill, you will hit your normal 'maximum' speed and still be able to accelerate more.


tonyg(Posted 2005) [#3]
Can MaxSpeed only be checked while accelerating while, when being 'exploded' the maxspeed is not checked?


Tibit(Posted 2005) [#4]
Yea but thats where the problem lies. There is no difference on force from the explosion or the thruster/engine or from another tank colliding. The force from the engine is generated by a vector which points in the direction of the tank. This thruster-force is added to the total force. The total force is calculated to acceleration, acc = Force/mass. Speed.Add(Acceleration) then Location.Add(Speed). And if I'm going downhill I would have a "gravity"force acting on the tank also, this would give a total speed which is higher than the tanks maxspeed. But If I don't limit the engine force by maxspeed then the tank will accelerate forever as long as the thruster is on.

Should I use one extra force,acceleration and Speed vector for the tank-movment perhaps like marc suggested? And then add that speed to the speed that comes from explosions/collisions.


QuietBloke(Posted 2005) [#5]
Rather than manually capping the top speed you could have a drag force that gets applied to the tank. The drag force is applid in the oppositie direction to the tank velocity vector and is based on the speed of the tank. At top speed this drag force is equal to your acceleration force.

Then you dont have to worry about explosions / collisions / slopes. Just apply the total force at any moment in time and let the drag force do its thing.

Did that make sense ?


Tibit(Posted 2005) [#6]
After you said that I first thougth that was the solution. But how do I calculate this dragForce?

if Speed.Length() > MaxSpeed
DragForce.SetDir(Dir+180)
DragForce.SetLength(EngineForce)'
endif

This would result in that the engine force gives no effect to the tanks movement if it goes faster than MaxSpeed.

I have to somehow calculate the speed in the direction of the tank. If tank is thrown to the side by a force which accelerates the tank to 200pix/sec to left (seen from the tank itself). If then the MaxSpeed is 50pix/sec the tank should still be able to continue forward at this speed while it is pushed to the left at 200pix/sec resulting in a mix of the two. This works until I reach the maxspeed, whereas the tank just get's pushed away until the friction from the ground makes it go slower than maxspeed. I need a way of keeping track of the speed forward, or the speed that originates from the engineforce. So that I can cap that speed and not just see to the total.


QuietBloke(Posted 2005) [#7]
Game Physics really isnt something Ive done much in so hopefully someone else here will be able to point you in the right direction for something a bit more realistic.

If I had to have a stab at a simple simulation Id probably try something like this.

1. If accelerating then apply an acceleration force to the tank.

2. The tank naturally wants to stop so every frame apply a friction force to the velocity.

I guess the friction force should increase with speed. In order to cap the total speed of the tank you want the friction force to be equal to the acceleration force when the velocity is the top speed.

so.. a simple first stab if the acceleration is 10 and max speed is 50 then friction could be velocity / 10.

so each frame you have the current velocity vector. You add the acceleration vector to it then reduce the length of the veolcity vector by the friction.

Hopefully this would mean the tank would accelerate fast at first and slow down as it approaches the max speed.
If a force of 200 hits the side of the tank when it is moving at max then you can carry on applying the acceleration vector to the velocity vector but the friction would ensure the total velocity would keep dropping until you reach normal forward motion.

Of course the above friction formulae is not very good so youd have to come up with something better.. maybe something like
1. If velocity < 50 then friction = 5
2. if velocity >= 50 then friction = 5+(velocity-50)*(velocity-50)

I dunno Id keep playing around till the results looked pleasing to the eye.

Anyway.. thats my mindless thoughts.. hopefully soon someone else who knows about these things will give you a better solution.
Good luck with it.


AntonyWells(Posted 2005) [#8]
Xi! = Xi! * Friction = drag.

Xi=Xi*0.95 = low friction. X=xi*1 = no friction.
Xi=xi*0.5 = Lots of friction.

(Xi being x inertia. repeat for all axis)

simple stuff but it works.


Sweenie(Posted 2005) [#9]
A simple dragforce could be calculated like this...

force = force - Dampingconstant * Velocity
[Basically the same damping often applied to springs]

There force is the current force acting on the tank and velocity of course is the speed of the tank.

So all in all it could look like this...

TotalForce = 0
TotalForce = TotalForce + ThrusterForce
DragForce = AirFrictionConstant * TankVelocity
TotalForce = TotalForce - DragForce

TankAcceleration = TotalForce/TankMass
TankVelocity = TankVelocity + TankAcceleration
TankPosition = TankPosition + TankVelocity

Depending on the AirFrictionConstant, the Dragforce will eventually cancel out the Thrusterforce when the velocity gets high enough.

A more correct dragforce calculation would also consider the area of the object but that is another story.


Yan(Posted 2005) [#10]
velocity :- (drag_constant * (velocity * velocity)) + friction_constant



Tibit(Posted 2005) [#11]
Thanks for all replies! and Special Thanks to QuiteBloke which really nailed it for me and my game =)

So I solved the problem and..

This is what I did:
This was perset set before the game "starts"
Global k#=Friction/MaxSpeed


This in the main-loop
Friction=Speed.Length()*k



I didn't need to change anything else to make it work, except to comment out If Speed.Length() < MaxSpeed.

I'm really impressed that a simple solution like that was what I was looking for lol.

Now I'm up for the task to actually make the tank act like a tank and not a spaceship =)


QuietBloke(Posted 2005) [#12]
Im glad to have been of some help.. I never seem to get round to writing anything myself other than experimental code and the physics stuff I mentioned was just random rambling but as usual ( and thats what I like about this community ) others with actual knowledge filled the gaps.

Good luck with the coding :)