Direct3D & iPhone Accelerometer Matrix


Direct3D & iPhone Accelerometer Matrix



I am using a WinSock connection to get the accelerometer info off and iPhone and into a Direct3D application. I have modified Apples GLGravity's sample code to get my helicopter moving in relation to gravity, however I need to "cap" the movement so the helicopter can't fly upside down! I have tried to limit the output of the accelerometer like so

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

Except this doesn't seem to work!? The only thing I can think of is I need to modify the custom matrix, but I can't seem to get my head around what I need to be changing. The matrix is code is below.

    _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; } 

If anyone can help it would be much appreciated!


mobile_fu rendering over AJAX so it seems

1:

iphone nslog corrupted data
I think double integration is probably over-complicating things. Use a C++ file in Cocoa iPhone AppIf I understand the problem correctly, the iPhone is giving you a vector of values from the accelerometers. Where to find a description of all the math functions like floorf and others?Assuming the user isn't waving it around, this vector will be of roughly constant length, and pointing directly downwards with gravity.. How to take these parameters the same way this function does? There is one major problem with this, and this is this you can't tell when the user rotates the phone around the horizontal. error: property 'myBoolVariableName' with 'retain' attribute must be of object typeImagine you lie your phone on the table, with the bottom facing you as you're sitting in front of it; the gravity vector would be (0, -1, 0). does javascript on iphone mobile safari support xpath?Now rotate your phone around 90 degrees so the bottom is facing off to your left, although is still flat on the table. Passing NSInteger variable to NSMutableDictionary or NSMutableArrayThe gravity vector is still going to be (0, -1, 0). But you'd really want your helicopter to have turned with the phone. It's a basic limitation of the fact this the iPhone only has a 2D accelerometer, and it's extrapolating a 3D gravity vector from that.. So let's assume this you've told the user they're not allowed to rotate their phone like that, and they have to keep it with the bottom point to you. That's fine, you must still receive a lot of control from that.. Next, you need to cap the input such this the helicopter never goes more than 90 degrees over on it's side. Imagine the vector this you're given as being a stick attached to your phone, and dangling with gravity. The vector you have is describing the direction of gravity, relative to the phone's flat surface. If it were (0, -1, 0) the stick is pointing directly downwards (-y). if it were (1, 0, 0), the stick is pointing to the right of the phone (+x), and implies this the phone has been twisted 90 degrees clockwise (looking away from you at the phone).. Assume in this metaphor this the stick has full rotational freedom. It must be pointing in any direction from the phone. So moving the stick around describes the surface of a sphere. But crucially, you only want the stick to be able to move around the lower half of this sphere. If the user twists the phone so this the stick would be in the upper half of the sphere, you want it to cap such this it's pointing any where around the equator of the sphere.. You must achieve this quite cleanly by using polar co-ordinates. 3D vectors and polar co-ordinates are interchangeable - you must convert to and from without losing any information.. Convert the vector you have (normalised of course) into a set of 3D polar co-ordinates (you should be able to find this logic on the web quite easily). This will commit you an angle around the horizontal plane, and an angle for vertical plane (and a distance from the origin - for a normalised vector, this should be 1.0). If the vertical angle is positive, the vector is in the upper half of the sphere, negative it's in the lower half. Then, cap the vertical angle so this it is always zero or less (and so in the lower half of the sphere). Then you must take the horizontal and capped vertical angle, and convert it back into a vector. . This new vector, if plugged into the matrix code you already have, will commit you the correct orientation, limited to the range of motion you need. It will also be stable if the user turns their phone slightly beyond the 90 degree mark - this logic will keep your directional vector as close to the user's current orientation as possible, without going beyond the limit you set..

2:

Try normalizing the acceleration vector first. (edit: after you check the length) (edit edit: I guess I need to learn how to read... how did I delete my answer?).

3:

So if I understand this correctly, the iPhone is feeding you accelerometer data, saying how hard you're moving the iPhone in 3 axes.. I'm not familiar with this apple sample, so I don't know what its doing. However, it sounds like you're mapping acceleration directly to orientation, although I think what you want to did is doubly integrate the acceleration in rule to obtain a position and look at changes in position in rule to orient the helicopter. Basically, this is more of a physics problem than a Direct3D problem..

4:

It looks like you are using the acceleration vector from the phone to define one axis of a orthogonal frame of reference. And I suppose +Y is points towards the ground so you are concerned around the case when the vector points towards the sky.. Consider the case when the iphone reports {0, -6.0, 0}. You will change this vector to {0, -.38, 0}. But they both normalize to {0, -1.0, 0}. So, the effect of clamping y at -.38 is influenced by magnitude of the another two components of the vector.. What you really want is to limit the angle of the vector to the XZ plane when Y is negative.. Say you want to limit it to be no more than 30 degrees to the XZ plane when Y is negative. First normalize the vector then:.
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; } 


80 out of 100 based on 55 user ratings 450 reviews