使用虚拟XNA-Rectangle-'触控板'的Kinect光标控制 - Y轴反转

时间:2012-07-19 10:55:40

标签: c# xna kinect coordinate-systems

我正在尝试为MS Kinect实施实时策略控制方案。 到目前为止,我有一个光标,可以通过移动你的左手(或右,取决于你的左手)移动。我有一个基于Open-NI的Kinect控制器,它为玩家动作设置了一个骨架,并为我的应用程序提供了腕部,肘部,肩部和身体中心坐标。 为了将这些腕部坐标投射到屏幕上,我设置了一个矩形,它位于玩家中心的左/右边,只要手腕在矩形内移动,光标就会在屏幕上移动。 我的问题是,XNA-Rectangle的左上角是原点,即X轴指向右边,因为它“应该”,但是Y轴指向下方,而K轴的Y轴指向 - 坐标系指向上方。当我向下移动手时,这会导致光标在屏幕上向上移动,反之亦然。我无法用Kinect坐标系改变任何东西,所以是否可以“翻转”矩形的“坐标系”,以便它的Y轴也指向上方?

以下是相关代码:

(来自Calibrate() - 方法:)

List<Vector3> joints = UDPlistener.getInstance().ParseCalibCoordinates(data);
//0 = Right Wrist 1 = Right Elbow 2 = Right Shoulder
//3 = Left Wrist  4 = Left Elbow 5 = Left Shoulder
//6 = Center
height = 762; 
width = 1024;            
switch (hand)
{
    case 0:
    cursorSpace = new Rectangle((int)(joints[6].X * 2) - 200, (int)(joints[6].Y * 2) + height, width, height);
    break;
    case 3:
    cursorSpace = new Rectangle((int)(joints[6].X * 2) - 1200, (int)(joints[6].Y * 2) + height, width, height);
    break;
}

public Point Cursor(String data)
{   
    List<Vector3> joints = UDPlistener.getInstance().ParsePlayCoordinates(data);
    //0 = Right Wrist 1 = Left Wrist 2 = Center
    double mhx = 0; //main hand x-coordinate
    double mhy = 0; // main hand y-coordinate
    switch (hand)
    {
        case 0:
        mhx = joints[hand].X;
        mhy = joints[hand].Y;
        break; 

        case 3:
        mhx = joints[hand-2].X;
        mhy = joints[hand-2].Y;
        break;                    
    }

int x; 
int y;
if (Math.Abs(mhx - mhxOld) < 1.0 || Math.Abs(mhy - mhyOld) < 1.0) 
//To remove jittering of the cursor
{
    x = (int) mhxOld * 2;
    y = (int) mhyOld * 2;  
}
else
{
    x = (int) mhx * 2;
    mhxOld = mhx;
    y = (int) mhy * 2;
    mhyOld = mhy;
}

Point cursor = new Point(0,0);

if (cursorSpace.Contains(x,y)) 
{
    cursor = new Point(x - cursorSpace.X, y - CursorSpace.Y);                    
    lastCursorPos = cursor;
    return cursor;                    
}

对不起文字的墙,我希望,我能说清楚。

提前致谢,

KK

2 个答案:

答案 0 :(得分:2)

我使用扩展方法转换OpenNI坐标。以下示例将OpenNI坐标映射到左上角640x480矩形中的XNA坐标,表示为Vector2对象。

public static Vector2 ToXnaCoordinates(this Point3D point)
{
    return new Vector2(
        point.X + 320,
        (point.Y - 240) * -1);
}

翻转y坐标的魔力是* -1部分。

如果要到达尺寸不同于640x480的矩形,则需要在转换后相应地缩放坐标。例如:

public static Vector2 ToScaledXnaCoordinates(this Point3D point, int rectSizeX, int rectSizeY)
{
    return new Vector2(
        (point.X + 320) * rectSizeX / 640,
        (point.Y - 240) * -rectSizeY / 480);
}

答案 1 :(得分:0)

我知道这不是XNA,但是我想把它放在那里为那些wpf用户:)如果你使用类似Channel 9's方法的东西,只需要一个bool来确定是否倒置。例如:

    private void ScalePosition(FrameworkElement element, Joint joint, bool inverted)
    {
        //convert the value to X/Y
        Joint scaledJoint = joint.ScaleTo(967, 611);

        //convert & scale (.3 = means 1/3 of joint distance)
        //Joint scaledJoint = joint.ScaleTo(1280, 720, 1f, 1f);
        if (!inverted)
        {
            Canvas.SetLeft(element, scaledJoint.Position.X);
            Canvas.SetTop(element, scaledJoint.Position.Y);
        }

        if (inverted)
        {
            Canvas.SetLeft(element, scaledJoint.Position.X);
            Canvas.SetBottom(element, scaledJoint.Position.Y);
        }
    }

希望这有助于WPF用户!