Модель механического движения
Космический корабль представляет из себя треугольник, в основании которого стоят два двигателя перпендикулярно этому основанию. Если два двигателя включить с одинаковой силой, то корабль будет двигаться вперед. Если с разной силой, то корабль будет вращаться.
Поступательное движение
Движение материальной точки:
a = F / m
v = v0 + at
s = s0 + vt
Вращательное движение
Движение системы из двух точек:
z = F1 / F2
x = r (1 - 2z/(1 - z))
e = x(F1 - F2) / mr^2
w = w0 + et
fi = fi0 + wt
Алгоритм
import Vector from './Vector'
// Характеристики космического корабля.
const mass = 1000
const sizeD = 100
// Дискретность времени.
const timeInterval = 1
// Начальные значения физических величин.
const initialPosition = new Vector(0, 0)
const initialAngle = 0
const initialLinearVelocity = new Vector(0, 0)
const initialAngularVelocity = 0
// Текущие значения физических величин.
const time = 0
const position = initialPosition
const angle = initialAngle
const linearVelocity = initialLinearVelocity
const linearAcceleration = new Vector(0, 0)
const angularVelocity = initialAngularVelocity
const angularAcceleration = 0
let endGame = false
while (!endGame) {
// Ввод векторов силы для двух двигателей космического корабля.
const force1 = new Vector(0, 0)
const force2 = new Vector(0, 0)
// Поступательное движение.
linearAcceleration = force1.add(force2)
linearVelocity = initialLinearVelocity + linearAcceleration.scale(time)
position = initialPosition.add(linearVelocity.scale(time))
// Вращательное движение.
const forceRatio = force1.length / force2.length
const leverArm = sizeD / 2 * (1 - 2 * forceRatio / (1 + forceRatio))
angularAcceleration = leverArm * (force1.sub(force2)) / mass * leverArm * leverArm
angularVelocity = initialAngularVelocity + angularAcceleration * time
angle = initialAngle + angularVelocity * time
// Рисуем корабль на экране.
draw(position, angle)
// Приращение времени.
time += timeInterval
// Остановка.
sleep(timeInterval)
}
На самом деле timeInterval не будет выдержан ровно 1 секунду, потому что вычисления между отдельными кадрами могут занимать разное время. Поэтому алгоритм следует переписать так, чтобы timeInterval было переменным числом.