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

Вернуться   Форум Flasher.ru > Блоги > ZackMercury

Оценить эту запись

Оптимизация движения по окружности

Запись от ZackMercury размещена 26.12.2018 в 21:06
Обновил(-а) ZackMercury 26.12.2018 в 21:18

Нормализация вектора включает извлечение квадратного корня для получения его длины и деление компонентов на его длину. Корни - чуть(почти в 2 раза) менее затратная операция, чем тригонометрия. Да, мы делаем её дважды, точно также, как дважды мы вызываем тригонометрическую функцию (sin - 1 и cos - 2).
Поэтому наш алгоритм должен работать в 2 раза более производительно, чем использование тригонометрической функции.

Однако, возможно улучшить производительность ещё в 2 раза, отказавшись от корней в главном цикле.
Делать такое можно только при неизменной скорости вращения, но то, что мы получили - это вращение без использования корней и тригонометрии в основном цикле.
Код AS3:
var greenBallCoords:Point = new Point(greenBall.x, greenBall.y);
var r:Point = new Point();
var v:Point = new Point();
 
const speed:Number = 5;
 
//The distance between 2 balls
var radiusOfRotation:Number = Math.sqrt(Math.pow(blueBall.x - greenBall.x,2) + Math.pow(blueBall.y - greenBall.y,2));
 
//defining the radius vector
r.x = blueBall.x;
r.y = blueBall.y;
r = r.subtract(greenBallCoords);
//defining the velocity vector as a radius vector, rotated counterclockwise by 90 deg
v.x = r.y;
v.y = -r.x;
//shrinking its length to the speed
v.normalize(speed);
 
blueBall.x += v.x;
blueBall.y += v.y;
 
//getting the r1 length
var newRadius:Number = Math.sqrt(Math.pow(blueBall.x - greenBall.x,2) + Math.pow(blueBall.y - greenBall.y,2));
//this is what makes our life easier: we can normalize by dividing by the new radius vector length and multiply by the radiusOfRotation at the same time
var rOverR1:Number = radiusOfRotation / newRadius;
//same goes with the velocity vector, we can normalize it by dividing it by the radiusOfRotation length and multiplying by the speed itself
var speedOverRadius:Number = speed / radiusOfRotation;
 
//here goes our main loop
function update(e:Event = null):void
{
	r.x = blueBall.x;
	r.y = blueBall.y;
	r = r.subtract(greenBallCoords);	
	v.x = r.y;
	v.y = -r.x;
	v.x *= speedOverRadius;
	v.y *= speedOverRadius;
 
	blueBall.x += v.x;
	blueBall.y += v.y;
 
	var r1:Point = new Point(blueBall.x, blueBall.y);
	r1 = r1.subtract(greenBallCoords);
	r1.x *= rOverR1;
	r1.y *= rOverR1;
	r1 = r1.add(greenBallCoords);
	blueBall.x = r1.x;
	blueBall.y = r1.y;
}
addEventListener(Event.ENTER_FRAME, update);
Можно упростить ещё больше, но пока что в этом нет необходимости.
circularButNotHarmonicMotion.swf   (1.1 Кб)
Вложения
Тип файла: swf circularButNotHarmonicMotion.swf (1.1 Кб, 30 просмотров)
Всего комментариев 0

Комментарии

 

 


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


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