2012-07-19 4 views
2

MS Kinect에 대한 실시간 전략 제어 체계를 구현하려고합니다. 지금까지 커서가 생겼습니다. 커서는 왼쪽 손 (또는 오른손, 왼손잡이)에 따라 움직일 수 있습니다. 저는 Open-NI 기반 Kinect 컨트롤러를 가지고 있습니다.이 컨트롤러는 플레이어의 움직임을위한 뼈대를 설정하고 손목, 팔꿈치, 어깨 및 몸통 중심 좌표를 어플리케이션에 전달합니다. 이 손목 좌표를 화면에 투영하려면 플레이어 중심에서 약간 왼쪽/오른쪽에 위치한 직사각형을 설정하고 손목이 사각형 내부로 이동하는 동안 커서가 화면 위로 이동합니다. 내 문제는 XNA 직사각형의 왼쪽 위 모서리가 원점 인 점입니다. 즉, X 축은 오른쪽에 있어야하지만 Y 축은 아래로 향하고 Kinect의 Y 축은 오른쪽으로 향해야합니다. - 좌표계가 올라간다. 이렇게하면 커서를 화면 위로 움직이게하고, 손을 아래로 움직이면 커서가 위쪽으로 움직입니다. Kinect 좌표계로 무엇이든 변경할 수있는 방법이 없으므로 사각형의 '좌표계'를 '뒤집어서'Y 축의 점도 위로 올릴 수 있습니까?가상 XNA 직사각형을 이용한 Kinect 커서 제어 - '터치 패드'- Y 축이 반전 됨

가 여기에 관련 코드입니다 :

(보정()에서 - 방법 : 텍스트의 벽

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

난 OpenNI 좌표를 변환하기위한 확장 방법을 사용한다. 다음 예제에서는 OpenNI 좌표를 Vector2 객체로 표시되는 왼쪽 상단 모서리의 640x480 사각형에있는 XNA 좌표에 매핑합니다.

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); 
} 
+0

+1 결코 * -1을 생각하면 간단하지 않습니다. :) –

+0

괜찮 았는데, 고마워. 그러나 또 다른 문제가 생겼다. 나의 접근 방식으로, 나는 사용자의 커서 - 손쪽으로 이동되어 화면에있는 각 지점을 스트레칭이나 과도하게 굴곡시키지 않고 쉽게 도달 할 수 있도록 깔끔한 영역을 가졌다. 내 'Cursor'-Method의 스위치 (손) 블록에 방법을 적용했는데 엄청나게 효과적 이었지만 지금은'센서 '영역이 플레이어의 바로 앞에 있으며 무릎 수준보다 약간 위까지 내려갑니다. 나는 'if (cursorSpace.Contains)'에 대해 수정되지 않은 손 좌표를 사용하고 그 후에 오프셋으로 '마법'을 적용하려고 시도했지만 의도 한대로 작동하지 않았습니다. 어떤 아이디어? –

+0

도달 범위를 최대화하기 위해 손 움직임을 최소화하기 위해 +320과 -240을 조정하는 것이 좋습니다. 또한, 좌표의 크기를 (시프 팅 후에) 사각형의 크기로 조절하고자 할 수 있습니다. 기본적으로 +320, -240, 640, 480 값을 변경해야합니다. 불행하게도, 케이스마다 다른 이상적인 솔루션을 제공 할 수는 없습니다. 그러나 목표 영역 크기의 증가에 따라 정확도가 떨어지는 것을 잊지 마십시오. –

0

나는이 XNA 아니라는 것을 알고,하지만 난 당신이 Channel 9's 방법 같은 것을 사용하는 경우, 단지 부울이 :) 반전 있는지 확인하는 WPF 사용자가이내는 싶어 여부 . 예 :

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 사용자에게 도움이됩니다.