![]() |
Повернуть объект Nое число раз
Возникла небольшая проблемка, а именно: при повороте объекта на угол формируемый некторым вектором, объект поворачивается до 2П, далее угол скидывается на -2П, и плавно уходит в ноль. Цикл повторяется, объект крутиться.
Только это ая-яй как плохо, ибо нужно чтоб крутилось от -nП до nП (требуется знать сколько витков намоталось или наоборот размоталось). На сегодняшний день, решение достаточно простое, есть некая переменная к которой прибавляется либо отнимается шаг угла. Сей алгоритм в некторых случаях уходит в погрешность и со временем вырастает в серьёзную проблему... Может быть кто-нибудь с таким сталкивался и красиво решил всё это дело?... |
ммм... ну ведь rotation это тоже некоторая переменная типа Number, и точность её не выше точности любой другой переменной типа Number. Ну ладно, геттер это, но суть от этого не меняется.
Проблема тут не в другой переменной, а в том, что шаг угла прибавляется итеративно, и погрешность накапливается. Так будет не только во флэше, но и в любой другой системе с ограниченной памятью. Поэтому подходить нужно с другой стороны: пусть угол поворота в момент времент t вычисляется как a*t + b. Теперь запоминаем время начала вращения, и в каждом кадре вычисляем прошедшее с этого момента время. Для всего этого есть глобальная функция getTimer(). Ну а далее, думаю, понятно :) |
Если значение с 2Пи скидывается на минус 2Пи, это, как мне кажется, ошибка алгоритма уже. По поводу накопления ошибки, это конечно возможно. Если вы крутите объект туда сюда раз эдак 10^8. Тогда может и накопиться. А в вашем случае, опять же, думаю что навран алгоритм.
А что конкретно и как крутится? Как вариант Код AS3:
|
proxiServer, вы забыли учесть, что прибавление угла происходит в каждом кадре, а их 30 в секунду. Так что ошибка очень даже накапливается, можете проверить.
Поэтому, если важно, чтобы объект не просто крутился (перемещался), а оказывался в определённый момент в определённом положении, то про последовательное прибавление угла (координаты) нужно забыть. |
можно сохранять угол поворота в отдельной переменой в градусах, и проводить операции тоже в градусах, с целыми значениями, а потом при применении к обьекту заранее вычисленного угла поворота переводить в радианы...
|
Да зачем же все эти ухищрения? Всё ж просто:
Код AS3:
|
SamFR, могу поверить) но не буду. там ей накапливаться негде. либо ее порядок настолько мал, что 30 лет будете крутить и может на пол-градуса ошибетесь. Врет алгоритм. Ну или пример покажите пожалуйста. Может какие особенности самого флеша.
|
Код AS3:
Скажите, что вы будете делать, если нужно, чтобы за 3, например, секунды, объект повернулся на N*PI радиан? Ведь частота кадров ролика не всегда равна заданному числу (а точнее, почти всегда не равна). Мало того, она непостоянна по времени, и зависит от того, сколько заняла отрисовка и выполнение скрипта. |
Цитата:
Еще раз про задачу. Пользователь накручивает некоторый вектор Nое кол-во раз, может совершить хоть 20000 витков, и в этоге получится какой-то бешеный угол в 34234Пи+отступ И вот на этот угол совершенно не торопясь будет поворачиваться объект. (r+=(endR-r)*speed) Причём чем больше кол-во витков тем "туже" идёт поворот (скорость уменьшим), но это уже лирика =) P.s. немного пояснений: нет проблемы от -180 до 180, преобразовать это не составляет труда, есть проблема, что после 360 идёт 0 а не 361 и т.д. Ибо при "мгновенном" повороте что 360 что 0 - одно и тоже, а при динамическом, думаю понятно как всё происходит. |
Цитата:
Полное время нужно, во-первых, для того, чтобы привести текущее время к заданному отрезку отрезку (в моём примере (-1, 1), можно к любому другому, как вам удобно). А, во-вторых, чтобы определить момент окончания вращения. Таким образом, в каждом кадре нужно проверять текущее время вращения, которое равно getTimer() - t0. Вычитать t0 нужно для того, чтобы время шло с 0, так как getTimer() возвращает время, прошедшее с момента запуска плеера. Как только величина getTimer() - t0 превзойдёт T, то в последний раз вычисляем угол для времени T, а затем заканчиваем анимацию (путём отписывания от события ENTER_FRAME, либо установки флага, как вам больше нравится). Цитата:
Можно (и даже лучше) взять не такую формулу, а что-то типа вашОбъект.rotation = angle0 + (angle1 – angle0)*t/T, где angle0 – начальный угол поворота в радианах, angle1 – конечный угол поворота в радианах, t = getTimer() – t0 задаёт текущее время. Цитата:
|
| Часовой пояс GMT +4, время: 19:47. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.