Skip to main content
GameDev.net gamedev.net
🔒 Locked

Lightspeed and lorentz

Started by Lode Dec 8, 2007 at 1:49 PM 24 replies 5.5k views
Original Post
Lode
Lode
Hi, I'm making a space game. In it, you can accelarate your ship. But if you're near lightspeed, I bring lorentz factors into account. This lorentz factor (well, the inverse, doesn't really matter) is calculated with the following formula:
double lorentzinv(double speed)
{
  return std::sqrt(lorentzinvsq(speed * speed));
}

double lorentzinvsq(double speedsq)
{
  if(speedsq >= LIGHTSPEED * LIGHTSPEED) return 0.0;
  double result =  (1.0 - (speedsq / (LIGHTSPEED * LIGHTSPEED))); //<-- the sqrt of this is the formula
  if(result <= 0.0) result = 0.0;
  return result;
}

The space game also has the feature that you can make the time go faster. You can choose between 1x, 10x, 100x, ..., up to 100000000x. The problem is now, if the time is going at a rate of 100000000x: then it would be insane to do physical calculations for every real second in those 1000000's of seconds in the interval. It would be way too inefficient to do that much calculations. BUT, at the huge intervals that the calculation has to happen then, is a problem!! The accelaration is calculated using the lorentz factor you have for the current speed. If you're at low speed, this lorentz factor is low. But then it makes you accelarate that fast for e.g. 1000000 seconds, without updating the lorentz factor in that (since like explained I don't work with millions of small intervals, I want to do the calculations in one go). So the result is that you reach lightspeed (much higher even), while in reality it shouldn't reach lightspeed, it should be near it because the lorentz factor should have slowed down the accelaration effect. So I've been trying to come up with a formula for the following: *) given -Your current speed in an absolute reference frame -The lorentz factor can be calculated using the formula given above -The start time (absolute time for external observer) -The end time (absolute time for external observer) -The power of your engine, and the fact that it constantly gives that constant power from start until end time *) asked -Your speed in said absolute reference frame after your engine has given a force with its constant power from start until end time, with the lorentz factors taken into account Does anyone know a way to come up with a formula for this? I've been thinking about something like this: calculate how much energy it's worth to give the constant power during the time interval. Then calculate how much that kinetic energy (with lorentz factors taken into account) adds up to your current speed. But I'm also stuck there at the part where kinetic energy and lorentz factors have to be combined. Anyone got experience with this? Please help :)
Zipster
Zipster
The relativistic kinetic energy equation is K = mc2(γ - 1) for Lorentz factor 'γ'. That's also the best approach I can think of, otherwise you're going to need to do some nasty integration or the like.
sergamer1
sergamer1
ok, this can get complicated, so here goes.

As Ziptster said, the kinetic energy is given by K = mc^2 (gamma - 1). If you first calculate the initial kinetic energy, which is

K_1 = mc^2 (gamma_1 - 1)

where subscript 1 refers to initial values (I will use subscript 2 to refer to values at the end of the timestep). If the engine burns for a time interval delta t = t_2 - t_1 (in the observer inertial reference frame), then the total work done by the engine on the ship is

W = power * (t_2 - t_1)

The final kinetic energy of the ship is then

K_2 = K_1 + W = mc^2 (gamma_2 - 1)

The trick now is to change the subject of the equation to get the speed v_2 from the above equation. I just went through the maths and came out with

v_2 = sqrt( 1 - 1/X^2 ) c

where X = (K_2)/(mc^2) + 1

I think that is correct, but it's easy to make a mistake in these kinds of things (it converges to the correct values for high and low energies, so it looks okay to me). I hope you understand my notation there. Just message again if it doesn't make sense and I'll try and write it again clearer. Special relativity is actually not too difficult PROVIDED you stay in the same inertial reference frame. Once you move to another frame, then you start screwing with you mind. Hope that helps :-)

Lode
Lode
Yes the notation is very clear, and I think I understand now how it can be solved in the case where you'd be going in one direction and only speed up in that direction.

There's one more complication though, everything is 3D vector math, and your velocity may be in 1 direction while you're accelarating in another direction, or you may even be accelarating in the opposite direction, causing you, within the time interval, to brake first and then start speeding up in the other direction.

Do you think this kind of things can be solved in the absolute reference frame? Or is it maybe needed to instead take for example the initial velocity of the ship as reference frame? If doing that, how to convert it to absolute speeds afterwards though? Because in the computer everything is still represented by absolute speeds.
sergamer1
sergamer1
Right yes, I see that I have made the assumption of travelling in a straight line. To do things in fully 3-D will be tricky, but I feel that perhaps the answer may be to use 4-vectors. 4-vectors are like traditional 3-D vectors, but have a fourth component relating to time (since space-time is 4-D). You can define a velocity and acceleration 4-vector and perhaps do the integration in standard ways, but using these 4-vectors instead of 3-vectors. I haven't read about this for a while so I'll have to do a bit of reading, but I think it can be done this way.
sergamer1
sergamer1
ok, let's give this another try. First of all the notation.

U3 = (ux, uy, uz) = Initial velocity vector (or the velocity 3-vector)
A3 = (ax, ay, az) = Acceleration vector (the acceleration 3-vector)
V3 = (vx, vy, vz) = Final velocity vector (i.e. at the end of the timestep)

If the engine burned for a time interval dt, then in conventional Newtonian dynamics, the answer would simply be

V3 = (ux + ax*dt, uy + uy*dt, uz + az*dt)

In Special Relativity, we must transfer our 3D vectors in 4D spacetime vectors. The velocity four vector is

U4 = (gamma1*c, gamma1*ux, gamma1*uy, gamma1*uz) = (gamma1*c, gamma1*U3)
where gamma1 is the Lorentz factor when travelling. In the last step, I have contracted the 4-velocity to 2 terms using the 3 velocity.

The acceleration 4-vector is a complete nightmare to write out here, but I'll try. First the scalar product of the velocity and accleration 3-vectors is
udota = ux*ax + uy*ay + uz*az

The acceleration 4-vector is then
A4 = (gamma1^4*udota/c , (gamma1^4*udota/c^2)*U3 + gamma1^2*A3) )

