Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.09.2014, 00:20   #1
Steklo
Новичок
Джуниор
 
Регистрация: 20.09.2014
Сообщений: 1
По умолчанию Время, за которое два объекта пройдут расстояние друг к другу (Unreal Script 2.5)

Пишу AI на UnrealScript, для вычислений нужна функция, которая определяет, через какое время два Pawn'а пройдут определённое расстояние друг к другу. Пока что вычисление упрощённое, по сути условно считается что это две точки в одномерном пространстве. Расстояние между точками равно Dist, соответственно нужно узнать, когда это расстояние будет равно 0. Физика Pawn'ов работает следующим образом - есть скорость, есть ускорение, есть "максимальная скорость". Ускорение влияет на скорость до тех пор, пока она не будет равна "максимальной скорости". Если ускорение равно нулю, скорость падает так же до нуля. В нашей функции мы знаем скорость с которой объекты движутся на момент начала вычисления: StartVel1, StartVel2, "максимальные" скорости, до которых скорость объектов будет доводиться с помощью ускорения: MaxVel1,MaxVel2, текущее расстояние между объектами - Dist. Ищем мы время, через которое объекты столкнутся. Отрицательное время или 0 тоже нужны в качестве результата, вплоть до бесконечностей.

Вот текущая функция, но она работает неправильно (собственно если бы она работала я бы не создал эту тему):

Код:
function float GetDistanceTime(Pawn P, float PawnMoveDir, float PMoveDir, float Dist, optional bool bMinimum)
{
	local float T,GST1,GST2; // Gather Speed Time - время за которое наш актор разовьёт максимальную скорость
	local float StartVel1,StartVel2,MaxVel1,MaxVel2,Accel1,Accel2;
	local float GSDist1,GSDist2;
	local float GSDistBoth,GSDistOne;
	local float A,B,C,D;
	local float PawnMoveDirLen,PMoveDirLen;
	
	if ( PawnMoveDir * PMoveDir <= 0 )
	{
		CLabel = Clabel;
	}
	if ( PawnMoveDir == 0 || PMoveDir == 0 )
	{
		CLabel = Clabel;
	}
	StartVel1 = VSize(Pawn.Velocity);
	StartVel2 = VSize(P.Velocity);
	MaxVel1 = Pawn.GroundSpeed * PawnMoveDir;
	MaxVel2 = P.GroundSpeed * PMoveDir;
	//PawnMoveDirLen = Abs(PawnMoveDir);
	//PawnMoveDir = MaxVel1 - StartVel1;
	//if ( PawnMoveDir != 0 )
	//	PawnMoveDir = PawnMoveDirLen*PawnMoveDir/Abs(PawnMoveDir);
	//PMoveDirLen = Abs(PMoveDir);
	//PMoveDir = MaxVel2 - StartVel2;
	//if ( PMoveDir != 0 )
	//	PMoveDir = PMoveDirLen*PMoveDir/Abs(PMoveDir);
	Accel1 = Pawn.AccelRate * PawnMoveDir;
	Accel2 = P.AccelRate * PMoveDir;
	//T = Dist / (MaxVel1 + MaxVel2);
	
	if ( Accel1 == 0 )
	{
		MaxVel1 = StartVel1;
		GST1 = 0;
		Goto 'CalcGST2';
	}
	GST1 = (MaxVel1 - StartVel1)/Accel1;
CalcGST2:
	if ( Accel2 == 0 )
	{
		MaxVel2 = StartVel2;
		GST2 = 0;
		Goto 'CalcGSDist';
	}
	GST2 = (MaxVel2 - StartVel2)/Accel2;
CalcGSDist:
	GSDist1 = GST1 * GST1 * Accel1 * 0.5;
	GSDist2 = GST2 * GST2 * Accel2 * 0.5;
	if ( GST2 > GST1 )
	{
		class'AdminControlMut'.Static.FExchange(GST1,GST2);
		class'AdminControlMut'.Static.FExchange(GSDist1,GSDist2);
		class'AdminControlMut'.Static.FExchange(Accel1,Accel2);
		class'AdminControlMut'.Static.FExchange(MaxVel1,MaxVel2);
		class'AdminControlMut'.Static.FExchange(StartVel1,StartVel2);
	}
	GSDistOne = GST2 * GST2 * Accel1 * 0.5;
	GSDistBoth = GSDistOne + GSDist2;
	if ( Dist <= GSDistBoth )
	{
		if ( bMinimum ) return 0;
		return GST2;
	}
	GSDistBoth = GSDist1 + GSDist2 + MaxVel2 * (GST1 - GST2);
	if ( Dist <= GSDistBoth )
	{
		if ( bMinimum ) return GST2;
		return GST1;
	}
	Dist -= GSDistBoth;
	T = Dist/(MaxVel1+MaxVel2) + GST1;
	return T;
	/*GST1 = (MaxVel1 - StartVel1)/Accel1;
	GST2 = (MaxVel2 - StartVel2)/Accel2;
	GSDist1 = GST1 * GST1 * Accel1 * 0.5;
	GSDist2 = GST2 * GST2 * Accel2 * 0.5;
	if ( GST2 > GST1 )
	{
		class'AdminControlMut'.Static.FExchange(GST1,GST2);
		class'AdminControlMut'.Static.FExchange(GSDist1,GSDist2);
		class'AdminControlMut'.Static.FExchange(Accel1,Accel2);
		class'AdminControlMut'.Static.FExchange(MaxVel1,MaxVel2);
		class'AdminControlMut'.Static.FExchange(StartVel1,StartVel2);
	}

	GSDistOne = GST2 * GST2 * Accel1 * 0.5;
	GSDistBoth = GSDistOne + GSDist2;
	if ( Dist <= GSDistBoth )
	{
		T = sqrt(Dist * 2 / (Accel1 + Accel2));
		return T;
	}
	StartVel1 = StartVel1 + Accel1 * GST2;
	StartVel2 = MaxVel2;
	T = GST2;
	GST1 -= GST2;
	GST2 = 0;
	GSDist1 = GSDist1; // это ещё старые значения
	GSDist2 += GST1 * MaxVel2;
	if ( Dist <= GSDist1 + GSDist2 )
	{
		Dist -= GSDistBoth;
		A = Accel1 * 0.5;
		B = StartVel2;
		C = -Dist;
		D = B*B - 4*A*C;
		D = sqrt(D);
		GST2 = T;
		T = (-B+D)*0.5/A;
		if ( T < 0 ) T = (-B-D)*0.5/A;
		return GST2 + T;
	}
	Dist -= GSDist1 - GSDist2;
	GST1 += T;
	T = GST1 + Dist / (MaxVel1 + MaxVel2);*/
	return T;
}
Steklo вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогаем друг другу в поиске музыки mihali4 Свободное общение 56 16.02.2017 22:03
Проверить, являются ли данные два слова обращенными друг к другу, то есть первое читается слева направо так же, как второе справа FYNZIK Паскаль, Turbo Pascal, PascalABC.NET 4 10.03.2014 18:23
C++. Две функции в разных файлах мешают друг другу. Крот Помощь студентам 13 21.03.2012 14:56
Привязка окон друг к другу при перетаскивании Alexxx5800 Общие вопросы .NET 2 10.10.2010 20:19