Форум 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, 16:45
proxiServer вне форума Посмотреть профиль Отправить личное сообщение для proxiServer Найти все сообщения от proxiServer
  № 7  
Ответить с цитированием
proxiServer
 
Аватар для proxiServer

Регистрация: Jun 2006
Сообщений: 400
SamFR, могу поверить) но не буду. там ей накапливаться негде. либо ее порядок настолько мал, что 30 лет будете крутить и может на пол-градуса ошибетесь. Врет алгоритм. Ну или пример покажите пожалуйста. Может какие особенности самого флеша.

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

Регистрация: Mar 2008
Адрес: Ростов-на-Дону
Сообщений: 354
Код AS3:
var t:Number = 0;
 
for(var i:int = 0; i < 600; i++){
	t += 0.01;
}
 
trace(t);
Да, ошибка маленькая, но основная проблема не в этом.

Скажите, что вы будете делать, если нужно, чтобы за 3, например, секунды, объект повернулся на N*PI радиан? Ведь частота кадров ролика не всегда равна заданному числу (а точнее, почти всегда не равна). Мало того, она непостоянна по времени, и зависит от того, сколько заняла отрисовка и выполнение скрипта.

Старый 06.11.2009, 19:36
me2 вне форума Посмотреть профиль Отправить личное сообщение для me2 Найти все сообщения от me2
  № 9  
Ответить с цитированием
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
  № 10  
Ответить с цитированием
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.
Создать новую тему Ответ Часовой пояс GMT +4, время: 00:26.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

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

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


 


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


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