Right, I think then that once you have constructed these 4-vectors, it is quite trivial to integrate as usual. The only slight trick here is that you have to integrate with the proper time, not the real time, i.e. dt/gamma, not just dt. The final 4-velocity then becomes

V4 = (gamma1*c + gamma1^4*udota*dt/(c*gamma1) , gamma1*U3 +
(gamma1^4*udota/c^2)*U3 + gamma1^2*A3)*dt/gamma1)

Obviously there are some simplification in there, but I don't want to jump steps here. So you do this above step numerically and you obtain the final 4-velocity V4. However, what you want is the 3-velocity, i.e. the final velocity of the ship as it moves in the observers inertial reference frame. To get this, we note that the V4 is

V4 = (gamma2*c, gamma2*V3)

In order to get V3, we first take the first component of V4, i.e. gamma2*c and divide by c to get the NEW Lorentz factor gamma2, and then we divide the other three components by this to get the 3-velocity V3.

Right, I cannot believe there is a more complicated way of doing that, but that's what happens when you do fully 3-D relativistic dynamics. I should add that I've never done this kind of computation myself before, but I don't see any problems here (other than possible typos that is). I'd suggest looking up 4-vectors on Wikipedia or somewhere where their maths is probably clearer than mine.
sergamer1
sergamer1
ok, I just read through my reply and it wasn't completely clear on a few things, so thought I'd add some more.

The 3-vector velocity is the usual velocity vector in 3-D space (as the external observer would measure in his reference frame). The 4-vector velocity is the velocity of a body through 4-D spacetime and it means something completely different to the 3 velocity. It isn't simply the 3-vector velocity plus another component, so don't get them confused in that way. It is simply that you have to do the maths in 4-D before transforming back to get things in usual 3-D.

