Перейти к содержанию

C# навигационный бот или привет математикам...


Рекомендуемые сообщения

Условия задачи:

1. Есть 3 адреса содержащие координаты X, Y, Z.

2. Есть координаты точки "А", до которой я бы хотел, что бы добрался мой "бот".

3. Есть адрес отвечающий за движение вперед.

4. Есть адреса отвечающие за повороты налево и направо.

Задача:

Добраться до точки "А" используя инструменты из п. 3 и 4 считывая значения адресов из п. 1.

 

Вот такую я штуку хочу реализовать. Но моих знаний в С# пока что маловато, да и с математикой я в разных лодках. А ведь хочется намутить автобегалку/леталку.

Люди добрые помогите кто чем может :-[

Ссылка на комментарий
Поделиться на другие сайты

Только что, Garik66 сказал:

По-моему это уже лучше перенести в раздел "Запросы".

 

А зачем? Мне нужно, что бы люди подсказали какие тут математические операции лучше проводить и как. Я же хочу не полный код готовый, я хочу, что бы люди меня вели в моих потугах.

Я просто не знаю с чего начать.

Ссылка на комментарий
Поделиться на другие сайты

8 минут назад, pachela сказал:

Добраться до точки "А"

Ну если по прямой , то это просто  А = sqrt(x^2+y^2+z^2)  так получится пространственный вектор (прямая) от точки твоего персонажа до точки А

PS ну что-то мне подсказывает , что нужно искать не прямой путь ) 

3 рисунок 

  • Понравилось 1
Ссылка на комментарий
Поделиться на другие сайты

12 минуты назад, IzerodayI сказал:

Ну если по прямой , то это просто  А = sqrt(x^2+y^2+z^2)  так получится пространственный вектор (прямая) от точки твоего персонажа до точки А

PS ну что-то мне подсказывает , что нужно искать не прямой путь ) 

3 рисунок 

Ну мы же говорим о читах? Тем более в которых используется ось Z. Т.е. я планирую делать так: Перешел на определенную высоту и дальше по прямой до точки "А", а потом сбрасываем высоту.

Нашел на просторах гугла, что этот математический метод для вычисления корня квадратного. А тем самым мы получим расстояние.

Пример вот такой вот

float deltaX = x1 - x0;
float deltaY = y1 - y0;
float deltaZ = z1 - z0;

float distance = (float) Math.Sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);

Хорошо, мы вычислим расстояние. Но как нам повернуть в нужную сторону и двигаться? Ведь я знаю координаты точки "А", но не знаю в какой стороне она находится.

Изменено пользователем pachela
Ссылка на комментарий
Поделиться на другие сайты

6 минут назад, pachela сказал:

Перешел на определенную высоту и дальше по прямой до точки "А"

в каких-то играх существует идеальная плоскость(пол(координата Z?)?)? не знаю.....

PS я вижу это так : находимся на беспрепятственной прямой и ищем вектор "А"  и бежим по вектору к точке (то есть все три вектора могут спокойно меняться(и z тоже)).

Ссылка на комментарий
Поделиться на другие сайты

30 минут назад, IzerodayI сказал:

PS я вижу это так : находимся на беспрепятственной прямой и ищем вектор "А"  и бежим по вектору к точке (то есть все три вектора могут спокойно меняться(и z тоже)).

Такс, сейчас опробовал это на практике и вижу, что я понял ход ваших мыслей.

Мы берем в цикле считываем X0, Y0, Z0 и вычисляем вектор. Далее делаем сравнение, если вектор увеличивается, то нужно "повернуть", если вектор уменьшатся, то значит правильным путем мы идем.

Но вот как оптимально выбрать самый кратчайший путь? Ведь я могу к примеру повернуть на 5 градусов и до поры, до времени значение будет уменьшаться и только когда угол станет слишком большой, начнет сначала слишком медленно уменьшаться, а в конечном итоге и увеличиваться.

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, pachela сказал:

