Я пишу автоматизированного бота для mmorpg, одна из необходимых частей информации — текущий заголовок игроков. Способ хранения углов обзора камер в памяти довольно сложен. У меня есть доступ к трем переменным, которые я назвал CamX1, CamX2 и CamY.
CamY — значение с плавающей запятой в диапазоне от -.91 до +.91, 0 перпендикулярно. Хитрость заключается в том, что значения корректируются от процента к этому значению, пропуская его через логарифм с основанием 10, и вы можете понять, что я имею в виду, посмотрев на приведенный ниже код, который превращает значение обратно в процент с помощью обратного логарифма.
CamX1 также является значением с плавающей запятой в диапазоне от -1 до положительного значения 1. При взгляде из-за W или из-за E значение равно 0. При взгляде на юг значение отрицательное, а при взгляде на север — положительное. Эта переменная является чрезвычайно важной, потому что значение пропускается через логарифм с основанием 10, но и максимальное значение при поиске из-за N или из-за S варьируется от .41 до 1 в зависимости от текущего значения Y. Вы можете лучше понять это, посмотрев на код для преобразования CamX1 в процентах.
CamX2 такой же, как CamX1, за исключением поворота на 90 градусов, поэтому вместо 0 при обращении к W или E он равен 0 при обращении к N или S. Положительный при E и отрицательный при W. Максимальное значение при обращении к W или E, но это максимальное значение варьируется, как CamX1, в зависимости от текущего угла обзора Y камеры.
Приведенный ниже код работает, за исключением случаев, когда вы обращены в пределах 10 градусов от любого кардинального направления, например: при обращении к 350 — 360 градусам значение всегда равно 350, при пересечении на север значение переходит на 10 градусов и не изменяйте до тех пор, пока вы не пройдете 10 градусов, если вы смотрите на 80 — 90 градусов, значение составляет 80 градусов, 90 — 100 градусов — это 100 градусов, но 101 — это 101 и так далее. Та же проблема существует со значением Y, но только в том случае, если в пределах 10 градусов от 0 значение от -10 до 0 равно -.1, а после пересечения 0 значение равно +.1 до тех пор, пока вы не пройдете 10 градусов, а затем оно увеличивается правильно. Если вы можете объяснить проблему только с помощью переменной Y, я, скорее всего, смогу применить ее к проблеме со значениями X и получить полное решение. Вот код:
float GetYFactor()
{
float yAsPercent = (pow(10,abs(CamY)/.91))/10;
if (yAsPercent > 1) yAsPercent = 1;
return 1-(yAsPercent*.59);
}
float GetX1ViewAngleAsPercent()
{
float x1AsPercent = (pow(10,abs(CamX1)/GetYFactor()))/10;
if (x1AsPercent > 1) x1AsPercent = (1 - GetX2ViewAngleAsPercent());
return x1AsPercent;
}
float GetX2ViewAngleAsPercent()
{
float x2AsPercent = (pow(10,abs(CamX2)/GetYFactor()))/10;
if (x2AsPercent > 1) x2AsPercent = (1 - GetX1ViewAngleAsPercent());
return x2AsPercent;
}
float GetCurrentHeading()
{
float deg = GetX1ViewAngleAsPercent() * 90;
if(CamX1 > 0 && CamX2 > 0) //Q1
deg = 90 - deg;
if(CamX1 < 0 && CamX2 > 0) //Q2
deg = 90 + deg;
if(CamX1 < 0 && CamX2 < 0) //Q3
deg = 180 + (90 - deg);
if(CamX1 > 0 && CamX2 < 0) //Q4
deg = 270 + deg;return deg;
}
Причина для кода, такого как
if (yAsPercent > 1) yAsPercent = 1;
Вероятно, связано с этой проблемой, при ближайших максимумах значение процентов будет увеличиваться после 1 и подниматься до 1,15, и это была моя попытка быстрого решения. но это не совсем решает проблему полностью.
Я знаю, что это было долгое чтение, поэтому спасибо за ваше время, любая помощь будет оказана с благодарностью, так как мне нужна точность около +/- 2 градуса, поэтому эти 20-градусные промежутки довольно разочаровывают, также не нужно беспокоиться о случае, когда любое из трех значений, с которых мы начинаем, равно 0, этого никогда не было, попробуйте, как я могу.
Я считаю, что это связано с передачей ценностей < .01 в функцию обратного логарифма (10 ^ .009), но у меня недостаточно опыта с этим типом математики, чтобы понять, что происходит.
Я не уверен, почему кто-то может кодировать углы с помощью логарифмов, не должно быть проблем с числовым превышением или понижением в типичных значениях углов.
Разумная интерпретация заключается в том, что пара (x1, x2) кодирует горизонтальную ориентацию y и высоту камеры. Тогда ожидаемый расчет будет
radians = atan2(x2,x1)
degrees = radians*180/pi
Значение у не будет вводить в расчет вообще. Может случиться так, что некоторая информация о радиусе или скорости закодирована в виде величины (x1, x2), например, как
0.5*log(x1^2+x2^2)
Недостаточно информации, чтобы предугадать, что же на самом деле происходит.
Я думаю, что то, что я думал, было ответом (как отмечено в комментарии, который я отправил), было правильным решением, или, по крайней мере, оно работает, если кто-то знает, почему я не должен делать это таким образом, пожалуйста, дайте мне знать. обновленный код приведен ниже, а основным изменением являются строки с модификатором локальной переменной. Я также переименовал CamX2 в CamZ.
float GetYFactor()
{
float modifier = 1;
if (abs(CamY) <= .1) modifier = 10;
float yAsPercent = (pow(10,abs(CamY * modifier)/.91))/10/modifier;
if (yAsPercent > 1) yAsPercent = 1;
return 1-(yAsPercent*.59);
}
float GetXViewAngleAsPercent()
{
float modifier = 1;
if (abs(CamX) <= .1) modifier = 10;
float xAsPercent = (pow(10,abs(CamX * modifier)/GetYFactor()))/10/modifier;
if (xAsPercent > 1) xAsPercent = (1 - GetZViewAngleAsPercent());
return xAsPercent;
}
float GetZViewAngleAsPercent()
{
float modifier = 1;
if (abs(CamZ) <= .1) modifier = 10;
float zAsPercent = (pow(10,abs(CamZ * modifier)/GetYFactor()))/10/modifier;
if (zAsPercent > 1) zAsPercent = (1 - GetXViewAngleAsPercent());
return zAsPercent;
}
float GetCurrentHeading()
{
float deg = GetXViewAngleAsPercent() * 90;
if(CamX > 0 && CamZ > 0) //Q1
deg = (90 - deg);
if(CamX < 0 && CamZ > 0) //Q2
deg += 90;
if(CamX < 0 && CamZ < 0) //Q3
deg = (90 - deg) + 180;
if(CamX > 0 && CamZ < 0) //Q4
deg += 270;
return deg;
}