Hello.
This article presents the concept of writing a physics engine for railway transport.
One of the main tasks that this physics engine should solve is the calculation of the interaction between the cars.
Collision detection
The railway can be represented as a graph, the nodes of which are arrows. When translating, the arrow connects the two arcs of the graph and breaks the link with the third. A curve consisting of several arcs of a graph, along which a carriage can travel without moving the arrows, will be referred to as
“route” .
The interaction between cars on the same route occurs in one-dimensional space. At the time of transfer, the arrows can be calculated: which car is in front of and behind the car. Until the arrow on the route is transferred, which car’s connections are in front and which ones in the rear remain unchanged.
In three-dimensional space, side collision checks remain when the paths are very close. In such places, cars on different routes will not be able to disperse and collide. To optimize calculations in three-dimensional space, you can divide the area into cells and look for car collisions within this and neighboring cells. At the same time, side collisions between cars on the same route are not necessary to check.
The above calculation optimization methods make it possible to make the complexity of the collision search algorithm almost linearly dependent on the number of cars.
The concept of the interaction of cars that are on the same "route"
')
The car constantly has an impulse
mv .
At time
t, we calculate the total force vector
F = ma . Which changes the pulse
P = mv for this period of time according to the formula:
a = F / m;
v = (v + a * t);
P = m * v;Where:
a is acceleration,
m is the mass of the car,
v is the speed of the car
Interaction with other cars occurs by transferring momentum between them.
The algorithm of interaction between cars is reduced to solving several problems.
Task :
It is necessary to calculate the coordinates and impulses of cars through time
t .
t - time interval is less than a second.
Solution :
Compare all cars in pairs. Distance between cars
S.If the distance between the cars is reduced (the cars move towards each other, or one car overtakes the other car), we calculate how much time it takes for them to collide. We find such a minimum
collision time.
If one car is linked to another, and they move away from each other, then we find how long it takes to pull the automatic coupling. Find the minimum time for automatic tensioning tension.
We find the minimum interaction time between the cars:
t interaction = min (t collision, t tension) .
If
t interactions> t , then we move the cars for time
t and complete the algorithm.
Otherwise, we combine the colliding cars into a group, we consider for them a common impulse. Subtract the time from the interval
t = t-t interaction .
We move all the cars to the distance that they will pass during the time
t interaction .
We repeat the operation of the interaction algorithm between the cars, the group is considered as a whole. Moreover, if a group of cars collides with another body, and the group has a stretched automatic coupler, then the groups should be again divided into separate cars, as the cars inside the group can come closer.
Simplifications : Since t is a small period of time, we believe that the momentum of a car changes instantaneously with the combined force, while the force remains unchanged, even though the car changes coordinates and, therefore, the path profile changes (slope, height difference ). To increase the accuracy, you can split the interval t into less long periods of time and sequentially run the algorithm several times.
Task: Calculation of time before the collision of cars.There are two cars or groups of cars. There is a distance
S between the points closest to each other.

The cars have some coordinate X. The value of the X coordinate of "Car 2" is greater than that of "Car 1". The movement directed conditionally to the right will be considered positive, to the left - negative.
The car has acceleration and initial speed at the time of the beginning of the computational iteration. The initial speed will be denoted by v1 and v2, the acceleration of cars a1 and a2, respectively, for the first and second cars.
In order for the cars to collide, they must reduce the distance S in some time t. The solution of the problem is reduced to finding the time t.
Simplification:Since the time interval of one iteration of computing system calculations can be quite small, we assume that the track profile and other external factors affecting the cars cannot change much during this period of time. Therefore, the acceleration per iteration of the calculation will be considered constant.
Also, this algorithm does not take into account the specificity of the friction force. The force of friction is directed against the movement. And if the car changes directions under the action of any forces, then the acceleration at this moment should change significantly, so the friction force changes its direction and will have an impact on the acceleration.
Decision:Each car before the collision will move:
The first car on S1 = v1 * t + a1 * t * t / 2
The second car on S2 = v2 * t + a2 * t * t / 2
The initial distance between the cars before the collision is the difference of movement of the first and second cars.
S = S1-S2;
S = (v1-v2) * t + (a1-a2) * t * t / 2
We get a quadratic equation. The root of this equation will be the solution to the problem.
The block diagram of the algorithm is shown in the figure. The implementation of this algorithm in C # is shown in the listing.

/// <summary> /// /// </summary> /// <param name="s"> /// /// 2- </param> /// <param name="v1"> /</param> /// <param name="v2"> /</param> /// <param name="a1"> /(*)</param> /// <param name="a2"> /(*)</param> /// <returns> /// . /// /// (double.PositiveInfinity) /// </returns> public static double ClashTime(double s, double v1, double v2, double a1, double a2){ double A = (a1 - a2) / 2; double B = v1 - v2; double T; if (Math.Abs(A) < 0.000001) { if (Math.Abs(B) < 0.000001) { T = double.PositiveInfinity; } else { T = s / B; } } else { // double D = B * B + 4 * A * s; if (D < 0) { T = double.PositiveInfinity; } else { double pD = Math.Sqrt(D) / (2 * A); double pB = -B / (2 * A); double t1 = pB + pD; double t2 = pB - pD; if (t1 >= 0) { if (t2 >= 0) T = Math.Min(t1, t2); else T = t1; } else { if (t2 >= 0) T = t2; else T = double.PositiveInfinity; } } } return T; }
Task: Calculation of time to stop or change the direction of movement of carsThere is a car or group of cars moving together. The car has an initial speed V. The carriage is acted on by various forces, which give acceleration A and friction force, which gives acceleration Atr.
The car has a certain X coordinate. The value of the X coordinate increases conditionally to the right and decreases conventionally to the left. That is, directed conditionally to the right, we will consider positive, and to the left - negative.
It is necessary to know how long it will take for the car to change direction or stop.
Simplification:Since the time interval of one iteration of computing system calculations can be quite small, we assume that the track profile and other external factors affecting the cars cannot change much during this period of time. Therefore, the acceleration per iteration of the calculation will be considered constant.
Decision:The force of friction is directed against the direction of movement. Therefore, to solve this problem, you need to find a time at which the speed drops to zero.
KofTr - coefficient indicating the direction of friction force
A - acceleration of the projection of the sum of all forces, except for the friction force
If V> 0 then KofTr = -1 otherwise KofTr = 1
V0 + A * T + KofTr * Atr * T = 0
V0 + T * (A + KofTr * Atr) = 0
T = -V0 / (A + KofTr * Atr);

/// <summary> /// /// /// </summary> public static double StoppingTime(double frictionForceAcceleration, double otherForcesAcceleration, double speed) { double Atr = Math.Abs(frictionForceAcceleration); double A = otherForcesAcceleration; double V = speed; double KofTr; if (V == 0) return 0; if (V > 0) KofTr = -1; else KofTr = 1; double a = (A+ KofTr*Atr); // a = 0, if (Math.Abs(a) < 0. 0000001) return double.PositiveInfinity; // V a if (a * V > 0) return double.PositiveInfinity; double t = -V / a; return t; }
Calculation of the effect of gravity on one car
Calculation of the friction force acting on one car
Calculation of the displacement of the car or related group of cars
Of course, this is only a small part of the physics engine for the railway, the rest of the next article.