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

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

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

Регистрация: Jan 2014
Сообщений: 6
По умолчанию Тригонометрия. Ошибка в условии изменения дельты угла в радиальной системе координат.

Добрый день!

Проблема в следующем:

В прикрепленном ролике подвижный корабль (ship) летит к синему указателю цели (pointer), который перемещается вокруг неподвижного корабля (target).
Мне нужно, чтобы при значении угла α < 90 градусов (т.е. Math.PI/2) синий указатель менял направление перемещения на противоположное.
Угол α на картинке обозначен.

Вот код функции ответственной за перемещение указателя:

Код AS3:
function MovePointer(ship:Object, targ:Object, point:Object, R:Number, DAngle:Number):Number
{
	var angle = Math.atan2(point.y - targ.y, point.x - targ.x);
 
	if ( Math.abs( Math.PI-( angle - (Math.PI+Math.atan2(ship.y - targ.y, ship.x - targ.x)) ) ) < Math.PI/2 )
	{
		DAngle=-DAngle;
	}
 
	angle += DAngle;
 
 
	point.x = targ.x + R * Math.cos(angle);
	point.y = targ.y + R * Math.sin(angle);
 
	return DAngle;
}
Название: Тригонометрия.png
Просмотров: 471

Размер: 7.9 Кб

StarControl.rar

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

Регистрация: Jan 2014
Сообщений: 6
Изменил алгоритм на:

Код AS3:
function MovePointer(ship:Object, targ:Object, point:Object, R:Number, DAngle:Number):Number
{
	var angle = Math.atan2(point.y - targ.y, point.x - targ.x);
	trace (Math.atan2(ship.y - targ.y, ship.x - targ.x) - angle);
 
	if (
		(
		 Math.abs( Math.atan2(ship.y - targ.y, ship.x - targ.x) - angle ) < (Math.PI/2 + 2*Math.abs(DAngle))
		 	)
				||
		(
		 Math.abs( Math.atan2(ship.y - targ.y, ship.x - targ.x) - angle ) > (Math.PI*3/2 - 2*Math.abs(DAngle)) 
			)
		)
	{
		DAngle=-DAngle;		
	}
 
	angle += DAngle;
 
 
	point.x = targ.x + R * Math.cos(angle);
	point.y = targ.y + R * Math.sin(angle);
 
	return DAngle;
}
-стал скакать как надо но все равно после определенного момента глючит (см. новое приложение):
StarControl.rar

Старый 13.01.2014, 00:33
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 3  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
Примерно так должно быть:
Код AS3:
const product : Number = (point.y - targ.y) * (ship.y - targ.y) + (point.x - targ.x) * (ship.x - targ.x);
if (product > 0) {
  DAngle = -DAngle;
}
Вроде бы со знаком сравнения не напутал.
Вычисление угла и вращение стоит оставить ваше.

Старый 13.01.2014, 00:45
InSelecto вне форума Посмотреть профиль Отправить личное сообщение для InSelecto Найти все сообщения от InSelecto
  № 4  
Ответить с цитированием
InSelecto

Регистрация: Jan 2014
Сообщений: 6
Цитата:
Сообщение от maxkar Посмотреть сообщение
Примерно так должно быть:
Код AS3:
const product : Number = (point.y - targ.y) * (ship.y - targ.y) + (point.x - targ.x) * (ship.x - targ.x);
if (product > 0) {
  DAngle = -DAngle;
}
Вроде бы со знаком сравнения не напутал.
Вычисление угла и вращение стоит оставить ваше.
Красота, но все равно после 2го отскока глючит: см. мой пост выше с новым приложением - там именно эта ситуация и с вашим алгоритмом.

Как вы к этому выражению пришли? "(point.y - targ.y) * (ship.y - targ.y) + (point.x - targ.x) * (ship.x - targ.x)"
Если не сложно - можно фото вычислений на бумаге? Или ссыль какую)


