2009-03-28 9 views
1

WinSock 연결을 사용하여 가속도 정보 및 iPhone을 가져 와서 Direct3D 응용 프로그램에 연결합니다. Apels GLGravity의 샘플 코드를 수정하여 헬리콥터가 중력과 관련하여 움직이게 만들었지 만 헬리콥터가 거꾸로 날아 가지 않도록 움직임을 "캡핑"해야합니다! 나는 가속도계의 출력을 제한하려고 시도했다.Direct3D 및 iPhone 가속도계 매트릭스

if (y < -0.38f) { 
    y = -0.38f; 
} 

이것이 효과가있는 것을 제외하고는!? 내가 생각할 수있는 유일한 것은 사용자 정의 행렬을 수정해야하지만, 내가 바꿀 필요가있는 것에 대해 머리를 맞출 수없는 것 같습니다. 매트릭스는 아래 코드입니다.

_x = acceleration.x; 
_y = acceleration.y; 
_z = acceleration.z; 

float length; 
D3DXMATRIX matrix, t; 

memset(matrix, '\0', sizeof(matrix)); 

D3DXMatrixIdentity(&matrix); 

// Make sure acceleration value is big enough. 
length = sqrtf(_x * _x + _y * _y + _z * _z); 

if (length >= 0.1f && kInFlight == TRUE) { // We have a acceleration value good enough to work with. 
    matrix._44 = 1.0f; // 

    // First matrix column is a gravity vector. 
    matrix._11 = _x/length; 
    matrix._12 = _y/length; 
    matrix._13 = _z/length; 

    // Second matrix is arbitrary vector in the plane perpendicular to the gravity vector {Gx, Gy, Gz}. 
    // defined by the equation Gx * x + Gy * y + Gz * z = 0 in which we set x = 0 and y = 1. 
    matrix._21 = 0.0f; 
    matrix._22 = 1.0f; 
    matrix._23 = -_y/_z; 
    length = sqrtf(matrix._21 * matrix._21 + matrix._22 * matrix._22 + matrix._23 * matrix._23); 
    matrix._21 /= length; 
    matrix._22 /= length; 
    matrix._23 /= length; 

    // Set third matrix column as a cross product of the first two. 
    matrix._31 = matrix._12 * matrix._23 - matrix._13 * matrix._22; 
    matrix._32 = matrix._21 * matrix._13 - matrix._23 * matrix._11; 
    matrix._33 = matrix._11 * matrix._22 - matrix._12 * matrix._21; 
} 

누구든지 도움을받을 수 있다면 매우 감사하겠습니다!

+0

당신은 지금 어떤 행동을 취하고 있습니까? – bayda

+0

아이폰에서 directx? – hhafez

+0

아니, 나는 그가 제어 장치와 마찬가지로 아이폰을 사용했다고 생각한다 – bayda

답변

0

먼저 가속 벡터를 정규화 해보십시오. (편집 : 당신이 길이를 확인한 후) (편집 편집 : 내가 어떻게 읽는 법을 배워야 할 것 같아요 ... 내 대답을 어떻게 삭제합니까?)

0

그래서 이것을 올바르게 이해하면 iPhone이 당신에게 가속도계 데이터, 3 축으로 iPhone을 얼마나 열심히 움직이는 지 말하는 것.

저는 사과 샘플에 익숙하지 않아서 그 일을 잘 모릅니다. 그러나 가속도를 방향에 직접 매핑하는 것처럼 들리지만, 원하는 것은 헬리콥터 방향을 지정하기 위해 위치를 얻고 위치의 변화를 확인하기 위해 가속을 두 배 통합하는 것입니다. 기본적으로 이것은 Direct3D 문제보다 더 많은 물리 문제입니다.

0

휴대 전화의 가속 벡터를 사용하여 직교 좌표계의 한 축을 정의한 것처럼 보입니다. 그리고 + Y가 땅을 향한 점이라고 가정합니다. 그래서 벡터가 하늘을 향하고있는 경우를 염려합니다.

아이폰이 {0, -6.0, 0}을보고하는 경우를 생각해보십시오. 이 벡터를 {0, -.38, 0}으로 바꿉니다. 하지만 둘 다 {0, -1.0, 0}으로 정상화됩니다. 따라서 -34에서 y를 클램프하는 효과는 벡터의 다른 두 요소의 크기에 영향을받습니다.

Y가 음수 일 때 벡터의 각도를 XZ 평면으로 제한하는 것이 좋습니다.

Y가 음수 일 때 XZ 평면으로 30도 이상으로 제한하고 싶다고합시다. 먼저 벡터를 다음과 같이 정규화하십시오.

const float limitAngle = 30.f * PI/180.f; // angle in radians 
const float sinLimitAngle = sinf(limitAngle); 
const float XZLimitLength = sqrtf(1-sinLimitAngle*sinLimitAngle); 

