Mathematical vectors

I dont argue against the fact that float & double work the same and the fact that care must be taken for both… this is the same between short & int … in case of floatting value care must be taken on the fact they are not made to work as integer and result should never be considered as exact : like better not doing floatComputation() == floatComutation() or similar thing, care must also be taken on NaN result, all that is true for double aswell as float, this was not what I was pointing

my point was rather : double are more precise and without any reason it is not necessary to use float, same apply with int they are more precise than short and without any good reason use int, also double & int have always been both defaut var type for java… and they both are fast

the argument saying double may hide bugs is ?! dont know… strange, funny… astonishing… : float can exacly do the same (work 99.9% of time and a days fail), so do you advice to use something with a lower precision than float to be sure to catch all possible bugs ? :slight_smile:

to be back on topic :

[quote]Currently what’s happening when the car collides is its velocity is reversed and added to its position, which has the effect of undoing the previous move(). (During move() the velocity is added to the position. On a collision, the velocity is subtracted from [its negative added to] the position. So the car is back where it started.) So the code is (inadvertently?) doing exactly what DzzD suggests – undoing the step that led to the collision.
[/quote]
hum not really the same, keeping trace of last pos is different, that’s another funny thing with floatting values (meaning float & double…) as they use dynamic “range of data” => this can be true : a+v-v != a

for example if you add big value with small one :

x=0.01
x+v=1000000.0
x+v-v=0.0

  	
    float x=0.01f;
    float vx=1000000f;
    System.out.println ("x=" + x);
    x+=vx;
    System.out.println ("x+v=" + x);
    x-=vx;
    System.out.println ("x+v-v=" + x); 

@OP, with float always replace addition by multiplication when possible/applyable :

for example to compute object location with floatting var :
posX=posX0+vx*nbStep
give smarter result than :
posX+=vx

hum not really the same, keeping trace of last pos is different […]
[/quote]
Good point. :slight_smile:
Replace “exactly” with “sort of like (but not as robust as)” in my original comment.
Simon

Hi guys!, Finally back after a short leave from work :P.
I’ve been working on the game for a while now - actually just adding features, re-coding classes, using more efficient manners of doing things, and well I decided to get rid of my currentSpeed variable inside the car class. That means I’m left with a constant acceleration variable ACCELERATION, a vector acceleration, vector position, vector direction and vector velocity.
Basically to get the speed now, we would use velocity.magnitude() now. The problem I’m having with this is in fact what pjt33 posted about acceleration being not a number when it’s length is set to the constant acceleration * deltaTime from the initial velocity vector (0,0). Getting the magnitude from that vector and using the length to divide it is what gives me NaN, so I decided to just return a vector(length,length) and that just isn’t the correct way to be doing it.

Btw, sorry if this is considered grave digging, but I figured it still relates to a related problem I’m having.

You’re using too many variables to store acceleration and velocity.

You need:

  1. a vector position (that is treated as a point)
  2. a vector velocity (this is the direction of travel, and the speed, you get the speed by taking the length of the vector).
  3. a vector acceleration (this is the direction of acceleration and the magnitude of acceleration, which you get from the length of the vector).

You do not need a separate constant variable ACCELERATION or a vector direction (assuming you’re keeping the vector velocity).

To figure out how to update something every frame, we can look at the physics equations:


v = a * t;
d = v * t;

These basically say that the change in velocity (v) over a period of time (t) is equal to the acceleration (a) multiplied with the time delta (t).

Similarly, the change in position (d) over a period of time (t) is equal to the velocity (v) multiplied with the time delta (t).

So if you’re using vectors, it would look something like:


Vector3 deltaV = acceleration.scale(dt); // calculate change in velocity based on delta time and current acceleration
Vector3 totalV = velocity.add(deltaV); // update velocity based on computed change for frame
Vector3 deltaP = totalV.scale(dt); // calculate change in location based on updated velocity and delta time
Vector3 finalP = position.add(deltaP); // location at end of frame.

This is euler integration if you’ve ever seen that term used in your readings.

To muddy the waters a bit, it’s a good habit to run simulations at a fixed time rate. Although not important for very simple situations, it’ll make make your life a lot easier when things get a little more involved.

Ahh right right, I thought I needed the constant acceleration variable to use it for the acceleration vector, since its initially started out as a zero vector.
I’m guessing we can just set the acceleration vector to some constant digit? - But then that would mean its direction would be wrong?.. In addition I believe that the code you are giving me relates to objects which have a linear velocity. IE A bullet, the player has no control over its acceleration. In my case I do need to change the acceleration depending on if (up/down) and the direction on (right/left).

