Accelerometer Low Pass Filter Smoothing - ios

I am using the device accelerometer and try to smooth the Accelerometer Data CMAcceleration.
I am doing this with help of this code:
-(void)proccessAccelerometerData:(CMAcceleration)accelData {
currentAccelX = (kUpdateInterval * accelData.x) + ((1.0 - kUpdateInterval) * currentAccelX);
currentAccelY = (kUpdateInterval * accelData.y) + ((1.0 - kUpdateInterval) * currentAccelY);
}
Which currentAccelX and currentAccelY is the last accelerometer x and y data.
Now, I have the smooth x and y values, What is my value of x or y to determine id the user move the device left/right/up/down?
Just to make things more clear, for example, let's say that I have 4 buttons, one for each direction left/right/up/down and I want to determine which direction the user user swipe the device? (not swipe gesture).
Thanks in advance!

Assuming you hold the device in portrait orientation, the x-Axis indicates the movement to the left and right (positive x is to the right and negative x to the left).
The y-Axis indicates the movement of the device up and down (positive y is upwards and negative y is downwards).
The z-Axis indicates the movement of the device forwards and backwards (positive z is towards the user and negative z is away from the user).
There is an info graphic by Apple: developer.apple.com

Related

change the origin of coordinates and match two coordinates with each other in the Lua language

I'm working on a project in which an + sign moves in animation according to the x and y coordinates on the page
Everything is fine so far.
Now I want to raise two issues: The first issue is that the beginning of the coordinate axis or point (0,0) is in the upper left corner of the page. I need to be able to move this coordinate origin in the four corners of the page if needed.
Problem 2: The + sign that moves in animation varies from 0 to 1400 in the x coordinates and from 0 to 900 in the y coordinates, while I have to display this value on the 340x290 page, how do these coordinate matches work?
Programming is in lua language.
Edit 1:
Screenshot
This sign (+) should move on the specified screen with dimensions of 290x340, according to the values ​​of x and y at the top right of the screen. The values ​​x and y shown at the top right are in millimeters, which can be from 0 to 900 mm for x and 0 to 1500 mm for y.
How to match a 0 to 900mm and 0 to 1500mm motion on a 290x340 pixel screen?
Thanks for each reply

Pixel-perfect collisions in Monogame, with float positions

