Войти
ПрограммированиеФорумФизика

Движение поезда по рельсам

#0
13:47, 8 апр. 2018

День добрый.

Никогда не думал, что буду обращаться с такой проблемой сюда, но все же)

Пишу сейчас маленькую игрушечку про поезда. Точнее, начинаю (это к тому, что кода сейчас особо нет, лишь воображаемый).
Суть такая: есть набор рельс, а именно - их пока что 3 вида. Прямые участки, стрелки и поворотные участки.
Поворотные участки - не просто дуги окружности. В зависимости от места их расположения они могут быть дугами овала, т.е. сплюснутой окружности.
Вопрос стоит примерно такой: как мне двигать поезд по рельсам?

Допустим, в моей реализации у каждой рельсы будут два поля (у стрелки 3) - соединенные рельсы. И что-то вроде функции

f(пройденныйПоРельсеПуть): ПоложениеТочкиВМире
Тогда станет реальным движение локомотива. Однако с вагонами будет уже сложнее. И я еще молчу насчет правильного позиционирования и поворота тележек с колесами.

Поэтому и обращаюсь сюда в надежде, что у кого-то есть идеи или же кто-то сам реализовывал уже что-то подобное.
Любые мысли сливайте сюда, ибо сам я уже отчаялся.

Спасибо.


#1
17:00, 8 апр. 2018

Тебе обязательно нужно, чтобы траектория задавалась паметрически

f(ПройденныйПоРельсеПуть): ПоложениеТочкиВМире
или можно передвигать вагоны инкрементально
g(СтароеПоложениеТочкиВМире, ДельтаПути): НовоеПоложениеТочкиВМире
?

alexanya11
> Однако с вагонами будет уже сложнее.
А в чём именно заключается проблема? Тебе нужно, чтобы они сохраняли постоянный интервал?

#2
17:48, 8 апр. 2018
Тебе обязательно нужно, чтобы траектория задавалась паметрически

Нет, не обязательно, однако это как вариант.

Дело в том, что я думаю реализовать так:

Абстрагируемся от понятия "поезд". Пусть будет понятие "материальная точка". Материальная точка - тележка с колесами.
Тележки нужно позиционировать на рельсах. Учитывая, что каждая тележка относительно другой находится на разном расстоянии по прямой,
но расстояние по рельсам не изменяется (что следует и того, что они проходят одинаковый путь), то мне достаточно лишь двигать первую тележку поезда,
а все остальные двигать на такое же расстояние, как и первую.

Хорошо, у нас есть понятие материальной точки. Как реализовать рельсы тогда? Описывать их функциями?
Можно для каждой тележки хранить рельсу, на которой она сейчас стоит, и расстояние от края. Но как тогда задавать направление движения? Сложно, в общем

#3
20:09, 8 апр. 2018

alexanya11
> Хорошо, у нас есть понятие материальной точки. Как реализовать рельсы тогда?
> Описывать их функциями?
> Можно для каждой тележки хранить рельсу, на которой она сейчас стоит, и
> расстояние от края. Но как тогда задавать направление движения? Сложно, в общем
1) Двигаешь обычную точку по напрвлению рельс с нужной тебе скоростю , а тележку физический привязуешь к этой точки всё  !

2) Ну или просто приминяшь импульс в направлении рельс , но тогда на поворотах инерция будет выкидывать тележку, так что лутше первый способ !

#4
1:54, 9 апр. 2018

alexanya11
> f(пройденныйПоРельсеПуть): ПоложениеТочкиВМире
в таком виде не очень-то удобно реализовывать ветвления рельс и некоторые другие эффекты вроде закона сохранения момента импульса на криволинейных траекториях. может быть проще задать путь в виде

train.pos = track.Project(train.pos);
идея в том, что ты каждый dt сначала двигаешь вагон, игнорируя рельсы:
train.pos += train.velocity * dt;
а потом — проецируешь его на ближайшую точку на рельсах.

ещё таким образом проще сделать жёсткие соединения между вагонами — просто накладываешь на вагоны position-based связи и всё.

#5
4:07, 9 апр. 2018

гугли движение по сплайну

#6
8:00, 9 апр. 2018

Как пример - в роботостроении есть такой алгоритм движения по линии. Там стоят датчики которые отслеживают белый и черный цвет и корректируют движение робота. Траектория может быть какой угодно правда с некоторыми ограничениями.
В инете множество реализаций этого алгоритма. Но это для робота.

Для рельс как и посоветовал mega_otec обычно используются сплайны.

#7
9:53, 9 апр. 2018

Очень смешно наблюдать за тем, как некоторые пишут в тему какой-то мусор и думают (наверно) что этим чем-то помогли (нет).

Suslik

> а потом — проецируешь его на ближайшую точку на рельсах.

Думал о чем-то похожем. Но это уже ближе к реальному физическому взаимодействию. Проще уже поставить поезд на рельсы и двигать физическим движком)

На самом деле я придумал, как буду делать. Для каждой тележки сохраняем рельсу, позицию на рельсы можно сохранять или от нулевого узла, либо как-то ещё - не важно. Потом на каждом кадре я для каждой колёсной тележки вызываю метод

move(direction: Vector2, distance: Float)
В классе рельсы будет инкапсулирована логика этого движения, будем двигать телегу в одну из двух сторон (выбираем исходя из скалярного произведения нормали рельсы в положении вагона сейчас и направления, в котором нужно подвинуть). Ну и потом двигаем по кривой рельсы.

Логично, что тележки поезда я буду двигать в направлении носа поезда. А вагоны буду двигать в направлении, в котором буду двигать предыдущий вагон (иди поезд для первого вагона). Как-то так.

#8
10:30, 9 апр. 2018

По логике у рельса должен быть интерфейс такого вида
interface Rails{
  bool overturning(double trainvelocity,double trainmasscenterHeigth,double trainmass);
  void CalculateWheelPositions(double [] pathpositions,Vector3 [] outputpoints);
  bool Move(double position,double moveaddition, out Rails nextpart, out double nextposition);
}
//позиция передаеться внутрь в виде расстояния от начала рельса
//движение вычисляеться через Move, если участок кончился, то переходит на следующий и оставляет в nextposition позицию относительно него
//тележки просто меняют свою позицию вместе с паровозом пока не прицеплены.
//положение вагона считаеться по колесам.
//overturning отвечает за сход с рельсов в соотвествии с характеристиами участка, если произошел, то дальше вагон едет по физике без участия рельсов.

относительность требеться для ветвящихся и кольцевых участков. Вторую рельсу можно не считать

#9
11:41, 9 апр. 2018

Сплайны?

#10
23:32, 11 апр. 2018

А почему бы  вагоны не привязать друг к другу джойнтами, а ведущий вагон или тележку двигать или что там ведущие , двигать чисто  физический в точку  которая задает абсолютный путь движения , тобишь  (точка которая как бы двигается по абсолютном пути , с нужной скоростью , и делает онна это не физичский  )
.
Car = это типа тележка или что там ведущие.
-----------------------------------------------------------------------------
PointPos = точка в которую будет физический стремиться физичский объект Car.
Car->Position = центр масс Car
Car->Velocity = скорость линейного движения Car
Car->massa = масса телеги Car
CoffPos  и coffVel кофициент подбираемые с помощью бубна,

Car->applyImpulse( dt * (pointPos - Car->Position) * Car->massa * coffPos + dt * Car->Velocity * coffVel  );
Если на условный Car не будут воздействовать какие-то силы, то кар будет стремиться попасть в точку pointPos  при таком applyImpulse , а вот саму эту точку pointPos двигать по абсолютной траектории, то бишь двигать к ближайшей точки или двигать точку по траектории  каждого  участка рельс , ну короче манипулировать этой точкой как угодно, из нужной скоростю  !
Соотношения коэффициентов CoffPos и coffVel как бы задаёт вязкость как будто среды, от этого зависит как сильно будет гаситься инерция при стримлении Car  к точки PointPos  , также на эти кофициенты можно наложыть фильтр чистот !
P.S: этот метод правильным с точки зрения физики!

#11
13:06, 18 апр. 2018

Трудно придумать что-то, чего еще не делали. Парни верно говорят, ответ на данный вопрос: сплайны. Почитай про кривые Безье (кривые Бернштейна). Начиная отсюда, например https://gamedev.ru/code/articles/bezier_curve_editor
Смысл в том, что путь движения должен быть описан математически. Это сплайн, вдоль которого поедет поезд (что достаточно близко к реальной модели движения поездов).
Если же принцип задачи это физическое моделирование, то сплайны не подойдут, но, мне кажется, что вопрос не в построении реальной физической модели, мы же говорим про игру. Сплайны как раз то, что нужно. Указываешь только время, пройденное (точнее пройденный путь в диапазоне от 0 до 1) и получаешь нужную координату.

Эти решается первая проблема: положение вагона с течением времени. Остается одна проблема - ориентация.

Вагон должен стоять параллельно пути рельсов в данной координате. Если вагоны по отношению к поворотным участкам рельсов малы (как в жизни, очень плавные повороты у рельсов, в отличии, например, от GTA IV, где поезд дергает при поворотах резких), то проблем тут не будет. А для вычисления достаточно воспользоваться простейшими формулами типа скалярного произведения векторов (что тоже легко гуглится).

Если нужны ответы в виде строк кода, то нужны и вопросы с примерами.

ПрограммированиеФорумФизика

Тема в архиве.