|
|
|||||
Регистрация: Jan 2008
Сообщений: 84
|
Повернуть объект Nое число раз
Возникла небольшая проблемка, а именно: при повороте объекта на угол формируемый некторым вектором, объект поворачивается до 2П, далее угол скидывается на -2П, и плавно уходит в ноль. Цикл повторяется, объект крутиться.
Только это ая-яй как плохо, ибо нужно чтоб крутилось от -nП до nП (требуется знать сколько витков намоталось или наоборот размоталось). На сегодняшний день, решение достаточно простое, есть некая переменная к которой прибавляется либо отнимается шаг угла. Сей алгоритм в некторых случаях уходит в погрешность и со временем вырастает в серьёзную проблему... Может быть кто-нибудь с таким сталкивался и красиво решил всё это дело?... |
|
|||||
Регистрация: Mar 2008
Адрес: Ростов-на-Дону
Сообщений: 354
|
ммм... ну ведь rotation это тоже некоторая переменная типа Number, и точность её не выше точности любой другой переменной типа Number. Ну ладно, геттер это, но суть от этого не меняется.
Проблема тут не в другой переменной, а в том, что шаг угла прибавляется итеративно, и погрешность накапливается. Так будет не только во флэше, но и в любой другой системе с ограниченной памятью. Поэтому подходить нужно с другой стороны: пусть угол поворота в момент времент t вычисляется как a*t + b. Теперь запоминаем время начала вращения, и в каждом кадре вычисляем прошедшее с этого момента время. Для всего этого есть глобальная функция getTimer(). Ну а далее, думаю, понятно Последний раз редактировалось SamFR; 06.11.2009 в 04:28. |
|
|||||
Регистрация: Jun 2006
Сообщений: 400
|
Если значение с 2Пи скидывается на минус 2Пи, это, как мне кажется, ошибка алгоритма уже. По поводу накопления ошибки, это конечно возможно. Если вы крутите объект туда сюда раз эдак 10^8. Тогда может и накопиться. А в вашем случае, опять же, думаю что навран алгоритм.
А что конкретно и как крутится? Как вариант Решение взял из статьи мерлина про игру с астеройдами. Она прилеплена. Последний раз редактировалось proxiServer; 06.11.2009 в 12:17. |
|
|||||
Регистрация: Mar 2008
Адрес: Ростов-на-Дону
Сообщений: 354
|
proxiServer, вы забыли учесть, что прибавление угла происходит в каждом кадре, а их 30 в секунду. Так что ошибка очень даже накапливается, можете проверить.
Поэтому, если важно, чтобы объект не просто крутился (перемещался), а оказывался в определённый момент в определённом положении, то про последовательное прибавление угла (координаты) нужно забыть. Последний раз редактировалось SamFR; 06.11.2009 в 16:27. |
|
|||||
можно сохранять угол поворота в отдельной переменой в градусах, и проводить операции тоже в градусах, с целыми значениями, а потом при применении к обьекту заранее вычисленного угла поворота переводить в радианы...
|
|
|||||
Регистрация: Mar 2008
Адрес: Ростов-на-Дону
Сообщений: 354
|
Да зачем же все эти ухищрения? Всё ж просто:
//перед началом вращения var t0:uint = getTimer(); //момент начала вращения var T:uint = 10000; //полное время вращения (в мс.) //каджый кадр var t:Number = 2*(getTimer() - t0)/T - 1; //от -1 (в начале вращения) до 1 (в конце) object.rotation = N*t*Math.PI; //от -N*PI в начале вращения до N*PI в конце |
|
|||||
Регистрация: Jun 2006
Сообщений: 400
|
SamFR, могу поверить) но не буду. там ей накапливаться негде. либо ее порядок настолько мал, что 30 лет будете крутить и может на пол-градуса ошибетесь. Врет алгоритм. Ну или пример покажите пожалуйста. Может какие особенности самого флеша.
|
|
|||||
Регистрация: Mar 2008
Адрес: Ростов-на-Дону
Сообщений: 354
|
Да, ошибка маленькая, но основная проблема не в этом.
Скажите, что вы будете делать, если нужно, чтобы за 3, например, секунды, объект повернулся на N*PI радиан? Ведь частота кадров ролика не всегда равна заданному числу (а точнее, почти всегда не равна). Мало того, она непостоянна по времени, и зависит от того, сколько заняла отрисовка и выполнение скрипта. |
|
|||||
Регистрация: Jan 2008
Сообщений: 84
|
Цитата:
Еще раз про задачу. Пользователь накручивает некоторый вектор Nое кол-во раз, может совершить хоть 20000 витков, и в этоге получится какой-то бешеный угол в 34234Пи+отступ И вот на этот угол совершенно не торопясь будет поворачиваться объект. (r+=(endR-r)*speed) Причём чем больше кол-во витков тем "туже" идёт поворот (скорость уменьшим), но это уже лирика =) P.s. немного пояснений: нет проблемы от -180 до 180, преобразовать это не составляет труда, есть проблема, что после 360 идёт 0 а не 361 и т.д. Ибо при "мгновенном" повороте что 360 что 0 - одно и тоже, а при динамическом, думаю понятно как всё происходит. |
|
|||||
Регистрация: Mar 2008
Адрес: Ростов-на-Дону
Сообщений: 354
|
T – это время, в течение которого будет продолжаться вращение (назовём его полное время). Так как getTimer() даёт время в миллисекундах, то для удобства (чтобы всё время не делить начальное время на 1000) полное время также задаётся в миллисекундах.
Полное время нужно, во-первых, для того, чтобы привести текущее время к заданному отрезку отрезку (в моём примере (-1, 1), можно к любому другому, как вам удобно). А, во-вторых, чтобы определить момент окончания вращения. Таким образом, в каждом кадре нужно проверять текущее время вращения, которое равно getTimer() - t0. Вычитать t0 нужно для того, чтобы время шло с 0, так как getTimer() возвращает время, прошедшее с момента запуска плеера. Как только величина getTimer() - t0 превзойдёт T, то в последний раз вычисляем угол для времени T, а затем заканчиваем анимацию (путём отписывания от события ENTER_FRAME, либо установки флага, как вам больше нравится). Цитата:
Можно (и даже лучше) взять не такую формулу, а что-то типа вашОбъект.rotation = angle0 + (angle1 – angle0)*t/T, где angle0 – начальный угол поворота в радианах, angle1 – конечный угол поворота в радианах, t = getTimer() – t0 задаёт текущее время. Это как раз-таки можно сделать, задавая перед запуском анимации T в зависимости от нужного количества витков. Чем больше будет полное время вращения, тем меньше будет скорость, естественно. Последний раз редактировалось SamFR; 06.11.2009 в 23:33. |
Часовой пояс GMT +4, время: 00:26. |
|
« Предыдущая тема | Следующая тема » |
|
|