如何调整这些函数,使其即使在值范围的极端情况下也能工作?(反向LOG)

How can I adjust these functions to work even at the extremes of the range of values? (Inverse LOG)

本文关键字:情况下 工作 LOG 反向 范围 调整 何调整 函数      更新时间:2023-10-16

我正在为mmorpg编写一个自动机器人,其中一个必要的信息是玩家的当前标题。相机视角存储在内存中的方式相当复杂。我有三个变量,我命名为CamX1,CamX2和CamY。

CamY是一个浮动点值,范围从-0.91到+0.91,0是垂直的。然而,一件棘手的事情是,通过将值通过以10为底的对数从其百分比调整为该值,您可以通过查看下面的代码来理解我的意思,该代码通过使用反对数将值转换回百分比。

CamX1也是一个从-1到正1的浮点值。当查找到期W或到期E时,值为0。向南看时,该值为负值,向北看时,其值为正值。这个变量是非常有结论的,因为该值是通过一个以10为底的对数传递的,但当查找到期N或到期S时,根据Y的当前值,最大值从.41到1不等。您可以通过查看将CamX1转换为百分比的代码来更好地理解这一点。

CamX2与CamX1相同,只是旋转了90度,所以当面对W或E时,它不是0。当面对N或S时,它是0。当E时为正,当W时为负。当面对W和E时它处于最大值,但最大值与CamX1一样根据相机当前的Y视角而变化。

下面的代码适用于面向任何基本方向的10度以内的情况,例如:面向350-360度时,值始终为350,当你越过正北时,值会跳到10度,直到你越过10度时才会改变,如果你面向80-90度,值为80度,90-100度是100度,但101是101度,依此类推。Y值也存在同样的问题,但只有在0的10度以内时,从-10到0的值才是-.1,一旦过了0,值就会是+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

y的值根本不会进入计算。可能是某种半径或速度信息被编码为(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;
    }