Mind giving me an example of what I’m up against seeing as deltaTime is not ALWAYS constant (The majority of the time it is, but some discrepancy is probable).

This is one of those “don’t worry about it now, but keep it in the back of your mind” kind-a things. Simulation results will almost alway vary depending on the times of each step used (unless you way overcomplicate the computations…and then they still vary…so you start to pull out your hair)

I don’t believe I’m ready just yet to turn to a fixed time step system, I’d rather understand how to fix what’s wrong now and later on if need be do conversions :stuck_out_tongue:

Anyway following lhkbob’s logic I’ve come up with the assumption that a new acceleration vector must be created when interacting with player input - thus giving me the following.


double deltaSeconds = deltaTime / 1000.0;// seconds since last update
double speed = velocity.magnitude();
double direction = Math.toRadians(carAngle - 90);
		
if (up)
	acceleration = new Vector2D(75 * Math.cos(direction),75 * Math.sin(direction));
if (down)
	acceleration = new Vector2D(-75 * Math.cos(direction),-75 * Math.sin(direction));
if (right)
	carAngle += rotationSpeed * deltaSeconds * (speed/topspeed);
if (left)
	carAngle -= rotationSpeed * deltaSeconds * (speed/topspeed);

acceleration = acceleration.scale(deltaSeconds); 
velocity = velocity.add(deltaV);
velocity = velocity.scale(deltaSeconds);
position = position.add(deltaP);

I believe that constant 75 would be used to describe the acceleration magnitude - but simulation wise is not the proper way of doing it. The car can accelerate and decelerate, thus meaning I need to figure out a way to increase/decrease acceleration respectively without creating a new vector each time the function is called. Would I need to add a step variable and increase/decrease it like I am doing it for the carAngle to determine the heading?

Another note on the same topic, how would i set the direction of the acceleration vector if I am simply scaling or setting the magnitude of the acceleration variable without creating that vector using a direction?

I believe you’re on the right track. The acceleration vector doesn’t need to be constant. You were worried about what happens when it’s not accelerating, then just have it set to (0, 0) (so it’s length is 0 = no acceleration). I guess you would want to have some constant that describes the MAX_ACCELERATION_LENGTH (if the acceleration’s length is larger than this, clamp it to that length, which would involve scaling the vector by MAX_ACCEL / length). You don’t need a float variable storing current acceleration, that’s what the vector is for.

In your code, it looks like you’ve assigned your computed variables incorrectly. Instead of:


acceleration = acceleration.scale(deltaSeconds);
velocity = velocity.add(deltaV);
velocity = velocity.scale(deltaSeconds);
position = position.add(deltaP);

you should have


deltaV = acceleration.scale(deltaSeconds);
velocity = velocity.add(deltaV);
deltaP = velocity.scale(deltaSeconds);
position = position.add(deltaP);

Regarding your last question, if you want to set the magnitude of the acceleration vector without changing its direction, you divide the acceleration vector by its current length (so the new vector has a length equal to 1), then you scale it by your new acceleration magnitude.

The resulting vector has the same direction as the old acceleration, but with the new magnitude. This does not work when the acceleration vector is (0, 0). At that point, you’d have to choose a direction as well.

Ahhh right right, the first part was my mistake :P, I actually had:


acceleration = acceleration.scale(deltaSeconds);
velocity = velocity.add(acceleration);
velocity = velocity.scale(deltaSeconds);
position = position.add(velocity);

The problem is actually increasing / decreasing the acceleration. Do I need a stepping varriable? IE. if (up) speed+= 5, and then in acceleration = new vector(speed* direction)? In addition the acceleration vector is set at zero in the beginning; How would I go about to setting up its direction if acceleration doesn’t exist? It only goes at non zero while inside the move() function which is called by the update loop.

This comes back to my original question which is do I need to create a new acceleration vector each loop - considering the player input?

I think my problem lies with me still thinking in 1D instead of 2D… I just don’t understand how you can increase/decrease acceleration without a constant. :frowning:

You can think of acceleration existing only so long as the object/player needs to change velocity. So if the player isn’t touching any keys, his acceleration is 0. If he hits the jump key, you might have 1 frame with an acceleration pointing up with a large enough magnitude that he’s still flying up for a few frames before gravity pulls him down. If he hits the forward key, set the acceleration to a constant magnitude in the direction he’s heading or turning until he’s accelerated to the desired velocity then set the acceleration to (0, 0). If he lets go of the key, the acceleration changes to (0, 0), if he hits the key for the opposite direction, the acceleration changes to the negative of the acceleration so he starts slowing down (and eventually reaches 0 velocity at which point you set acceleration to 0, or keep going to have him going in reverse).

I believe in my case having acceleration set to 0 while no keys are being touched is incorrect. – unless we apply friction to velocity and not acceleration (something i should just check actually*), but I fail to see the relation between this and a constant possibly*? being needed to calculate acceleration based on player input.
Furthermore if the requirement to calculate acceleration does lead to having a new vector created each time the move function loops, - we DO need a step variable to increment acceleration since a car doesn’t have constant acceleration - based on player input - if this efficient?
Instead would it be possible of coming up with a way to deal with acceleration just based on vector functions?

Seems you were right in saying that I don’t need a stepping variable to increment acceleration - seeing as its constant* (It’s the velocity that increases when we add acceleration! :D)

I actually have a problem with the rotation now that acceleration is fixed… :frowning: dammit is it possible to get this over with! sheesh! :stuck_out_tongue:
So I know what the problem is but I actually have no idea how to fix it…


double direction = Math.toRadians(carAngle - 90);
double speed = velocity.magnitude();
double magnitude = 0;
		
if (up)
	magnitude = 100.0;
if (down)
	magnitude = -100.0;
if (right)
	carAngle += rotationSpeed * (speed/topspeed);
if (left)
	carAngle -= rotationSpeed * (speed/topspeed);
		
acceleration = new Vector2D(magnitude * Math.cos(direction), magnitude * Math.sin(direction));

The problem is the acceleration vector. When I just turn the car, magnitude = 0 and 0*direction gives me 0 thus not updating the direction…
I thought I could fix it with a simple if (speed > 0) acceleration = new Vector2D(speed * Math.cos(direction), speed * Math.sin(direction)) but that doesn’t work and is obviously illogical… seeing as we would keep adding the acceleration to velocity till velocity would hit MAX_VEL_LEN. Thoughts, ideas, suggestions?

By the way I hate double posting :frowning: but I really didn’t want to make another topic on this subject regarding the same type of query this is, as I like related information to be kept concise and organised, and it has been a while…

Split it up into two accelerations, one for rotating and one for translation. In this limited situation, you can specify each acceleration as a double. This is because you should define the translation acceleration to always be in the direction is facing, and the rotational acceleration about the center of the car.

It is not a perfect model, but it should work. First you use the above equations to figure out the amount of rotational velocity in an interval, and use that to update your carAngle variable. Then with the carAngle variable, you know the direction you’re going so you can compute the translation acceleration and update the velocity and position of the car.

Alternatively, look into a physics engine like JBox2D that can handle all of this for you. The model I described above isn’t perfect and won’t account for drift or anything like that and a physics engine will make sure all of the equations are correct. Now that you know more about vectors you should be able to understand the concepts of the engine reasonably well.

The thing is, I don’t understand how the rotation occurs if we have a magnitude of 0. Acceleration cannot be 0 when changing direction or can it? So how do you handle this using a single acceleration vector? accompanied by a velocity vector and a position vector of course.

Not that I don’t want to use 2 accelerations, but tbh that would confuse me! since I wouldn’t understand how to unite them for the final acceleration! Also as far as using an engine I’d rather have a shot at my own, that way once it’s all worked out I’ll be able to say I’ve created one and can move on to a more sophisticated one if I wish to do so :stuck_out_tongue:

I’m so close… yet sometimes it seems so far… I think once we’ve solved this rotation issue, motion won’t be a problem anymore anywhere within this game :smiley:

If you want to handle rotation, you need two acceleration vectors. One vector is the acceleration we’ve talked about before, which applies to translational velocity and affects the position of your vehicle.

The second vector is a rotational acceleration. It applies to how fast your rotational velocity is increasing. The rotational velocity changes the direction your car is attempting to travel. By splitting things into two vectors you can have things like drift where the car turns one direction and continues to slide the way it was originally going.

The direction of the acceleration vector is generally perpendicular to the direction you’re heading, which is why I simplified it in my last post.

So let me clear something up then, this means we are creating a new velocity vector each update instead of simply adding the acceleration? I thought velocity just the added acceleration * dt each update? but essentially what I’m getting out of what you are telling me is velocity = new Vector2D(magvector, dirvector), which quite honestly I don’t understand…

