Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 06.11.2009, 03:17
me2 вне форума Посмотреть профиль Отправить личное сообщение для me2 Найти все сообщения от me2
  № 1  
Ответить с цитированием
me2

Регистрация: Jan 2008
Сообщений: 84
По умолчанию Повернуть объект Nое число раз

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

Старый 06.11.2009, 04:24
SamFR вне форума Посмотреть профиль Отправить личное сообщение для SamFR Посетить домашнюю страницу SamFR Найти все сообщения от SamFR
  № 2  
Ответить с цитированием
SamFR

Регистрация: Mar 2008
Адрес: Ростов-на-Дону
Сообщений: 354
ммм... ну ведь rotation это тоже некоторая переменная типа Number, и точность её не выше точности любой другой переменной типа Number. Ну ладно, геттер это, но суть от этого не меняется.

Проблема тут не в другой переменной, а в том, что шаг угла прибавляется итеративно, и погрешность накапливается. Так будет не только во флэше, но и в любой другой системе с ограниченной памятью. Поэтому подходить нужно с другой стороны: пусть угол поворота в момент времент t вычисляется как a*t + b. Теперь запоминаем время начала вращения, и в каждом кадре вычисляем прошедшее с этого момента время. Для всего этого есть глобальная функция getTimer(). Ну а далее, думаю, понятно


Последний раз редактировалось SamFR; 06.11.2009 в 04:28.
Старый 06.11.2009, 10:37
proxiServer вне форума Посмотреть профиль Отправить личное сообщение для proxiServer Найти все сообщения от proxiServer
  № 3  
Ответить с цитированием
proxiServer
 
Аватар для proxiServer

Регистрация: Jun 2006
Сообщений: 400
Если значение с 2Пи скидывается на минус 2Пи, это, как мне кажется, ошибка алгоритма уже. По поводу накопления ошибки, это конечно возможно. Если вы крутите объект туда сюда раз эдак 10^8. Тогда может и накопиться. А в вашем случае, опять же, думаю что навран алгоритм.

А что конкретно и как крутится?

Как вариант
Код AS3:
 
// проблема с переходом -180...180
                     if (angle>180){
                            angle-=360;
                     } else if (angle<-180){
                            angle+=360;
                     }
Решение взял из статьи мерлина про игру с астеройдами. Она прилеплена.


Последний раз редактировалось proxiServer; 06.11.2009 в 12:17.
Старый 06.11.2009, 16:25
SamFR вне форума Посмотреть профиль Отправить личное сообщение для SamFR Посетить домашнюю страницу SamFR Найти все сообщения от SamFR
  № 4  
Ответить с цитированием
SamFR

Регистрация: Mar 2008
Адрес: Ростов-на-Дону
Сообщений: 354
proxiServer, вы забыли учесть, что прибавление угла происходит в каждом кадре, а их 30 в секунду. Так что ошибка очень даже накапливается, можете проверить.

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


Последний раз редактировалось SamFR; 06.11.2009 в 16:27.
Старый 06.11.2009, 16:31
dsQuadro вне форума Посмотреть профиль Отправить личное сообщение для dsQuadro Посетить домашнюю страницу dsQuadro Найти все сообщения от dsQuadro
  № 5  
Ответить с цитированием
dsQuadro
 
Аватар для dsQuadro

Регистрация: Feb 2008
Адрес: Москва
Сообщений: 238
Отправить сообщение для dsQuadro с помощью ICQ
можно сохранять угол поворота в отдельной переменой в градусах, и проводить операции тоже в градусах, с целыми значениями, а потом при применении к обьекту заранее вычисленного угла поворота переводить в радианы...

Старый 06.11.2009, 16:41
SamFR вне форума Посмотреть профиль Отправить личное сообщение для SamFR Посетить домашнюю страницу SamFR Найти все сообщения от SamFR
  № 6  
Ответить с цитированием
SamFR

Регистрация: Mar 2008
Адрес: Ростов-на-Дону
Сообщений: 354
Да зачем же все эти ухищрения? Всё ж просто:

Код AS3:
//перед началом вращения
 
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 в конце
Таким же макаром можно, при желании, заставить угол изменяться по синусоиде, например. И про накопление погрешности можно забыть.

Старый 06.11.2009, 19:36
me2 вне форума Посмотреть профиль Отправить личное сообщение для me2 Найти все сообщения от me2
  № 7  
Ответить с цитированием
me2

Регистрация: Jan 2008
Сообщений: 84
Цитата:
Сообщение от SamFR Посмотреть сообщение
Да зачем же все эти ухищрения? Всё ж просто:

Код AS3:
//перед началом вращения
 
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 в конце
Таким же макаром можно, при желании, заставить угол изменяться по синусоиде, например. И про накопление погрешности можно забыть.
К чему-то подобному бесконечно стремятся мои умозаключения. Не совсем понятен T=10000; чуть подробней можно?

Еще раз про задачу.
Пользователь накручивает некоторый вектор Nое кол-во раз, может совершить хоть 20000 витков, и в этоге получится какой-то бешеный угол в 34234Пи+отступ
И вот на этот угол совершенно не торопясь будет поворачиваться объект. (r+=(endR-r)*speed)
Причём чем больше кол-во витков тем "туже" идёт поворот (скорость уменьшим), но это уже лирика =)

P.s.
немного пояснений: нет проблемы от -180 до 180, преобразовать это не составляет труда, есть проблема, что после 360 идёт 0 а не 361 и т.д.
Ибо при "мгновенном" повороте что 360 что 0 - одно и тоже, а при динамическом, думаю понятно как всё происходит.