Хорошо, мы вычислим расстояние. Но как нам повернуть в нужную сторону и двигаться?

Если имеется карта с препятствиями, то парсить видимую область которая попадает в fov к примеру лучами трассировки или парсить локацию, и если на пути вектора будет препятствие, то высота к примеру будет больше 2 юнитов - куда персонаж не может зайти, то искать обход, где высота будет меньше 2-х. Твой бот будет "видеть" это как-то так:

 

 

1 час назад, pachela сказал:

А ведь хочется намутить автобегалку/леталку.

 

Это тебе дорога в нейронные сети, бот никогда не сможет сам выстраивать оптимальный путь, всегда будет какой-то процент застреваний.

Ссылка на комментарий
Поделиться на другие сайты

Давайте разберемся для начала с прямой, без каких либо препятствий.

Я вот что подумал, может стоит сравнивать 2 вектора, что бы бот повернул в правильном направлении? Ну т.е. запускаю кнопку и бот едет вперед 20 метров, записывает координаты старта и координаты финиша. Строит вектор и умножает это все в 500-1000 раз. А далее бот сравнивает эти 2 вектора и принимает решение, поворачивать или идти прямо.

Или я не в те дебри лезу?

Ссылка на комментарий
Поделиться на другие сайты

14 минуты назад, pachela сказал:

А далее бот сравнивает эти 2 вектора и принимает решение, поворачивать или идти прямо.

Может, проще будет задать алгоритм при котором дистанция всегда должна быть меньше текущей пока не станет равна 0?

Как тут ты писал.

36 минут назад, pachela сказал:

Далее делаем сравнение, если вектор увеличивается, то нужно "повернуть", если вектор уменьшатся, то значит правильным путем мы идем.

Ссылка на комментарий
Поделиться на другие сайты

Только что, kiwipapayamongoose сказал:

Может, проще будет задать алгоритм при котором дистанция всегда должна быть меньше текущей пока не станет равна 0?

я подозреваю, что руками тогда будет проще бежать =).

Хочется же тыкнуть одну кнопку и идти пить чай. А он себе летит к нужной точке, а потом мягкая посадочка =)))

Нашел сейчас вот такой вот ответ, но пока что еще не придумал ему применения =)

Ссылка на комментарий
Поделиться на другие сайты

19 минут назад, pachela сказал:

я подозреваю, что руками тогда будет проще бежать =).

 

Кстати, можно попробовать способ построения вектора самой игры, если поддерживает конечно, например в гта маркер создает кратчайший путь от точки А до точки Б по дорогам ,а по нему не составит труда запустить игрока.

Да и на самом деле не сложно будет заставить бота ходить, например создаешь для начала каркас обычный вектор от а до б по прямой, после этого запускаешь бота, чтобы сканировал пространство, если обнаружит препятствие во время движения по каркасу по прогнозированному движению, то должен будет обойти и оптимизировать свой путь и так в цикле до идеального прохождения, а для этого тебе придется использовать ещё одну переменную, что-то типа прогнозирования движения, для этого нужно вектор движения умножить на скорость. Но это очень по простому в идеале, нужно будет учитывать скорость движения за фрейм или такт процессора, ускорение и всякое такое, для идеального результата. Тут можешь подробней почитать.

 

https://www.unknowncheats.me/forum/general-programming-and-reversing/173986-math-hack-2-predicting-future-3d-kinematics.html

 

Ссылка на комментарий
Поделиться на другие сайты

Ой. Тут бы сейчас на велосипеде научиться кататься, а за баранку боинга я даже и не думаю.

Пока что пытаюсь реализовать сравнение 2 значений. Теперешний и последний вектора. И если значение теперешнего будет больше, то делать поворот. Пока что попробую так. ДАльше будем смотреть.

В игре то есть маркер и автопуть, но не всегда этот автопуть кратчайший, да и в небе он не нужен =))). А маркер в некоторых ситуациях перестает работать и именно для этих ситуаций и нужен бот.

Ссылка на комментарий
Поделиться на другие сайты

