The Nameless One
|
|
« : 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 »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #1 : 08-05-2011 11:04 » |
|
опиши закон движения в зависимости от времени - как отдельную функцию. Затем для каждого элемента применяй закон. Сдвиг по времени - это расстояние от головы до элемента , делённое на скорость головы
|
|
|
Записан
|
|
|
|
The Nameless One
|
|
« Ответ #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 »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
|
|
« Ответ #4 : 08-05-2011 11:30 » |
|
Спасибо, я сейчас всё опробую.
Добавлено через 3 минуты и 25 секунд: А что тогда со временем? Есть просто общее время, не локальное для каждого отрезка? Тогда надо будет написать ф-ию, которая по общему времени вернёт положение по всей ломанной...
|
|
« Последнее редактирование: 08-05-2011 11:34 от The Nameless One »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #5 : 08-05-2011 12:24 » |
|
время общее, конечно же. Но никто не мешает задавать смещение времени при вызове функции
|
|
|
Записан
|
|
|
|
Dale
|
|
« Ответ #6 : 08-05-2011 13:34 » |
|
Предлагаю очень простой и, как мне кажется, корректный вариант. Допущения: - Каждый "вагон" касается "пути" в двух точках - "голова" и "хвост".
- "Вагоны" жесткие, т.е не могут деформироваться. Другими словами, длина от "головы" до "хвоста" - константа (при этом не обязательно, чтобы все "вагоны" имели одинаковую длину).
- Длина "сцепки" = 0, т.е. "голова" следующего "вагона" совпадает с "хвостом" предыдущего.
При этом достаточно отслеживать только движение "головы" первого "вагона". Координаты "головы" второго определяются как точка пересечения ломаной-траектории и окружности с центром в "голове" первого "вагона" и радиусом, равным длине "вагона". И так далее, по всей длине "поезда". Возникнут небольшие трудности с выбором точки пересечения, поскольку окружность пересекает ломаную минимум в двух точках, а то и более, если ломаная сильно петляет, но эти трудности вполне преодолимы. Примерно так же двигался бы реальный поезд с учетом данных допущений. Понятно на словах или нужны поясняющие иллюстрации?
|
|
« Последнее редактирование: 08-05-2011 14:29 от Dale »
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
The Nameless One
|
|
« Ответ #7 : 08-05-2011 14:24 » |
|
Предельно понятно, спасибо!
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #8 : 08-05-2011 14:48 » |
|
А почему бы каждому вагону, когда он делает шаг вперёд, не передавать информацию о своём прежнем местоположении следующему вагону? Для того, чтобы следующий вагон занял именно эту позицию. Тогда достаточно двигать голову, а хвост будет тянуться сам вне зависимости от формы траектории, скорости движения состава.
Естественно, это предполагает, что сцепка вагонов жёсткая.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
The Nameless One
|
|
« Ответ #9 : 08-05-2011 15:14 » |
|
Dimka, Потому что расстояние между прежним местоположением и текущим у вагона будет много меньше длины вагона.
|
|
« Последнее редактирование: 08-05-2011 15:16 от The Nameless One »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #10 : 08-05-2011 17:07 » |
|
The Nameless One, но форма вагона ведь известна. А значит по координатам его головы однозначно определяются координаты его хвоста - именно в этом районе находится голова следующего. Размеры вагонов не имеют ни малейшего значения. Значение имеют их форма и ориентация на плоскости.
P.S. Вообще у меня складывается впечатление, что речь идёт не о вагонах, а о чём-то вроде графика Ганта, где связанные порядком задачи "ездят" целыми группами при изменениях.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
The Nameless One
|
|
« Ответ #11 : 08-05-2011 19:08 » |
|
Dimka, звучит хорошо, но у меня очень много сторонних факторов, сразу всё не прикинешь. Может сработать. Завтра попробую и этот вариант. Спасибо.
|
|
|
Записан
|
|
|
|
|