is Sprite Kit unit conversion meter->points 1:1? - ios

What is the ratio between meters and points in sprite kit?
'Cause on the apple documentation it says that the speeds and accelerations are in meter/sec - meters/sec^2, but it doesn't give a conversion in points/sec etc..
I tried measuring the speed of an object either with apple's sprites velocity attribute, either doing manually the calculation of the points per second, and I came up at a ca 1:1 ratio, meaning 1m/s = 1point/s.
Now, can anyone confirm that? or am I completely wrong?
Here is the code I used for the calculation:
double dt = currentTime - previousTime;
previousTime = currentTime;
double x = ball.physicsBody.velocity.dx;
double y = ball.physicsBody.velocity.dy;
double mod = sqrt(x*x+y*y);
double x2 = (ball.position.x-previousPosition.x)/dt;
double y2 = (ball.position.y-previousPosition.y)/dt;
double mod2 = sqrt(x2*x2+y2*y2);
if (mod2!=0){totalSpeed = totalSpeed + mod2;
j++;}
double mod3 = totalSpeed/j;
NSLog(#"Ball Speed: %.2f - %.2f - %.2f",mod,mod2,mod3);
previousPosition = ball.position;

Related

Alternative to CMPedometer to calculate number of steps with accelerometer on iOS

Since CMPedometer is not available for below iPhone5S.
CMPedometer StepCounting not Available
Is there an algorithm code that we can use to program number of steps with the accelerometer on ios ?
Thanks
IOS aside, there is no simple solution to create an accurate pedometer using just the accelerometer output; it's just to noisy. Using the output from a gyroscope(where available) to filter the output would increase the accuracy.
But a crude here's a crude approach to wiring code for a pedometer:
- steps are detected as a variation in the acceleration detected on the Z axis. Assuming you know the default acceleration(the impact of gravity) here's how you do it:
float g = (x * x + y * y + z * z) / (GRAVITY_VALUE * GRAVITY_VALUE)
Your threshold is g=1 (this is what you would see when standing still). Spikes in this value represent steps. So all you have to do is count the spikes. Please mind here that a simple g>1 will not do, as for one step, the g value will increase for a certain amount of time and then go back (if you plot the value over time, it should look like a sin wave when there is a step - essentially you want to count the sin waves)
Mind you that this is just something to get you started; you will have to add more complexity to it to increase accuracy.
Things like:
- hysteresis to avoid false step detection
- filtering the accelerometer output
- figuring out the step intervals
Are not included here and should be experimented with.
You can detect step Event using accelerometer data from CMMotionManager
protected CMMotionManager _motionManager;
public event EventHandler<bool> OnMotion;
public double ACCEL_DETECTION_LIMIT = 0.31;
private const double ACCEL_REDUCE_SPEED = 0.9;
private double accel = -1;
private double accelCurrent = 0;
private void StartAccelerometerUpdates()
{
if (_motionManager.AccelerometerAvailable)
_motionManager.AccelerometerUpdateInterval = ACCEL_UPDATE_INTERVAL;
_motionManager.StartAccelerometerUpdates (NSOperationQueue.MainQueue, AccelerometerDataUpdatedHandler);
}
public void AccelerometerDataUpdatedHandler(CMAccelerometerData data, NSError error)
{
double x = data.Acceleration.X;
double y = data.Acceleration.Y;
double z = data.Acceleration.Z;
double accelLast = accelCurrent;
accelCurrent = Math.Sqrt(x * x + y * y + z * z);
double delta = accelCurrent - accelLast;
accel = accel * ACCEL_REDUCE_SPEED + delta;
var didStep = OnMotion;
if (accel > ACCEL_DETECTION_LIMIT)
{
didStep (this, true);//maked a step
} else {
didStep (this, false);
}
}

How do I implement the area calculator using latitude and longitueds

Can any one help me , How do I implement the area calculator using in group of latitude and longitudes .
For Example One person walk around the building , I am getting the latitude and longitudes while walking time . I want calculate the how much square feet that building was constructed.
Well, I´m going to try to help you, but I´m not going to give the complete answer.
I think, the first step is convert lats and longs in a cartesian coordinate system. You should calculate the center of all points. (A simple median).
Second step, convert all points to ENU coordinates centered in its center:
This step, I did, and here you are:
Constants:
#define DEGREES_TO_RADIANS (M_PI/180.0)
#define WGS84_A (6378137.0) // WGS 84 semi-major axis constant in meters
#define WGS84_E (8.1819190842622e-2) // WGS 84 eccentricity
Structs:
//To change to ECEF
typedef struct{
double x;
double y;
double z;
} ECEFCoordinate;
typedef struct{
double east;
double north;
double up;
} ENUCoordinate;
Methods, (you need past through ECEF):
#pragma mark Geodetic utilities definition
-(ECEFCoordinate) ecefFromLatitude:(double)lat longitude:(double)lon andAltitude:(double)alt
{
double clat = cos(lat * DEGREES_TO_RADIANS);
double slat = sin(lat * DEGREES_TO_RADIANS);
double clon = cos(lon * DEGREES_TO_RADIANS);
double slon = sin(lon * DEGREES_TO_RADIANS);
double N = WGS84_A / sqrt(1.0 - WGS84_E * WGS84_E * slat * slat);
ECEFCoordinate ecef;
ecef.x = (N + alt) * clat * clon;
ecef.y = (N + alt) * clat * slon;
ecef.z = (N * (1.0 - WGS84_E * WGS84_E) + alt) * slat;
return ecef;
}
// Converts ECEF to ENU coordinates centered at given lat , lon (with ECEFCenter)
-(ENUCoordinate)enuFromECEFCenter:(ECEFCoordinate)ecefCenter withLat:(double)lat andLon:(double)lon fromEcef:(ECEFCoordinate)ecef
{
double clat = cos(lat * DEGREES_TO_RADIANS);
double slat = sin(lat * DEGREES_TO_RADIANS);
double clon = cos(lon * DEGREES_TO_RADIANS);
double slon = sin(lon * DEGREES_TO_RADIANS);
double dx = ecefCenter.x - ecef.x;
double dy = ecefCenter.y - ecef.y;
double dz = ecefCenter.z - ecef.z;
ENUCoordinate enu;
enu.east = -slon*dx + clon*dy;
enu.north = -slat*clon*dx - slat*slon*dy + clat*dz;
enu.up = clat*clon*dx + clat*slon*dy + slat*dz;
return enu;
}
Last step: (I think the easy way is use triangles, from center to two consecutive points), calculate the area of a bunch of points in a cartesian coordinate system (east,north). Same than (x,y).
Good luck.
Last help two calculate the Area, I think you can find more help (and maybe best way) trough internet.

iOS Generate Square Sound

I want to generate a square wave sound on iPhone, I found a sine wave code on Web (sorry forgotten the link), but i want to generate Square wave format.
Could you help me please?
const double amplitude = 0.25;
ViewController *viewController =
(__bridge ViewController *)inRefCon;
double theta = viewController->theta;
double theta_increment = 2.0 * M_PI * viewController->frequency / viewController->sampleRate;
const int channel = 0;
Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData;
for (UInt32 frame = 0; frame < inNumberFrames; frame++)
{
buffer[frame] = sin(theta) * amplitude;
theta += theta_increment;
if (theta > 2.0 * M_PI)
{
theta -= 2.0 * M_PI;
}
}
viewController->theta = theta;
Sum of the odd harmonics
A perfect square wave is the sum of all the odd harmonics divided by the harmonic number up to infinity. In the real world you have to stop of course - specifically at the nyquist frequency in digital. Below is a picture of the fundamental plus the first 3 odd harmonics. You can see how the square begins to take shape.
In your code sample, this would mean wrapping the sine generation in another loop. Something like this:
double harmNum = 1.0;
while (true)
{
double freq = viewController->frequency * harmNum;
if (freq > viewController->sampleRate / 2.0)
break;
double theta_increment = 2.0 * M_PI * freq / viewController->sampleRate;
double ampl = amplitude / harmNum;
// and then the rest of your code.
for (UInt32 frame = ....
The main problem you'll have is that you need to track theta for each of the harmonics.
A cheater solution
A cheat would be to draw a square like you would on paper. Divide the sample rate by the frequency by 2 and then produce that number of -1 and that number of +1.
For example, for a 1kHz sine at 48kHz. 48000/1000/2 = 24 so you need to output [-1,-1,-1,....,1,1,1,.....] where there are 24 of each.
A major disadvantage is that you'll have poor frequency resolution. Like if your sample rate were 44100 you can't produce exactly 1kHz. because that would require 22.05 samples at -1 and 22.05 samples at 1 so you have to round down.
Depending on your requirements this might an easier way to go since you can implement it with a counter and the last count between invocations (as you're tracking theta now)

Make object move in a circle

I'm a beginner at programming, and I've been trying to make an object orbit around another object (or just move in a circle). But I haven't succeeded very well. Any ideas?
You need some constants to specify radius and speed:
const float speed = 100.0f;
const float radius = 50.0f;
you also need some variable to store angle:
float angle;
- (void)updateObject:(NSTimeInterval)dt
{
angle += speed * dt;
angle = fmodf(angle, 360.0f);
float x = cosf(DEGREES_TO_RADIANS(angle)) * radius;
float y = sinf(DEGREES_TO_RADIANS(angle)) * radius;
float newXPosition = _yourSprite.position.x + x;
float newYPosition = _yourSprite.position.y + y;
//Assign the values to your sprite
_yourSprite.position = ...
}
Try connecting two nodes with SKPhysicsJointLimit, with the first node not movable (maybe not dynamic), set the linear damping of the second node to zero and disable gravitation forces on it. It also should not collide with any other object, of course.When the joint is stretched to its maximum and you apply an Impulse vertical to the connection between the two objects, the object should start orbiting around the other one.
I have not tested this one.

Collision accuracy

Not quite sure how to word this but I've been using
if (CGRectIntersectsRect(ball.frame, bottom.frame)) {
[self finish ];
}
for my collision detection and it run the code perfectly but the ball sometimes collides with the bottom and runs the code but you can clearly see there is a gap in between the objects. i have created the images my self and they have no background around them. i was wondering if theres any other way of coding it or making it so the it doesn't run the code until the intersect x amount of pixels into one another.
You can implement ball-line collision in many ways. Your solution is in fact a rectangle - rectangle collision detection. Here is how I did it in one of my small gaming projects. It gave me best results and it's simple.
Let's say that a ball has a ballRadius, and location (xBall, yBall). The line is defined with two points (xStart, yStart) and (xEnd, yEnd).
Implementation of a simple collision detection:
float ballRadius = ...;
float x1 = xStart - xBall;
float y1 = yStart - yBall;
float x2 = xEnd - xBall;
float y2 = yEnd - yBall;
float dx = x2 - x1;
float dy = y2 - y1;
float dr = sqrtf(powf(dx, 2) + powf(dy, 2));
float D = x1*y2 - x2*y1;
float delta = powf(ballRadius*0.9,2)*powf(dr,2) - powf(D,2);
if (delta >= 0)
{
// Collision detected
}
If delta is greater than zero there are two intersections between ball (circle) and line. If delta is equal to zero there is one intersection – perfect collision.

Resources