pachela, самый простой бот, это на основания точек, как тут, уже посоветовали, вот пример на немецком(понятно написано, даже с гуг перреводчиком).

Ссылка на комментарий
Поделиться на другие сайты

27 минут назад, pachela сказал:

Тут бы сейчас на велосипеде научиться кататься

Предлагаю такой алгоритм : 

1) Вычисляется вектор по прямой 

2) Идешь по вектору и сравниваешь настоящие значение с прошлым (допустим 1 секунду назад) и если они одинаковы , то есть бот уперся в тупик , то поворачиваешь налево и через 10 значений 

3) поворачиваешь обратно (тобишь направо) и идешь по вектору(см. 1) , в случае неудачи см.2   =)

Ссылка на комментарий
Поделиться на другие сайты

в первую очередь найди угол обзора. 

В радианах он или в градусах - пофиг, всегда можно конвертнуть

я сейчас найду на винте и скину код, калькулятора угла(подбираю с помощью него угол обзора, если все сходится, добавляю расчеты в проект)

От тебя потребуется узнать в чем у нас измеряет угол обзора игра и мин/макс значение угла, я подскажу как поправить код или если уловишь суть можешь по эксперементировать сам.

 

Скрытый текст

#include <iostream>
#include <Windows.h>

#define _USE_MATH_DEFINES
#include <math.h>

float CalcAngle(float X, float Y, float nX, float nY); // Портотип функции
float CalcRadians(float angle); // Портотип функции

using namespace std;

int main()
{
	float X = 0;
	float Y = 0;
	float nX = 0;
	float nY = 0;
	double halfcircle = M_PI;
	// Ввод/Вывод нужной информации
	cout << "Angel Calculator by Wi11ka" << endl;
	// Проверяем наши переменные
	cout << "Math PI: " << M_PI << endl; // not needed :D
	
	// Получаем нужные значение от пользователя
	// и сразу же выводим значение для проверки правильности.
	cout << "Input X:" << endl;
	cin  >> X;
	cout << "X =" << X << endl;
	cout << "Input Y:" << endl;
	cin >> Y;
	cout << "Y =" << Y << endl;
	cout << "Input needed X:" << endl;
	cin >> nX;
	cout << "Needed X = " << nX << endl;
	cout << "Input needed Y:" << endl;
	cin >> nY;
	cout << "Needed Y = " << nY << endl;

	// Вызываем функцию Калькулирующую наш угол и выводим результат.
	float res = CalcAngle(X, Y, nX, nY);
	cout << "Result: " << res << endl;
	float fResult = CalcRadians(res);
	cout << "Finish Result: " << fResult << endl;
	system("PAUSE");
}

float CalcAngle(float X, float Y, float nX, float nY)
{

	// Различие между нами и целью по оси X и Y
	double Xdiff;
	double Ydiff;
	// Угол 
	double AngleA;

	// Времянка :D
	double tmp;

	// Разбиваем работу на 4 секции
	// Section 1
	if (nY > Y && nX <= X)
	{
		Ydiff = nY - Y;
		Xdiff = X - nX;
		// Умножаем на 57.29578 для перевода из радиан в градусы.
		AngleA = atan(Xdiff / Ydiff) * 57.29578;
		
		tmp = 0 - AngleA;

	}
	// Section 2 
	if (nY <= Y && nX < X)
	{
		Ydiff = Y - nY;
		Xdiff = X - nX;

		AngleA = atan(Xdiff / Ydiff) * 57.29578;
		
		tmp = (180 - AngleA)*-1;
	

	}
	// Section 3
	if (nY < Y && nX >= X)
	{
		Ydiff = Y - nY;
		Xdiff = nX - X;

		AngleA = atan(Xdiff / Ydiff) * 57.29578;
		

		tmp = 180 - AngleA;

	}
	// Section 4
	if (nY >= Y && nX > X)
	{
		Ydiff = nY - Y;
		Xdiff = nX - X;

		AngleA = atan(Xdiff / Ydiff)  * 57.29578;
		

		tmp = 0 + AngleA;

	}
	return tmp;
}