Right now the procedure is simple, as in my initial velocity vector is 0,0 and all I do is increase it by adding a new acceleration vector each update (which is scaled by time), leading to adding this to velocity vector to my position. Essentially I’m saying v = a * dt and p = v * dt. You are suggesting to switch this how exactly?

I don’t understand how you would manage to change/update the velocity without a single acceleration variable - that is the magnitude and the direction.

This is the current situation


double secondsElapsed = (deltaTime / 1000.0);// seconds since last update
double speed = velocity.magnitude();
double magnitude = 0;
		
if (up)
	magnitude = 100.0;
if (down)
	magnitude = -100.0;
if (right)
	direction += rotationSpeed * (speed/topspeed);
if (left)
	direction -= rotationSpeed * (speed/topspeed);

double dir = Math.toRadians(direction - 90);
acceleration = new Vector2D(magnitude * Math.cos(dir), magnitude * Math.sin(dir));
		
Vector2D scaledA = acceleration.scale(secondsElapsed);
velocity = velocity.add(scaledA);
		
/**
//////////////////////// CALCULATE FRICTION //////////////////////////
Vector2D friction = velocity.scale(-0.3 * speed * secondsElapsed);
velocity = velocity.add(friction);		
//////////////////////////////////////////////////////////////////////
**/
		
if (speed < 1.5 && speed != 0)
	velocity.setLength(0);
		
Vector2D scaledV = velocity.scale(secondsElapsed);
position = position.add(scaledV);

There are two directions you need to think about, the direction something is rotating and the direction something is sliding. The rotation and position of an object describe it. The rotation can be represented as an angle or as a direction vector that signals which way is front.

In physics there are three principal concepts: acceleration, speed, and distance. Acceleration * dt will give you the change in speed, speed * dt will give you the change in distance. Velocity is speed in a multidimensional case.

The rotation of the object gets an acceleration, speed, and distance (amount of rotation) and the position of an object gets an acceleration, speed, and distance. These are all 2D vectors. The rotational acceleration, rotational velocity, and rotation are independent of normal acceleration, velocity and position except for a case I’ll describe below.

You’re trying to simulate a vehicle. How you apply the physics to a vehicle can significantly impact how it “handles”. In my vehicle model, the engine accelerates the vehicle forward in the direction its facing. This implies that you need to compute the rotation first, and then use the rotation to compute the positional acceleration since each frame it accelerates in the direction its facing.

You current situation that you’ve written up looks okay to me. You have implemented all of the concepts I’ve described. One thing to note is that you’ve collapsed the rotation equations down to a single dimension. This is 100% valid in your situation since you’re turning about an objects center. Additionally, you’ve removed rotational acceleration so that turning is on or off (and when on will not speed up or slow down). This is also valid.

Basically, you are telling me here that rotation can be represented as a single double variable or a vector which has a magnitude of 1. I’m using a single double variable as pointed out earlier.

This is a part I don’t understand. How is rotational acceleration, rotational velocity and rotation independent of acceleration? Acceleration has the direction of that rotation, does it not?

You are telling me that my current situation is valid here, yet my rotation has the problem of not being updated because my acceleration magnitude can be 0 when a user doesn’t press up or down, which I have no idea how that can actually be correct. The rotation is not changing when the user is only pressing left or right arrow keys since my magnitude is 0 * Math.sin/cos(dir) == 0.

How exactly do you represent the direction of acceleration if as you say, the rotation component of it all is separate from the acceleration? Additionally how do these two separate components interact with velocity and position? Like I mentioned isn’t velocity dependent on acceleration * dt? (Note: acceleration is a vector…)

Maybe some pseudo code would be of use here… I find it strange that acceleration and rotation are two different components when used in physics – since acceleration has a direction! lol (I know there is a lot of repetition here, but I just want to explain myself clearly)

Oh and I want to thank you for sticking with me this long, I’m sure it’s a pain, but I feel we are very close to the final result! :smiley:

Sorry for late response. Acceleration does have a direction, it is the direction that the object slides or translates. Rotational acceleration is the acceleration of the change in degree of rotation.

I think the issue that is confusing you is that the angle a car is rotated, or its direction, affects the direction that its motor accelerates the vehicle. When you press left/right keys you want to change the rotational acceleration and when you press up/down you want to change the translational acceleration.