操纵杆输入-类似于D-Pad. (数学问题.) [英] Joystick Input - Like a D-Pad. (Math issues.)

查看:74
本文介绍了操纵杆输入-类似于D-Pad. (数学问题.)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为一个使用操纵杆的模拟输入的C ++应用程序(其他人写过)进行修复,我需要使它像D-Pad一样工作,我真正想做的就是创建介于0-360度之间的八个象限,并将两个象限应用于每个方向. (上\下\左\右)

那应该使其表现得更像预期,但是,我对此背后的数学有一些麻烦. (我在数学上很烂,对不起.)

此代码可以工作,但是不正确..

I''m working on a fix for a C++ application(someone else wrote it) which uses analog input from a joystick, I need this to act like a D-Pad, what I really wanted to do, was to create eight quadrants between 0-360 degrees, and apply two quadrants to each direction. (Up\Down\Left\Right)

That should make it act a bit more like it''s supposed to, however, I''m having a bit of trouble with the math behind this. (I suck at math, sorry.)

This code sort of works, but, it''s not right..

    I'm assuming an origin(for my line) of 0,0(ie, the analog stick centered = 0,0.), and trying to calculate the angle using the X, and Y values of the joystick. (wm_ax, wm_ay are of course the current position of the joystick..)

// Input Detected
if (wm_ax * wm_ax + wm_ay * wm_ay > PADCAL * PADCAL) // No idea what this does, it was the original authors, assuming it makes sure it's not in  the dead zone, out of bounds, etc,. ? (No clue what PADCAL is.)
{
    int quadrant = -1;
    double angle = atan2(wm_ay - 0, wm_ax - 0);
    double degrees = angle * 180 / PI;

    if (degrees < 0)
    {
        degrees=-degrees;
        quadrant = 4-degrees/90;
    }
    else
    {
        quadrant = 1+degrees/90;
    }

            // I DO get input here, but it's not right..
    if (quadrant == 1) // I tried 0 based too
        J |= VBA_UP;
    else if (quadrant == 2)
        J |= VBA_RIGHT;
    else if (quadrant == 3)
        J |= VBA_DOWN;
    else if (quadrant == 4)
        J |= VBA_LEFT;

}



这是原始代码,它可以帮助您更好地理解我的需求. (此代码有效,但是它不是很准确,并且有时在某些角度下会显得有些奇怪.)

(您可以忽略pad_x \ pad_y位,这些位用于此函数处理的其他输入类型.)



Here is the original code, it may help you understand what I need a little better. (This code works, but, it''s not very accurate, and acts a bit wonky sometimes at certain angles.)

(You can ignore the pad_x\pad_y bits, those are for other input types that this function handles.)

// Is XY inside the "zone"?
if (wm_ax * wm_ax + wm_ay * wm_ay > PADCAL * PADCAL)
{
    /*** we don't want division by zero ***/
    if (wm_ay == 0)
    {
        if(wm_ax > 0)
        {
            J |= VBA_RIGHT;
        }
        else if(pad_x < 0)
        {
            J |= VBA_LEFT;
        }
    }
    if (wm_ax == 0)
    {
        if(wm_ay > 0)
        {
            J |= VBA_UP;
        }
        else if(pad_y < 0)
        {
            J |= VBA_DOWN;
        }
    }

    if (wm_ax != 0 && wm_ay != 0)
    {
        if ((fabs((double)(wm_ay) / (double)(wm_ax))) < 2.41421356237)
        {
            if (wm_ax >= 0)
                J |= VBA_RIGHT;
            else
                J |= VBA_LEFT;
        }
        if ((fabs((double)(wm_ax) / (double)(wm_ay))) < 2.41421356237)
        {
            if (wm_ay >= 0)
                J |= VBA_UP;
            else
                J |= VBA_DOWN;
        }
    }
}



任何帮助,将不胜感激. :)



Any help would be appreciated. :)

推荐答案

您可能需要这样的表达式:
You probably need an expression like this:
if ( wm_ax * wm_ax + wm_ay * wm_ay > R2 )
{// valid direction: consider the stick out of the 'dead zone'

}


R2值取决于您.

然后,您可以直接使用atan2的结果来计算象限.

但是,我想您可能会做得更好:


where R2 value is up to you.

Then you may directly use the result of atan2 for computing the quadrant.

However, I guess, you may do better:

J = 0;
if ( wm_ax * wm_ax + wm_ay * wm_ay > R2 )
{
  // inside the 'valid direction' block.
  double angle = atan2(wm_ay, wm_ax);
  const double THRES = 1.0 / sqrt(2.0);

  if ( cos(angle) > THRES ) 
    J |= VBA_RIGHT;
  else if ( cos(angle) < -THRES )
    J |= VBA_LEFT;
  if ( sin(angle) > THRES )
    J |= VBA_UP;
  else if ( sin(angle) < -THRES)
    J |= VBA_DOWN;
}


这篇关于操纵杆输入-类似于D-Pad. (数学问题.)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