The other thing probably worth addressing is the acceleration. My first attempt at solving this problem used engine power, while here I have used acceleration. The 3-acceleration is the acceleration in ships frame. Of course, the external observer sees something different (this is equivalently a time-dilation effect, since he sees the engine running slower with less power and hence less acceleration). The power of the engine in the ships frame is the actual measure of the engines power.

Well, I'll be online most of the day, so hopefully I can answer any questions about this. If there's anyone out there reading this who understand relativity, it would be nice for some input on whether you think this is the correct method or not. Cheers,

Sergamer
Lode
Lode
I'll try to put this all together in code now, I think it'll be a while before this is done, maybe I'll post the result if it works.

Thanks for the help, it's really helpful :) I'm also reading the stuff on Wikipedia now, but the replies here are more clear for this particular problem.

EDIT: removed question, I understand it now, I think they forgot a "u" in an index in a formula on the Four-accelaration page on Wikipedia :)

[Edited by - Lode on December 9, 2007 11:26:34 AM]
sergamer1
sergamer1
ok, the entry on Wikipedia had a typo in it. The gamma-without-a-u should also be a gamma_u (already corrected ;-) ). The extra factor of gamma is in the four-acceleration definition, e.g. the first component of the four-acceleration is gamma_u * dotted_gamma_u * c . The dotted_gamma_u contains 3 powers of gamma_u so the total is gamma_u^4. Also, one of the factors of c cancel out leaving just one in the denominator.

A couple of other things have come to mind also. There may be some timestep constraints for accurate integration, although I can't think how to formulate a timestep condition off the top of my head (maybe something to do with dotted_gamma_u ?). Also, a check you can make to ensure things are going well is to recompute gamma using the 3-velocity and compare it to the value you get from the first component of the 4-velocity. They should be pretty close if things are done correctly. I would also suggest using this new recomputed value of gamma for the next timestep rather than use the one that comes out of the four-velocity. I have a feeling that would otherwise be a source of error.

Sure, tell me how it goes and if it works, since I'll interested to know if it does. Good luck coding!
taby
taby
You're on the right track! Three things to always remember in inertial frames of reference:

1) 3-velocity is always less than c for a massive object.
2) The massive object's time rate t slows with increased 3-velocity, and is always greater than 0.
3) 4-velocity is the magnitude of the time rate t and 3-velocity, and is always equal to c.

These rules are expressed in the following code:

#include <iostream>#include <cmath>using namespace std;int main(void){	double c = 299792458;	double c2 = c*c;	double x = c/2;	double y = 0;	double z = 0;	double vel3 = sqrt(x*x + y*y + z*z);	double t = c*sqrt(1 - vel3*vel3 / c2);	double vel4 = sqrt(t*t + x*x + y*y + z*z);	cout << vel3 << endl;	cout << t << endl;	cout << vel4 << endl;	return 0;}


For a massless object, 3-vel is c, t = 0, 4-vel is c.
Lode
Lode
I got this code so far:

class FourVector //for special relativity calculations{  public:  double t;  double x;  double y;  double z;    double length() const  {    return std::sqrt(lengthsq());  }    double lengthsq() const  {    return t * t - x * x - y * y - z * z;  }    void fromVelocity(const lpi::Vector3& u, double gamma)  {    t = gamma * LIGHTSPEED;    x = gamma * u.x;    y = gamma * u.y;    z = gamma * u.z;  }    void fromAccelaration(const lpi::Vector3& a, const lpi::Vector3& u, double gamma)  {    double udota = dot(a, u);    double gamma2 = gamma * gamma;    double gamma4 = gamma2 * gamma2;        t = gamma4 * udota / LIGHTSPEED;    x = gamma4 * udota / (LIGHTSPEED * LIGHTSPEED) * u.x + gamma2 * a.x;    y = gamma4 * udota / (LIGHTSPEED * LIGHTSPEED) * u.y + gamma2 * a.y;    z = gamma4 * udota / (LIGHTSPEED * LIGHTSPEED) * u.z + gamma2 * a.z;  }    void toVelocity(lpi::Vector3& u)  {    double gamma = t / LIGHTSPEED;    u.x = x / gamma;    u.y = y / gamma;    u.z = z / gamma;  }    FourVector& operator*=(double d)  {    t *= d;    x *= d;    y *= d;    z *= d;    return *this;  }    FourVector& operator+=(const FourVector& other)  {    t += other.t;    x += other.x;    y += other.y;    z += other.z;    return *this;  }};inline FourVector operator*(double a, const FourVector& b){  FourVector result = b;  result *= a;  return result;}inline FourVector operator*(const FourVector& a, double b){  FourVector result = a;  result *= b;  return result;}inline FourVector operator+(const FourVector& a, const FourVector& b){  FourVector result = a;  result += b;  return result;}