if (_y < -sinLimitAngle) 
{ 
    _y = -sinLimitAngle; 
    float XZlengthScale = XZLimitLength/sqrtf(_x*_x + _z*_z); 
    _x *= XZlengthScale; 
    _z *= XZlengthScale; 
} 
+0

또한 _x 및 _z이 0 인 경우에도 대소 문자를 처리해야합니다. 가장 단순하지는 않지만 최선의 방법은 벡터 _x = XZLimitLength, _y = -sinLimitAngle, _z = 0을 선택하는 것입니다. –

+0

그리고 휴대 전화와 함께 가상 헬리콥터를 움직이려면 합법화에 동의합니다. 그러면 전체 접근법이 잘못되었습니다. –

1

이중 통합은 아마도 지나치게 복잡한 것입니다. 문제를 올바르게 이해하면 iPhone이 가속도계의 값의 벡터를 제공합니다. 사용자가 주위를 흔들지 않는다고 가정하면 그 벡터는 대략 일정한 길이를 가지며 중력에 따라 아래쪽을 직접 가리킬 것입니다.

큰 문제가 하나 있는데, 사용자가 가로로 전화를 돌릴 때이를 알 수 없다는 것입니다. 테이블 위에 전화기를 놓고 상판에 앉아있는 상태에서 바닥을 바라 볼 수 있다고 상상해보십시오. 중력 벡터는 (0, -1, 0)이됩니다. 이제 바닥을 왼쪽으로 향하게하여 휴대 전화를 약 90도 회전 시키되 테이블 위에서 평평하게 유지하십시오. 중력 벡터는 여전히 (0, -1, 0)이 될 것입니다. 하지만 헬리콥터가 휴대 전화로 바뀌길 바랍니다. iPhone에는 2D 가속도계 만 있고 3D 중력 벡터는 외삽 법에 의해 추정된다는 점이 기본적인 한계입니다.

그래서 사용자에게 전화를 돌릴 수 없다고 말했고, 맨 아래 지점으로 이동해야한다고 가정 해 보겠습니다. 괜찮습니다. 당신은 여전히 ​​많은 것을 통제 할 수 있습니다.

다음으로 헬리콥터가 결코 옆으로 90도 이상 오지 않도록 입력을 캡핑해야합니다. 당신이 휴대 전화에 붙어있는 막대기로 주어지고 중력에 매달려있는 벡터를 상상해보십시오. 가지고있는 벡터는 휴대 전화의 평평한 표면에 비례하여 중력의 방향을 설명합니다. 그것이 (0, -1, 0)이라면 스틱이 바로 아래를 가리키고 있습니다 (-y). 스틱이 (1, 0, 0)이면 스틱은 전화 (+ x)의 오른쪽을 가리키며 전화기가 시계 방향으로 90도 비틀어 졌음을 나타냅니다.

이 은유에서 스틱이 완전히 회전 할 수 있다고 가정합니다. 그것은 전화에서 어떤 방향으로 가리킬 수 있습니다. 그래서 스틱을 움직이면 구의 표면을 묘사합니다. 그러나 결정적으로, 당신은 단지 스틱이 그 구의 아래쪽 절반 주위를 움직일 수 있기를 원합니다. 스틱이 구의 상반부에있을 수 있도록 사용자가 전화기를 비틀면 구형의 적도 부근을 가리 키도록 스틱을 감싸고 싶습니다.

극좌표를 사용하면 아주 명확하게이를 수행 할 수 있습니다. 3D 벡터와 극좌표는 상호 교환 가능하므로 정보를 잃지 않고 변환 할 수 있습니다.

당신이 가지고있는 벡터를 3D 극좌표 세트로 변환하십시오 (물론 웹에서이 논리를 쉽게 찾을 수 있어야합니다). 이것은 수평면 주위의 각도와 수직면의 각도를 제공합니다 (그리고 원점으로부터의 거리 - 정규화 된 벡터의 경우 1.0입니다). 수직 각도가 양수이면 벡터는 구의 상반부에 있고 음수는 반쪽에 있습니다. 그런 다음 수직 각도를 항상 0이되도록 모자하십시오 (따라서 구의 아래쪽 반쪽에서도 마찬가지 임). 그런 다음 가로 및 꼭지점 세로 각도를 가져 와서 벡터로 다시 변환 할 수 있습니다.

이 새로운 벡터는 이미 가지고있는 매트릭스 코드에 연결하면 필요한 동작 범위로 제한된 올바른 방향을 제공합니다. 사용자가 휴대 전화를 90도 이상으로 약간 돌리면 안정적입니다.이 논리는 설정 한도를 초과하지 않고 방향 벡터를 가능한 한 사용자의 현재 방향에 가깝게 유지합니다.