float CalcRadians(float angle)
{
	// Возвращаем в радианы
	angle = angle / 57.29578; 

	return angle;
}

 

 

 

Честно не помню под какую игру тут были расчеты, но суть, что в игре угол обзора был от -3.14 до 3.14 

И в итоге это выглядело вот так

https://drive.google.com/open?id=12OprCTzivVEVdIUxVnfpJfwh6xsXnbpt

 

P.S. Извеняюсь, что-то не обратил внимания на C# в заголовке, пример на C++ хотя может тоже поможет. Сори.

 

Изменено пользователем temtriss
Ссылка на комментарий
Поделиться на другие сайты

1 минуту назад, pachela сказал:

Угол обзора это же FOV

Не совсем, FOV - это угол поля зрения. А мне нужен угол на который повернута камера. И его Мин/Макс значения

Ссылка на комментарий
Поделиться на другие сайты

7 минут назад, temtriss сказал:

Не совсем, FOV - это угол поля зрения. А мне нужен угол на который повернута камера. И его Мин/Макс значения

Вот это вот сложнее вычислить. Хотя у меня есть адрес отвечающий за поворот "тела". Так вот оно от 0 и до 6 в float.

Ссылка на комментарий
Поделиться на другие сайты

float и до 6.28?

Так, если я правильно помню, то меняем секцию 1 и 2, а меняем так, 

Секция один: 

tmp = 360 - AngleA;

 

Секция 2:

 

tmp = 180+ AngleA;

Теоретически должно отработать, может возникнуть путаница со сторонами, но надеюсь поможет) потести

Изменено пользователем temtriss
Ссылка на комментарий
Поделиться на другие сайты

14 часа назад, temtriss сказал:

А мне нужен угол на который повернута камера. И его Мин/Макс значения

Я вот сижу и думаю, на сколько я вчера сильно протупил? Камеру в игре можно поворачивать на 360 градусов по горизонтали и на 180 градусов по вертикали.

Почитал я статейку от немца Алекса, любезно порекомендованную вот в этом посте товарищем 2zolo2, и мне она понравилась. Но только тяжковато воспринимается немецкий даже с переводом =). Теперь вот буду думать как вычислить "идеальный угол" =).

Не. Не 6.14, если я правильно понял что пишет программа, то это xmm4:6.27

Изменено пользователем pachela
Ссылка на комментарий
Поделиться на другие сайты

2 часа назад, pachela сказал:

6.27

Да вы правы я затупил) 6.28(6.28 == 0) по этому вы видите 6.27

Число Пи умноженое на 2

Мой пример должен прекрасно отработать)

Ссылка на комментарий
Поделиться на другие сайты

Прочитал ваш пример и теоретически понял его. Осталось перевести в Шарп.

Я правильно понял, что 

float CalcRadians(float angle)
{
	// Возвращаем в радианы
	angle = angle / 57.29578; 

	return angle;
}

Вот этот вот "angle" мы впишем в адрес содержащий "6.28"? Т.е. вот этот вот 6.28 и есть угол, который нам нужно изменить?

Ссылка на комментарий
Поделиться на другие сайты

19 часов назад, pachela сказал:

Вот такую я штуку хочу реализовать. Но моих знаний в С# пока что маловато, да и с математикой я в разных лодках. А ведь хочется намутить автобегалку/леталку.

Люди добрые помогите кто чем может :-[

 

Намутить автобегалку/леталку  можно на игровом движке Unity. Посмотреть как сделать движение и повороты. Можно сделать очень много экспериментов по движениям, эйлеровым углам, кватернионам, матрицам, шейдерам и прочее. По навигации можно наделать алгоритмов на C# сколько угодно. Есть также стандартный агент навигации, который поможет сравнить свой и его алгоритм.

Также можно декомплировать .net библиотеки и в них посмотреть формулы, если они вдруг пригодятся в чужой игре.

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.