Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Движение элементов змейкой или поездом по траектории  (Прочитано 10021 раз)
0 Пользователей и 1 Гость смотрят эту тему.
The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« : 08-05-2011 10:56 » 

Привет.
Мне надо реализовать следующее: есть цепочка элементов в двумерной системе координат (x, y).
Элементы эти как вагоны поезда, должны пройти по определённой траектории, неразрывно друг от друга и не влезая друг в друга - в точности как вагоны состава поезда, расстояние должно быть между ними одинаковое.

Траектория это - ломанная линия из отрезков разной длины.  Движение всей цепи равнолинейное, ускорение =0.
По этим отрезкам по очереди интерполирую по t от 0 до 1 позицию каждого элемента.
Чтобы скорость была у всех элементов цепочки одинаковой, параметр, на который я увеличиваю t в цикле, для каждого отрезка разный. Высчитывается он так: dt = speed / длину отрезка.

Но проблема в том, что элементы всё равно отстают друг от друга по ходу движения, виновата в этом, как я думаю, моя реализация следования вагонов за ,"головой". Я интерполирую все элементы по t в цикле, если расстояние до впереди стоящего меньше заданного, то жду, если больше или равно - двигаю.
Но, очевидно, по t надо "двигать" только голову состава, а следующие за ней элементы надо считать как позиция N-1 минус заданное расстояние между вагонами(элементами).

Но как именно это сделать - не могу придумать. Подскажите, пожалуйста.
« Последнее редактирование: 08-05-2011 10:58 от The Nameless One » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 08-05-2011 11:04 » 

опиши закон движения в зависимости от времени - как отдельную функцию. Затем для каждого элемента применяй закон. Сдвиг по времени - это расстояние от головы до элемента , делённое на скорость головы
Записан

The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 08-05-2011 11:15 » 

Алексей1153++,
У меня отдельной ф-ией:

Point Vector2::Lerp(point[n  - 1] - point[n], t);
когда t ранов 0, возвращается point[n  - 1], когда 1, возвращается point[n], 0.5 - середина и т.д.

Для каждого элемента вызывается, только у каждого элемента свой n, который зависит от того, на каком отрезке от сейчас едет. Т.е., например, голова поезда на n+1 отрезке, следующий за ним элемент на n том отрезке, а хвост на n - 1 отрезке.

Т.е. предлагаете параметр t текущего элемента увеличивать на расстояние от головы до элемента , делённое на скорость головы?



Добавлено через 8 минут и 43 секунды:
А можно ещё как-нибудь заставить двигаться точку (x0, y0) к цели (x1, y1), кроме как параметрически по t, чтобы она не промахнулась?

Ну, например, если просто посчитать направление (вектор) к цели и прибавлять к координатам с определённой скоростью, пока не достигнем цели - то в общем случаем мы промахнёмся:

velocity = vectorTarget - vectorPoint;
velocity.Normalize();

while( vectorPoint != vectorTarget)
{
      vectorPoint += velocity * speed;
}

условия цикла с большой вероятностью никогда не будет выполненно, точка "проскочит" свою цель.
« Последнее редактирование: 08-05-2011 11:24 от The Nameless One » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 08-05-2011 11:25 » 

я предлагаю вот что:
Код:
//функция координаты от времени
Point GetPosFromTime(float time);

//функция определения расстояния между точками с индексами n1 и n2
float GetDistance(int n1, int n2));

тогда вывод змейки:
Код:
const float t=...; //текущее время
const float V=...; //скорость головы

for(int i=0; i<N; i++)
{
const int dist=GetDistance(0,i));
Point p= GetPosFromTime(t-dist/V);
//p - координата вывода элемента i
}

само собой, все эти функции - члены класса, инкапсулирующего массив с элементами
« Последнее редактирование: 08-05-2011 11:28 от Алексей1153++ » Записан

The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 08-05-2011 11:30 » 

Спасибо, я сейчас всё опробую.

Добавлено через 3 минуты и 25 секунд:
А что тогда со временем?
Есть просто общее время, не локальное для каждого отрезка? Тогда надо будет написать ф-ию, которая по общему времени вернёт положение по всей ломанной...
« Последнее редактирование: 08-05-2011 11:34 от The Nameless One » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 08-05-2011 12:24 » 

время общее, конечно же. Но никто не мешает задавать смещение времени при вызове функции
Записан

Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 08-05-2011 13:34 » 

Предлагаю очень простой и, как мне кажется, корректный вариант.

Допущения:
  • Каждый "вагон" касается "пути" в двух точках - "голова" и "хвост".
  • "Вагоны" жесткие, т.е не могут деформироваться. Другими словами, длина от "головы" до "хвоста" - константа (при этом не обязательно, чтобы все "вагоны" имели одинаковую длину).
  • Длина "сцепки" = 0, т.е. "голова" следующего "вагона" совпадает с "хвостом" предыдущего.

При этом достаточно отслеживать только движение "головы" первого "вагона". Координаты "головы" второго определяются как точка пересечения ломаной-траектории и окружности с центром в "голове" первого "вагона" и радиусом, равным длине "вагона". И так далее, по всей длине "поезда". Возникнут небольшие трудности с выбором точки пересечения, поскольку окружность пересекает ломаную минимум в двух точках, а то и более, если ломаная сильно петляет, но эти трудности вполне преодолимы.

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

Понятно на словах или нужны поясняющие иллюстрации?
« Последнее редактирование: 08-05-2011 14:29 от Dale » Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 08-05-2011 14:24 » 

Предельно понятно, спасибо!
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 08-05-2011 14:48 » 

А почему бы каждому вагону, когда он делает шаг вперёд, не передавать информацию о своём прежнем местоположении следующему вагону? Для того, чтобы следующий вагон занял именно эту позицию. Тогда достаточно двигать голову, а хвост будет тянуться сам вне зависимости от формы траектории, скорости движения состава.

Естественно, это предполагает, что сцепка вагонов жёсткая.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 08-05-2011 15:14 » 

Dimka,
Потому что расстояние между прежним местоположением и текущим у вагона будет много меньше длины вагона.
« Последнее редактирование: 08-05-2011 15:16 от The Nameless One » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 08-05-2011 17:07 » 

The Nameless One, но форма вагона ведь известна. А значит по координатам его головы однозначно определяются координаты его хвоста - именно в этом районе находится голова следующего. Размеры вагонов не имеют ни малейшего значения. Значение имеют их форма и ориентация на плоскости.

P.S. Вообще у меня складывается впечатление, что речь идёт не о вагонах, а о чём-то вроде графика Ганта, где связанные порядком задачи "ездят" целыми группами при изменениях.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 08-05-2011 19:08 » 

Dimka, звучит хорошо, но у меня очень много сторонних факторов, сразу всё не прикинешь. Может сработать. Завтра попробую и этот вариант.
Спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines