Logarithmic calculation in Objective-C [duplicate] - ios

This question already has answers here:
What kind of logarithm functions / methods are available in objective-c / cocoa-touch?
(3 answers)
Closed 9 years ago.
I am building a game using Sprite Kit and I want to gradually increase the difficulty (starting at 1.0) based on the time since starting the game.
Someone suggested that I should use a logarithmic calculation for this but I'm unsure how to implement this in Objective-C.
- (float)difficulty
{
timeSinceStart = ???; // I don't what kind of object this should be to make it play nice w/ `log`
return log(???);
}
Update #1
I know that I need to use the log method but I'm uncertain what values I need to pass to it.

Objective C is a superset of the C language, therefore you can use "math.h".
The function that computes the natural logarithm from "math.h" is double log(double x);
EDIT
Since you want the difficulty to increase as a function of time, you would pass the time as the argument to log(double x). How you would use that to calculate and change the "difficulty" is an entirely different question.
If you want to change the shape of the curve, either multiply the expression by a constant, as in 2*log(x) or multiply the parameter by a constant, as in log(2*x). You will have to look at the individual curves to see what will work best for your specific application.

Since log(1.0) == 0 you probably want to do some scaling and translation. Use something like 1.0 + log(1.0 + c * time). At time zero this will give a difficulty of 1.0, and as time advances the difficulty will increase at a progressively slower pace whose rate is determined by c. Small values such as c = 0.01 will give a slow ramp-up, larger values will ramp-up faster.

#pjs gave a pretty clear answer. As to how to figure out the time: You probably want the amount of time spent actually playing, rather than elapsed time since launching the game.
So you will nee to track total time played, game after game.
I suggest you create an entry in NSUserDefaults. You can save and load double values to user defaults using the NSUserDefaults methods setDouble:forKey: and doubleForKey:
I would create an instance variable startPlayingTime, type double
When you start the game action running, capture the start time using
startPlayingTime = [NSDate timeIntervalSinceReferenceDate];
When the user passes the game/exits to the background, use
NSTimeInterval currentPlayTime = [NSDate timeIntervalSinceReferenceDate] - startPlayingTime;
Then read the total time played from user defaults, add currentPlayTime to it, and save it back to user defaults.
You can then make your game difficulty based on
difficulty = log(1+ c * totalPlayTime);
(as explained by pjs, above) and pick some appropriate value for C.

Related

Measure (frequency-weighted) sound levels with AudioKit

I am trying to implement an SLM app for iOS using AudioKit. Therefore I need to determine different loudness values to a) display the current loudness (averaged over a second) and b) do further calculations (e.g. to calculate the "Equivalent Continuous Sound Level" over a longer time span). The app should be able to track frequency-weighted decibel values like dB(A) and dB(C).
I do understand that some of the issues im facing are related to my general lack of understanding in the field of signal and audio processing. My question is how one would approach this task with AudioKit. I will describe my current process and would like to get some input:
Create an instance of AKMicrophone and a AKFrequencyTracker on this microphone
Create a Timer instance with some interval (currently 1/48_000.0)
Inside the timer: retrieve the amplitude and frequency. Calculate a decibel value from the amplitude with 20 * log10(amplitude) + calibrationOffset (calibration offset will be determined per device model with the help of a professional SLM). Calculate offsets for the retrieved frequency according to frequency-weighting (A and C) and apply these to the initial dB value. Store dB, dB(A) and dB(C) values in an array.
Calculate the average for arrays over the give timeframe (1 second).
I read somewhere else that using a Timer this is not the best approach. What else is there that I could use for the "sampling"? What exactly is the frequency of AKFrequencyTracker? Will this frequency be sufficient to determine dB(A) and dB(C) values or will I need an AKFFTTap for this? How are values retrieved from the AKFrequencyTracker averaged, i.e. what time frame is used for the RMS?
Possibly related questions: Get dB(a) level from AudioKit in swift, AudioKit FFT conversion to dB?

How do I find the required maxima in acceleration data obtained from an iPhone?

I need to find the number of times the accelerometer value stream attains a maximum. I made a plot of the accelerometer values obtained from an iPhones against time, using CoreMotion method to obtain the DeviceMotionUpdates. When the data was being recorded, I shook the phone 9 times (where each extremity was one of the highest points of acceleration).
I have marked the 18 (i.e. 9*2) times when acceleration had attained maximum in red boxes on the plot.
But, as you see, there are some local maxima that I do not want to consider. Can someone direct me towards an idea that will help me achieve detecting only the maxima of importance to me?
Edit: I think I have to use a low pass filter. But, how do I implement this in Swift? How do I choose the frequency of cut-off?
Edit 2:
I implemented a low pass filter and passed the raw motion data through it and obtained the graph as shown below. This is a lot better. I still need a way to avoid the insignificant maxima that can be observed. I'll work in depth with the filter and probably fix it.
Instead of trying to find the maximas, I would try to look for cycles. Especially, we note that the (main) minimas seem to be a lot more consistent than the maximas.
I am not familiar with swift, so I'll layout my idea in pseudo code. Suppose we have our values in v[i] and the derivative in dv[i] = v[i] - v[i - 1]. You can use any other differentiation scheme if you get a better result.
I would try something like
cycles = [] // list of pairs
cstart = -1
cend = -1
v_threshold = 1.8 // completely guessing these figures looking at the plot
dv_threshold = 0.01
for i in v:
if cstart < 0 and
v[i] > v_threshold and
dv[i] < dv_threshold then:
// cycle is starting here
cstart = i
else if cstart > 0 and
v[i] < v_threshold and
dv[i] < dv_threshold then:
// cycle ended
cend = i
cycles.add(pair(cstart, cend))
cstart = -1
cend = -1
end if
Now you note in comments that the user should be able to shake with different force and you should be able to recognise the motion. I would start with a simple 'hard-coded' cases as the one above, and see if you can get it to work sufficiently well. There is a lot of things you could try to get a variable threshold, but you will nevertheless always need one. However, from the data you show I strongly suggest at least limiting yourself to looking at the minimas and not the maximas.
Also: the code I suggested is written assuming you have the full data set, however you will want to run this in real time. This will be no problem, and the algorithm will still work (that is, the idea will still work but you'll have to code it somewhat differently).

Interpolating and predicting CLLocationManager

I need to get an updated user location with at least 10 hz to animate the location smoothly in MapBox for iOS while driving. Since Core Location only provides one point every second I believe I need to do some prediction.
I have tried ikalman but it doesn`t seem to do any difference when updated once a second and queried at 10 hz.
How do i tackle this please?
What you're looking for is extrapolation, not interpolation.
I'm really, really surprised that there's so few resources on extrapolation on the internet. If you want to know more you should read some numerical methods/math book and implement the algorithm yourself.
Maybe simple linear extrapolation will suffice ?
// You need two last points to extrapolate
-(double) getExtrapolatedValueAt:(double)x withPointA:(Point*)A andPointB(Point*)B
{
// X is time, Y is either longtitute or latitude.
return A.y + ( x - A.x ) / (B.x - A.x) * (B.y - A.y);
}
-(Point*) getExtrapolatedPointAtTime:(double)X fromLatitudeA:(Point*)latA andLatitudeB:(Point*)latB andLongtitudeA:(Point*)longA andLongtitudeB:(Coord*)longB
{
double extrapolatedLatitude = [self getExtraploatedValueAt:X withPointA:latA andPointB:latB];
double extrapolatedLongtitude = [self getExtrapolatedValueAt:X withPointA:longA andPointB:longB];
Coord* extrapolatedPoint = [Coord new];
extrapolatedPoint.longtitude = extrapolatedLongtitude;
extrapolatedPoint.latitude = extrapolatedLatitude;
return extrapolatedPoint;
}
Not sure if I got the function right but you can check here:
http://en.wikipedia.org/wiki/Extrapolation
it's really easy.
You should implement the linear extrapolation.
If you find out that linear extrapolation isn't enough (for curves for example) you should just iterate and change it with some other extrapolation algorithm.
Another approach would be to have a 1 sec delay in animation and animate between two known points using interpolation. I don't know if that's acceptable for your use case.
This problem is typically solved with something called "Dead Reckoning". And you're right on track with trying to use a Kalman filter for doing this. If iKalman isn't working for you, you can try to resort to a simpler approach.
There's a lot of this sort of problem solving when dealing with games and network latency, so you can likely reuse an algorithm developed for this purpose.
This seems like a pretty thorough example.
The wiki on Kalman filters may help out as well.
I ended up solving this by using long UIView animations instead (2-3) seconds with easing that start from the current state. This gives the impression of smooth position and heading following "for free".

Cocos2d, iOS, Objective-C: float error [duplicate]

This question already has answers here:
How dangerous is it to compare floating point values?
(12 answers)
Error subtracting floating point numbers when passing through 0.0
(4 answers)
Closed 9 years ago.
I tested this on a empty project and does not happen.
As you can see the newValue becomes 2.98023e-08 when I subtract the bossPercentage value.
This happens only when bossPercentage is 0.2f and the previous value is 0.2f.
The difference should be 0.0f but I don't understand why I get 2.98023e-08 instead.
For reference, remainingBossPercentage is a property in [GameController] class defined as following:
//header
#property (readwrite, nonatomic) float remainingBossPercentage;
//.m
#synthetize remainingBossPercentage;
//init
remainingBossPercentage=1.0f;
I'd like to ask you inisght on what I may be doing that causes this error.
EDIT: I subtract 0.2f to remainingBossPercentage (for each boss enemy) and everything works fine until I reach the last enemy object that has again 0.2f and I get to the crucial point of doing 0.2f - 0.2f (screenshot below)
EDIT 2: I am greatful for all comments and answers, also the closing votes. What induced me to ask this question is the fact that newValue is 2.98023e-08. I now see that there are also comparison issues (thanks to the extremely useful QA linked by the people that voted to close the answer). What I wonder is.. why in my new test project with only 2 test variables this does not happen? (I created a HelloWorld project that substracts two floats).
I am asking this because, as one of the user suggests, is important to understand floating points without taking shourtcuts. YES, I am taking a shortcut by asking this question because I don't have time tonight to study it properly but I would like to try understanding and learning at the best I can. I will read the answers properly and dedicate my time to understand but if in the meanwhile I can I would like to add a doubt:
could it be that for memory management reasons the two projects (the test one and my actual game) beheave differently? Could the different beheaviour of the two projects somehow linked with memory being swapped in dirty areas? (e.g. the game having bigger memory usage gets swapped more and hence there may be a loss of precision?)
PS: I found out a question with exactly the same 2.98023e-08 value. What I still wonder is why this doesn't happen in the same test project (I am doing some more testing now).
Simply, floating point numbers should not be expected to be completely accurate.
Floating point numbers (as used in our usual computers) are natively in base 2, out usual number is base 10. Not all numbers in one number base can be expressed with full accuracy in another number base.
As an empale 1/3 can not be expressed with complete accurate in the base 10 number system (0.333333...) but can be in the base 3 number system.
The upshot, one needs to compare floating point numbers with a specified error range. Take the absolute value of the difference and compare that to the allowable range.
Because of this financial amounts are generally not (should not be) expressed as floating point numbers. This give rise to classes such as NSDecimalNumber.

Simulating probability with stdlib.h on device (e.g. iPhone)

Stupid stupid question but here we are..
so, I want to generate some random events in an iOS application (in my case a game). I have written a function "verifyEvents" that I call each time I load a particular view (game scene).
To associate a probability to an event I assigned a value to each event (e.g. kill player: 0.05, give extra bonus 0.08).
In the function I generate a random number using CCRANDOM_0_1(), an iOS macro based on the random() function defined in stdlib.h. If the number is less than the assigned value I trigger the event (below there is the code).
#define CCRANDOM_0_1() ((random() / (float)0x7fffffff ))
Is this the best approach or do you use something else in your apps?
-(void) verifyEvents
{
float value = CCRANDOM_0_1() ;
float eventPValue = 0.05f;
if(value<eventPValue){
CCLOG(#"EVENT!");
}
}
Ok, following the suggestion of #lukya I asked the question on gamedev and did some more research. By far I got two answer which seem quiet interesting (which should be read together with the comments on my question).
EDIT: Forgot to put the link here as well (was only in the comment):
https://gamedev.stackexchange.com/questions/33236/simulating-probability

Resources