Последний раз редактировалось InSelecto; 13.01.2014 в 00:55.
Старый 13.01.2014, 01:15
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 5  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
Цитата:
Сообщение от InSelecto Посмотреть сообщение
Красота, но все равно после 2го отскока глючит: см. мой пост выше с новым приложением - там именно эта ситуация и с вашим алгоритмом.
А зачем ваш метод возвращает DAngle? Вы его там потом ничему заново не присваиваете и в новую итерацию не передаете? У меня подозрения, что угол потом резко (за счет движения корабля) попадает в область "< 90 градусов" и выйти из нее уже не может (так и меняется на противоположный).

Мне кажется, нужно менять алгоритм. Пока угол тупой - target движется в предыдущем направлении. Если же угол острый (или прямой) - затупляем его вне зависимости от предыдущего движения. Для этого смотрим на знак

Код AS3:
if (product < 0) {
  const crossProduct : Number = (point.y - targ.y) * (ship.x - targ.x) - (point.x - targ.x) * (ship.y - targ.y);
  DAngle = (crossProduct <= 0 ? -1 : 1) * Math.abs(DAngle);
}
Может быть, там условие ">=0" вместо "<=0".

Цитата:
Сообщение от InSelecto Посмотреть сообщение
Как вы к этому выражению пришли? Или ссыль какую)
Не люблю считать в углах, если все можно посчитать в векторах. В углах очень много граничных случаев. Ваша задача проверки угла на тупизну эквивалентна проверке знака косинуса угла. А проверка знака косинуса угла эквивалентна проверке знака скалярного произведения векторов (скалярное произведение равно произведению длин на косинус угла между ними). Формула product - формула скалярного произведения векторов по их коордиантам в ортонормированном базисе. Формула crossProduct - "длина" векторного произведения векторов, ее знак определяет направление поворота между векторами (в каком случае положительно - не помню). Т.е. при изменении порядка веткоров "векторное произведение" поменяет знак. Пока точные углы не нужны, векторного произведения вполне достаточно для качественной оценки (поворот по/против часовой стрелки).

Вся необходимая теория - в учебниках по линейной алгебре (первый курс университетов).

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

Регистрация: Jan 2014
Сообщений: 6
Цитата:
Сообщение от maxkar Посмотреть сообщение
Не люблю считать в углах, если все можно посчитать в векторах. В углах очень много граничных случаев. Ваша задача проверки угла на тупизну эквивалентна проверке знака косинуса угла. А проверка знака косинуса угла эквивалентна проверке знака скалярного произведения векторов (скалярное произведение равно произведению длин на косинус угла между ними). Формула product - формула скалярного произведения векторов по их коордиантам в ортонормированном базисе. Формула crossProduct - "длина" векторного произведения векторов, ее знак определяет направление поворота между векторами (в каком случае положительно - не помню). Т.е. при изменении порядка веткоров "векторное произведение" поменяет знак. Пока точные углы не нужны, векторного произведения вполне достаточно для качественной оценки (поворот по/против часовой стрелки).

Вся необходимая теория - в учебниках по линейной алгебре (первый курс университетов).
Уже нашел) Читаю.

Добавлено через 11 минут
Цитата:
Сообщение от maxkar Посмотреть сообщение
А зачем ваш метод возвращает DAngle? Вы его там потом ничему заново не присваиваете и в новую итерацию не передаете? У меня подозрения, что угол потом резко (за счет движения корабля) попадает в область "< 90 градусов" и выйти из нее уже не может (так и меняется на противоположный).
Передаю:
Код AS3:
DeltaAngle=MovePointer (Player1, Target1, Pointer1, PointerRadius, DeltaAngle);

Старый 14.01.2014, 22:52
dimarik вне форума Посмотреть профиль Отправить личное сообщение для dimarik Найти все сообщения от dimarik
  № 7  
Ответить с цитированием
dimarik
.
 
Аватар для dimarik

модератор форума
Регистрация: Sep 2003
Адрес: Москва
Сообщений: 4,630
Записей в блоге: 20
Прошу прощения за занудство, но по решению комиссии IEEE от 30.02.1901 года, термин "радиальная" (Система Координат) заменен на полярная (СК).
__________________
Воспитан в TimeZero. Работаю в Mail.ru.

Создать новую тему Ответ Часовой пояс GMT +4, время: 01:29.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

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

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


 


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


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