I want to detect pixel-perfect collisions between 2 sprites.
I use the following function which I have found online, but makes total sense to me.
static bool PerPixelCollision(Sprite a, Sprite b)
{
// Get Color data of each Texture
Color[] bitsA = new Color[a.Width * a.Height];
a.Texture.GetData(0, a.CurrentFrameRectangle, bitsA, 0, a.Width * a.Height);
Color[] bitsB = new Color[b.Width * b.Height];
b.Texture.GetData(0, b.CurrentFrameRectangle, bitsB, 0, b.Width * b.Height);
// Calculate the intersecting rectangle
int x1 = (int)Math.Floor(Math.Max(a.Bounds.X, b.Bounds.X));
int x2 = (int)Math.Floor(Math.Min(a.Bounds.X + a.Bounds.Width, b.Bounds.X + b.Bounds.Width));
int y1 = (int)Math.Floor(Math.Max(a.Bounds.Y, b.Bounds.Y));
int y2 = (int)Math.Floor(Math.Min(a.Bounds.Y + a.Bounds.Height, b.Bounds.Y + b.Bounds.Height));
// For each single pixel in the intersecting rectangle
for (int y = y1; y < y2; ++y)
{
for (int x = x1; x < x2; ++x)
{
// Get the color from each texture
Color colorA = bitsA[(x - (int)Math.Floor(a.Bounds.X)) + (y - (int)Math.Floor(a.Bounds.Y)) * a.Texture.Width];
Color colorB = bitsB[(x - (int)Math.Floor(b.Bounds.X)) + (y - (int)Math.Floor(b.Bounds.Y)) * b.Texture.Width];
if (colorA.A != 0 && colorB.A != 0) // If both colors are not transparent (the alpha channel is not 0), then there is a collision
{
return true;
}
}
}
//If no collision occurred by now, we're clear.
return false;
}
(all the Math.floor are useless, I copied this function from my current code where I'm trying to make it work with floats).
It reads the color of the sprites in the rectangle portion that is common to both sprites.
This actually works fine, when I display the sprites at x/y coordinates where x and y are int's (.Bounds.X and .Bounds.Y):
View an example
The problem with displaying sprites at int's coordinates is that it results in a very jaggy movement in diagonals:
View an example
So ultimately I would like to not cast the sprite position to int's when drawing them, which results in a smooth(er) movement:
View an example
The issue is that the PerPixelCollision works with ints, not floats, so that's why I added all those Math.Floor. As is, it works in most cases, but it's missing one line and one row of checking on the bottom and right (I think) of the common Rectangle because of the rounding induced by Math.Floor:
View an example
When I think about it, I think it makes sense. If x1 is 80 and x2 would actually be 81.5 but is 81 because of the cast, then the loop will only work for x = 80, and therefore miss the last column (in the example gif, the fixed sprite has a transparent column on the left of the visible pixels).
The issue is that no matter how hard I think about this, or no matter what I try (I have tried a lot of things) - I cannot make this work properly. I am almost convinced that x2 and y2 should have Math.Ceiling instead of Math.Floor, so as to "include" the last pixel that otherwise is left out, but then it always gets me an index out of the bitsA or bitsB arrays.
Would anyone be able to adjust this function so that it works when Bounds.X and Bounds.Y are floats?
PS - could the issue possibly come from BoxingViewportAdapter? I am using this (from MonoExtended) to "upscale" my game which is actually 144p.
Remember, there is no such thing as a fractional pixel. For movement purposes, it completely makes sense to use floats for the values and cast them to integer pixels when drawn. The problem is not in the fractional values, but in the way that they are drawn.
The main reason the collisions are not appearing to work correctly is the scaling. The colors for the new pixels in between the diagonals get their colors by averaging* the surrounding pixels. The effect makes the image appear larger than the original, especially on the diagonals.
*there are several methods that may be used for the scaling, bi-cubic and linear are the most common.
The only direct(pixel perfect) solution is to compare the actual output after scaling. This requires rendering the entire screen twice, and requires the scale factor more computations. (not recommended)
Since you are comparing the non-scaled images your collisions appear to be off.
The other issue is movement speed. If you are moving faster than one pixel per Update(), detecting per pixel collisions is not enough, if the movement is to be restricted by the obstacle. You must resolve the collision.
For enemies or environmental hazards your original code is sufficient and collision resolution is not required. It will give the player a minor advantage.
A simple resolution algorithm(see below for a mathematical solution) is to unwind the movement by half, check for collision. If it is still colliding, unwind the movement by a quarter, otherwise advance it by a quarter and check for collision. Repeat until the movement is less than 1 pixel. This runs log of Speed times.
As for the top wall not colliding perfectly: If the starting Y value is not a multiple of the vertical movement speed, you will not land perfectly on zero. I prefer to resolve this by setting the Y = 0, when Y is negative. It is the same for X, and also when X and Y > screen bounds - origin, for the bottom and right of the screen.
I prefer to use mathematical solutions for collision resolution. In your example images, you show a box colliding with a diamond, the diamond shape is represented mathematically as the Manhattan distance(Math.Abs(x1-x2) + Math.Abs(y1-y2)). From this fact, it is easy directly calculate the resolution to the collision.
On optimizations:
Be sure to check that the bounding Rectangles are overlapping before calling this method.
As you have stated, remove all Math.Floors, since, the cast is sufficient. Reduce all calculations inside of the loops not dependent on the loop variable outside of the loop.
The (int)a.Bounds.Y * a.Texture.Width and (int)b.Bounds.Y * b.Texture.Width are not dependent on the x or y variables and should be calculated and stored before the loops. The subtractions 'y-[above variable]` should be stored in the "y" loop.
I would recommend using a bitboard(1 bit per 8 by 8 square) for collisions. It reduces the broad(8x8) collision checks to O(1). For a resolution of 144x144, the entire search space becomes 18x18.
you can wrap your sprite with a rectangle and use its function called Intersect,which detedct collistions.
Intersect - XNA

How do I ensure a bouncing object lands on a scrolling object on the ground (after “X” bounces) where "X" bounces is known in advance?

Please see the demo of what I have at the moment:
https://www.dropbox.com/s/zfg3crvoohrrhij/bouncingDemo.mov?dl=0
There is an orange square that should bounce on a green square after the orange square bounces "X" times (where "X" is defined in advance). For example, after the orange square bounces 2 times, it MUST land on a green square on the 3rd bounce and increase in height again and resume bouncing.
The issue I'm facing is that the orange square doesn't always land on a green square. Sometimes the orange square lands on the green square as expected but other times it lands just before or after it. I add the green squares (off screen) after a certain number of frames and move them by changing it's "X" co-ordinate every frame. The orange square is moved by using transitions (rather than by every frame).
What is the best way to guarantee the orange object lands on the green object after every 3 bounces?
Make both the square and platforms position a function of time.
so the plaform position might be :
Xp = velocity * t
Yp = height of platform
the bouncing squares position is more complicated, but the x position is easy
Xb = velocityX * t
Yb is complicated by the bounce, as the discontinuity is hard to express.
If we assume no energy lost per bounce, so each bounce lasts the same time though :
Yb = (initialUpVelocityY * t mod bounceTime) - (0.5 * g * (t mod bouncetime)^2)
now solve for Xp = Xb and Yp = Yb and t= x * bouncetime

How to measure acceleration and deceleration of a vehicle?

Given the following data
Orientation of the device (CMAttitude - Quaternion or Rotation Matrix)
Acceleration Vector (CMAcceleration - userAcceleration --> without gravity)
Is there a way to get the acceleration and deceleration of a car placing the device in an arbitrary orientation into the car?
If not what would be the best approach to get the acceleration and deceleration by positioning the device in a fixed position inside the car?
Any hints or solution approached would be highly appreciated.
Thanks in advance!
Edit:
I tried to implement the suggested approach from this answer Using CMDeviceMotion and CMAttitude to isolate vertical or horizontal acceleration to isolate the vertical and horizontal acceleration.
I set the reference frame to CMAttitudeReferenceFrameXMagneticNorthZVertical
//Quaternion Conjugation
CMQuaternion quaternion = newMotion.attitude.quaternion;
GLKQuaternion conjugated_quaternion = GLKQuaternionMake(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
conjugated_quaternion = GLKQuaternionConjugate(conjugated_quaternion);
//Rotation of Accelerometer vector with quanternion
GLKVector3 acceleromationVector = GLKVector3Make(newMotion.userAcceleration.x, newMotion.userAcceleration.y, newMotion.userAcceleration.z);
GLKVector3 accelerometionVector_toReferenceFrame = GLKQuaternionRotateVector3(conjugated_quaternion, acceleromationVector);
//Horizontal Acceleration
float horizontalAcceleration = sqrtf(powf(accelerometionVector_toReferenceFrame.x,2)+powf(accelerometionVector_toReferenceFrame.y,2));
In the suggested answer the reference frame which should be used is North-East-Down. Would this be the same than CMAttitudeReferenceFrameXMagneticNorthZVertical? Or could it be that this is the wron reference frame and thus the results of this implementation turn out to be wrong?
You're looking for an algorithm not a functionality in the device itself. I don't believe there is a feature in any apple's iDevice that allows you to get the current ** deceleration/acceleration**
Use The Kinematic Equations: a = (Vf - Vi) / t
a: Acceleration
Vf: final velocity
Vi: initial velocity
t: time difference between Vi and Vf
This is what I would do to get the de/acceleration:
Calculate Vf = d/t say the car moves for a 10 km (this is d distance in meters) in 10 seconds (this is t time in seconds) you should be able get the final velocity Vf.
Assume Vi = 0 at first calculation then keep track of it by assigning current-Vi = previous-Vf
Calculate de/acceleration a = (Vf - Vi) / t
Remember deceleration is just a negative acceleration
Edit: You can also use userAcceleration defined in CMDeviceMotion.h

Xna 4.0 RTS camera

How do I make a RTS camera so that when the mouse is at the edge of the window, it will move either left/right/up/down. I been trying to create an invisible box at the side of the screen so that when the mouse is at the box it will move the camera, but it still doesn't work. Please help!
Building upon what #Davor Mlinaric said, using the mouses x and y coordinates (which can be gotten from Mouse.GetState()), and testing whether those coordinates come in contact with the top, bottom and sides of the screen.
It would be a good start to set where those boxes will be something along the lines of:
GraphicsDevice.Viewport.Width/Height -/+ offset
Where offset is the amount of distance from the top,bottom or side.
Then test where the mouse position is, with a boolean.
boolean inTheZone = false;
//Bottom Box
if(Mouse.GetState().Y > GraphicsDevice.Viewport.Height - offset)
{
//Move camera in the y axis downwards (+).
inTheZone = true;
}
else
{
inTheZone = false;
}
and then the same for the 4 remaining sides.
Notice ive also used Y here, depending on how you set up the camera this may change to Z.
I hope this helps

Resources