Старый 06.11.2009, 23:20
SamFR вне форума Посмотреть профиль Отправить личное сообщение для SamFR Посетить домашнюю страницу SamFR Найти все сообщения от SamFR
  № 8  
Ответить с цитированием
SamFR

Регистрация: Mar 2008
Адрес: Ростов-на-Дону
Сообщений: 354
Цитата:
Сообщение от me2 Посмотреть сообщение
Не совсем понятен T=10000; чуть подробней можно?
T – это время, в течение которого будет продолжаться вращение (назовём его полное время). Так как getTimer() даёт время в миллисекундах, то для удобства (чтобы всё время не делить начальное время на 1000) полное время также задаётся в миллисекундах.

Полное время нужно, во-первых, для того, чтобы привести текущее время к заданному отрезку отрезку (в моём примере (-1, 1), можно к любому другому, как вам удобно). А, во-вторых, чтобы определить момент окончания вращения. Таким образом, в каждом кадре нужно проверять текущее время вращения, которое равно getTimer() - t0. Вычитать t0 нужно для того, чтобы время шло с 0, так как getTimer() возвращает время, прошедшее с момента запуска плеера. Как только величина getTimer() - t0 превзойдёт T, то в последний раз вычисляем угол для времени T, а затем заканчиваем анимацию (путём отписывания от события ENTER_FRAME, либо установки флага, как вам больше нравится).

Цитата:
Сообщение от me2 Посмотреть сообщение
Еще раз про задачу.
Пользователь накручивает некоторый вектор Nое кол-во раз, может совершить хоть 20000 витков, и в этоге получится какой-то бешеный угол в 34234Пи+отступ
И вот на этот угол совершенно не торопясь будет поворачиваться объект.
Смотрим пример, который я вам приводил. Задаём N, исходя из того, сколько витков пользователь совершил (N не обязательно должно быть целым). Засекаем t0 и запускаем анимацию по тем формулам, что я привёл. Как только перешли за T, поворачиваем объект на угол, вычисленный для времени T и останавливаем анимацию. По-моему, всё просто

Можно (и даже лучше) взять не такую формулу, а что-то типа вашОбъект.rotation = angle0 + (angle1 – angle0)*t/T, где angle0 – начальный угол поворота в радианах, angle1 – конечный угол поворота в радианах, t = getTimer() – t0 задаёт текущее время.

Цитата:
Сообщение от me2 Посмотреть сообщение
Причём чем больше кол-во витков тем "туже" идёт поворот (скорость уменьшим), но это уже лирика =)
Это как раз-таки можно сделать, задавая перед запуском анимации T в зависимости от нужного количества витков. Чем больше будет полное время вращения, тем меньше будет скорость, естественно.


Последний раз редактировалось SamFR; 06.11.2009 в 23:33.
Старый 09.11.2009, 18:40
me2 вне форума Посмотреть профиль Отправить личное сообщение для me2 Найти все сообщения от me2
  № 9  
Ответить с цитированием
me2

Регистрация: Jan 2008
Сообщений: 84
Где то я видимо объясняю криво.
Смотрим пример, который я вам приводил. Задаём N, исходя из того, сколько витков пользователь совершил
[/quote]
Ведь в этом и проблема =) Зная N, можно устанавливать угол например так: currentAngle+2Pi*n и не нужны эти сложности с таймерами и прочим.
Вычислить максимально точно N у меня не получается (стоит очень быстро покрутить мышкой и все слетает) отсюда погрешности и прочее.

Перегружать rotation как то не охота =) он не виноват, ему смело можно указать rotation=720

Старый 09.11.2009, 21:50
SamFR вне форума Посмотреть профиль Отправить личное сообщение для SamFR Посетить домашнюю страницу SamFR Найти все сообщения от SamFR
  № 10  
Ответить с цитированием
SamFR

Регистрация: Mar 2008
Адрес: Ростов-на-Дону
Сообщений: 354
Тогда
Цитата:
Сообщение от SamFR Посмотреть сообщение
Можно (и даже лучше) взять не такую формулу, а что-то типа вашОбъект.rotation = angle0 + (angle1 – angle0)*t/T, где angle0 – начальный угол поворота в радианах, angle1 – конечный угол поворота в радианах, t = getTimer() – t0 задаёт текущее время.
Или проблема в том, как узнать, сколько раз нужно прокрутить объект между angle0 и angle1 (если принять, что оба угла лежат между 0 и 2*PI)? Здесь однозначного решения нет.

Можно смотреть, сколько раз object.rotation перешёл значения PI/2 и -PI/2, и в какой последовательности. И на основе этого предполагать, сколько было сделано полных оборотов.

Либо изначально количество оборотов задавать не вращением объекта, а, например, перетягиванием ползунка (вводом числа). Тут уж всё зависит от специфики.

Но, как мне кажется, общая схема, если не получается точно определить количество оборотов, такова: узнали angle0 (object.rotation перед началом вращения объекта пользователем) и angle1 (object.rotation в конце вращения объекта пользователем), а также [N], то есть количество полных оборотов. Далее к angle0 и angle1 прибавили (вычли) период (то есть 2*PI) столько раз, чтобы оба угла лежали на полуотрезке [0; 2*PI). Далее к angle1 прибавали количество полных оборотов, умноженное на 2*PI (то есть angle1 += [N]*2*PI). Далее вращаем.


Последний раз редактировалось SamFR; 09.11.2009 в 22:17.
Создать новую тему Ответ Часовой пояс GMT +4, время: 19:58.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 19:58.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.