and using this class here:

void SpaceObject::handleNewton(double deltaTime){  double gamma = std::sqrt(lorentzsq(vel.lengthsq()));    double tauTime = deltaTime / gamma; //proper time    FourVector fourVel;  fourVel.fromVelocity(vel, gamma);    FourVector fourAcc;  fourAcc.fromAccelaration(acc, vel, gamma);    FourVector newVel = fourVel + fourAcc * tauTime;    //now fill in the new vel  newVel.toVelocity(vel);    //move by the velocity  move(vel * deltaTime);    //limit velocity to lightspeed just in case  if(length(vel) > LIGHTSPEED) vel = lpi::normalize(vel) * LIGHTSPEED;}



At the moment this doesn't work as intended though, it just goes to LIGHTSPEED and then I can't decellarate anymore because the lorentz factor becomes too close to infinity. Maybe something is wrong. I'll continue working on this tomorrow. Just posting the intermediate result for the curious ones :)
taby
taby
When you are accelerating, you must keep in mind that the body's total energy (and thus inertia) increases much faster than in Newtonian mechanics.

Rest mass:
m = E/c^2

Relativistic momentum:
p = mv/sqrt(1 - v^2/c^2)

Relativistic energy:
E' = sqrt(p^2*c^2 + m^2*c^4) = E/sqrt(1 - v^2/c^2)

Acceleration from force (from Newton's F = ma, a = F/m):
a = F / (E'/c^2)

It should never ever be possible to accelerate a massive object to light speed. This is apparent when v ~ c, because E' ~ inf, and thus a ~ 0 regardless of how large of a Force is applied.

Keep in mind that the amount of Force generated per spent litre of fuel is constant (assuming you do regular oil changes and have the tires aligned every 3000km).

Also, each litre of fuel that is carried along with the vehicle also contains mass-energy, which in turn increases the vehicle's total inertia, which further reduces the acceleration obtained from unit Force. It's a vicious circle that cannot be overcome. Attach a camper-trailer to a Mazda 3 and fuel efficiency (acceleration against air pressure and road friction) gets 5 miles/gallon instead of 60. Same amount of fuel/force, smaller amount of acceleration due to inertia.

Finally, where a > 9.81 m / s^2, discomfort will ensue.

[Edited by - taby on December 9, 2007 7:34:54 PM]
medevilenemy
medevilenemy
so says conventional physics :-p. Unfortunately, taby is right. It would probably be better to think up and rationalize some sort of FTL scheme that doesn't require direct acceleration (perhaps something like Alcubierre drive which is theorized, but not concretely proven or disproven).
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
taby
taby
I see where you might be running into trouble...

At v = c - 0.00000005, the increase in energy is nowhere near infinite, but that's about as precise as I can get before things blow up. Maybe you need a higher precision floating point type.
taby
taby
Quote:
Original post by medevilenemy
so says conventional physics :-p. Unfortunately, taby is right. It would probably be better to think up and rationalize some sort of FTL scheme that doesn't require direct acceleration (perhaps something like Alcubierre drive which is theorized, but not concretely proven or disproven).


I see on the wikipedia page for this that the objection is brought up:

"It has been suggested that an intense flux of blue shifted starlight would fry any inhabitants of the bubble".

Not that this is limited to FTL. I think it goes to show that any significant velocity greater than 0 is a bad idea in practice, due to the Doppler shift light colliding with the front of the vehicle.
taby
taby
Quote:
Original post by medevilenemy
so says conventional physics :-p. Unfortunately, taby is right. It would probably be better to think up and rationalize some sort of FTL scheme that doesn't require direct acceleration (perhaps something like Alcubierre drive which is theorized, but not concretely proven or disproven).


I see on the wikipedia page for this that the objection is brought up:

"It has been suggested that an intense flux of blue shifted starlight would fry any inhabitants of the bubble".

This effect is not limited to FTL, which I think goes to show that any significant velocity greater than 0 is a bad idea in practice, due to the relativistic Doppler shift of light colliding with the front of the vehicle. At a great enough velocity, the relativistic energy (E' = pc) of a single microwave photon (I picked this wavelength arbitrarily) would end up being greater than the total rest energy of the star which emitted it! To collide with that would truly suck. And to those who say "don't travel directly toward a star", my response would be "what else would want you fly toward?".

Whether or not this type of spacetime metric is possible is beside the point, since it seems that this setup is not verifiable. Should physicists stop conjuring up such dream-like configurations? No. It's too much fun to think about. :)
medevilenemy
medevilenemy
Yeah, but realistically, though, one really doesn't need to worry about EM radiation frying the crew. EM Radiation is relatively easy to block (A heavy duty hull would probably function like a really good faraday cage, not to mention a bunch of other methods.
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
liquiddark
liquiddark
If you really want to push into the extremely-close-to-lightspeed problem, then you should not be using floating point. You're just asking for bad behaviour. Switch to a fixed-point representation, or limit the speed, or find a better way to scale your numbers when you get close to light speed. Digital computation is not your friend in this domain, I'm afraid.
No Excuses
Lode
Lode
Quote:
Original post by taby
I see where you might be running into trouble...

At v = c - 0.00000005, the increase in energy is nowhere near infinite, but that's about as precise as I can get before things blow up. Maybe you need a higher precision floating point type.


Quote:
Original post by liquiddark
If you really want to push into the extremely-close-to-lightspeed problem, then you should not be using floating point. You're just asking for bad behaviour. Switch to a fixed-point representation, or limit the speed, or find a better way to scale your numbers when you get close to light speed. Digital computation is not your friend in this domain, I'm afraid.


Well there exists a 128-bit floating point type in the floating point standard now (or at least soon), but do you think the C++ standard follows? Nooooo, they're way to slow, they first have to finally introduce the long long type that is at least 64-bit int that has been supported by CPU's for decades, the quad floating point is probably going to take 20 years before the first proper C++ standard about it exists. They think it's funny that you have to use non standard libraries that need external linking and make code less portable, to have useful number types that are natively supported by the CPU and will compile on more than one compiler.

Quote:
Original post by taby
Also, each litre of fuel that is carried along with the vehicle also contains mass-energy, which in turn increases the vehicle's total inertia, which further reduces the acceleration obtained from unit Force. It's a vicious circle that cannot be overcome. Attach a camper-trailer to a Mazda 3 and fuel efficiency (acceleration against air pressure and road friction) gets 5 miles/gallon instead of 60. Same amount of fuel/force, smaller amount of acceleration due to inertia.

Finally, where a > 9.81 m / s^2, discomfort will ensue.


That's not really a problem, who said it's using fuel, it could for example use the combination of matter and antimatter to produce the force.

And the people in the ship are protected from accelarations up to 1000g (9810 m/s^2 ;)).

Something has to be unrealistic in a space game, I guess now it's the ability to accelarate faster than a human or fuel could handle, but at least it isn't wormholes or warp drives this time :)

I guess i'll have to find some numerical way around the problems...
liquiddark
liquiddark
Quote:
Original post by Lode
Well there exists a 128-bit floating point type in the floating point standard now (or at least soon), but do you think the C++ standard follows?


Unless you limit the growth of your speed in some way, this only gives you more wiggle room. Numerical instability isn't a consequence of the length of the mantissa. It's a fundamental problem with floating point numbers.
No Excuses

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.