Frame-independent animation in game developement on android - android

Ok so delta-time is 1/fps right? Say the fps was 50, then delta time would equal 1/50= 0.02. My question is that frame rate varies(one second it might be 50, another it might be 52). So say for one second the fps is 50, that means that delta time will be equal to 0.02, but the NEXT second the fps will be 52, but we don't know that yet. So our animations are being done with delta time of 1/50 but the fps is actually 52. Until the next second is finished we won't know that the fps has changed. This may not seem like a big deal if the changes are small, but if they become very big then we have a problem. So the thing is we are always doing calculations based on the previous second's fps. I want to know how to solve this. Thanks!

You're right that 1/fps = delta-time. However, fps isn't known at the present, and as you pointed out going about it this way would cause a problem! In practice, the formula is re-arranged such that 1/dt = fps.
So, we determine delta-time by determining how much time has passed since the last update( deltaTime = (CurrentTime - LastTime) ). If we were to have a variable that we add delta time to every every update (say, deltaCounter += deltaTime), and another variable which is a counter we add one to each update (Counter++), we would see that when deltaCounter is becomes equal to 1, the Counter variable is our fps for that second.
Further Reading on Delta Time and its Implementation

Related

JodaTime: Print Period as Days:Hours:Minutes:Seconds

Oddly I'm having the inverse problem to many similar posts; I'm trying to use JodaTime (on Android) to give me a dd:hh:mm:ss type output and failing miserably. Code is;
public String GetEventTimeString(boolean withMS, int eventTime)
{
Period p = new Period(eventTime, PeriodType.yearMonthDayTime());
if (withMS)
return _formatter_withms.print(p);
else return _formatter_withoutms.print(p);
}
When I use the debugger to halt after p is set, I see that p itself has the hours value set to 568 and the days value is zero, so I've not posted the code that creates the formatters. eventTime is an int representing elapsed time in ms and has a value of 2045489151 in this case.
In case there's some oddity with the size of the number and the fact it's an int instead of a long, I tried making a new Period(1500000L, PeriodType.yearMonthDayTime()) and got a period of 0 days, 25 hours, 0 minutes and seconds.
Exploring the structure of the iType member of the period, I see an array iTypes containing elements "years", "months" etc. I also see an array iIndices which appears to map types to elements in some other array. Most indices make sense, but the index corresponding to "Days" is -1. So it seems PeriodType.yearMonthDayTime() isn't doing what I think the docs say it should.
If I try PeriodType.yearWeekDayTime I get the same result. If I try PeriodType.yearWeekDay then the three fields are zero with my 25 hour test value. So it's not just the one PeriodType that's misbehaving.
Wondering about the coincidence of getting exactly 25 hours from my fairly arbitrary (picked a number and kept adding zeroes) 1500000ms, I tried 1510000 and got 25h 10m 0s. But neither of those actually makes any sense when you work the conversion manually!
This is on Android, up to date Android Studio 1.3.2, not sure how to tell what version JodaTime I'm using but it's within the last few months and this seems a bit too glaringly obvious to be an obscure bug- more a combination of misunderstanding and digging too deep on my part I think.
Does anyone have any thoughts on what's going on?
Well, Joda-Time says about the normalization of a millisecond-based period:
Creates a period from the given millisecond duration. Only precise
fields in the period type will be used. Imprecise fields will not be
populated.
Here the question arises: Is the day unit a precise field in context of Joda-Time? No because a day can have 23 or 25 hours when it comes to switching daylight-saving time on/off in many countries (in reality there are even more possibilities like 23.5 hours etc). So the constructor you call does not fill the day-unit-field.
How can you get the desired normalization effect? Just do this recommended approach (no normalization in constructing the period):
long eventTime = 2045489151;
Period p = new Period(eventTime, PeriodType.millis());
System.out.println(p); // PT2045489.151S (no normalization)
System.out.println(p.normalizedStandard(PeriodType.dayTime()));
// P23DT16H11M29.151S
System.out.println(p.normalizedStandard(PeriodType.yearMonthDayTime()));
// P23DT16H11M29.151S ( the same result as one line before, not the best period type)
It is for debate IMHO that the Period-constructor, you used does a partial normalization. In my opinion either a full normalization using the given period type or no normalization at all (preferred by me - just leaving the milliseconds as millis, but then the second constructor argument is simply silly) would have been a wiser design decision. Interestingly (and confusing, too), the constructor without explicit period type argument does a partial normalization, too. To avoid premature incomplete normalization in constructor, you have to explicitly specify the period type as PeriodType.millis(). Sorry for your confusion.

Making a decibel meter (first android app), problems converting Amplitude to Decibels

As a part of a larger aplication I am currently working on a decibel meters that takes the average sound level of a 10 second timespan.
To achieve this I made a CountDownTimer of 10 000 miliseconds that ticks every 100 miliseconds.
In each onTick event I update the textfield that shows the time left, and I also update the realtime decibel value.
My issue however is converting the maximum amplitude to decibels. I found the "power_db = 20 * log10(amp / amp_ref);" formula here on StackOverflow and I understand how it works, but I seem to always end up with a negative decibel value.
I understand that this is because of a wrong amp_ref value, but I am absolutely stumped on which one I should use. I found alot of different values on the web and none seem to do the trick.
Does anyone have any idea which reference amplitude I should use to get the correct decibel reading on my meter? The phone I am testing this on is a Google Nexus 5. For now it would be good enough if it only was a really accurate value on this phone if thats of any help.
The code I have in my onTick event is the following (I removed the formula for now since it seemed to be wrong anyways):
public void onTick(long ms) {
meetBtn.setText(String.valueOf((ms/1000)+1));
amplitude = mRecorder.getMaxAmplitude();
decibelView.setText(String.valueOf(amplitude));
}
If anyone has any tips or needs more information, please let me know!
Thanks in advance! :)
Negative decibels are fine, because it's a relative measure anyway. In fact it's a common practice to take the maximum possible amplitude as a reference point and as a result have decibels go from 0 down to negative space. Pro systems usually indicate positive decibels as an overload when clipping and distortions of sound may occur.
So for example if your amplitude range is 0 to 1 (an accepted float-PCM standard), then your amp_ref would be 1 and your decibel values will go from some negative value that depends on the bitness resolution of your source (e.g. -186dB for 32 bit, or -90dB for 16-bit source), up to 0dB. This is normal!
Edit: actually, your float-PCM amplitude range is -1 to 1, but decibel calculation "drops" the minus sign and gives the same result for both negative and positive amplitudes.

Fast way to access Mat from Opencv on Android?

I need to modify/access my mat on Android, but it is really really slow (it took about 2 minutes to run on a 3500*100 mat).
I need to set some value to 0, but not all, and I am using this line to modify it.
this.getMyMat().put(i, j, 0);
Any idea to get it a bit faster ? My code in C++ takes at least 50 times less time to run, doing this way :
((myMat.data + myMat.step*row))[j] = 0
You can use rowRange() or colRange() to extract the submatrix you wish to be zeroed out, and call setTo() to actually fill in the values. This will be faster than iterating pixel-by-pixel.
Mat rows = this.getMyMat().rowRange(0,3);
rows.setTo(new Scalar(0));

how to give random time interval in images in android

In my app, animated image should repeat every time with different time interval.
like i want any of between 1000 to 5000.
I applied below code but this not work properly. Image move very fast.
So, plz help me out of this problem.
Random gen = new Random();
anim.setDuration(new Random().nextInt(5000-1000+1));
I think you just need to set interpolator.
anim.setInterpolator(new AccelerateDecelerateInterpolator());
So its speed will be proportioned
First of all - you even didn't check values returned by nextInt(5000-1000+1).If you check this you will discover that values are from 0 to 4001.
If you need values from 1000 to 5000 use:
anim.setDuration(1000 + gen.nextInt(4000));

How to calculate moving average speed from GPS?

I'm developing an android application using GPS. I'd like to implement a feature that displays the users average speed over the 1/5/15 minute. Something like the CPU load on unix. I can calculate average easily by cumulating the distance traveled second by second and divide it by the elapsed time, but I can't think of a smart way of calculating the moving average.
Obviously I can get id done by putting the distance between the last and the current position in an array every second while deleting the oldest value.
I'm looking for a neat way of doing this.
Heres one way to go about it that is pretty straight forward:
If you are sampling position every second keep 901 samples in a queue, thats 15 mins worth (and 1 extra).
Position 0 is the most recent measurement, effectively your current position.
For an average speed over the last X minutes:
s = X * 60;
point1 = postion_queue[0]; // this is your current position
point2 = postion_queue[s]; // this is your position s seconds ago
d = distance_between_points(point1, point2);
speed = d / s;
speed is now distance units per second, convert to mph, or kph or whatever units you need. Different values of X can be used for any average between 1 and 15 minutes.
You will need to store all the values for the whole time span, as you already suggested. The reason is that you somehow need to "forget" the contributions of the old values to the moving average. You can't do that exactly if you don't know what these values where (i.e. if you do not store them).
In your case, 1 value each second for 15 minutes amounts to 15 * 60 = 900 data points, that should be OK.
Note that you do not need to perform a sum over the whole array each time you update: You can calculate the new moving average from the number of data points, the new value and the value you are "forgetting" at that moment:
new_average = (n * old_average - x_forget + x_new) / n
Here, n is the number of data points (900 in your case), x_forget is the value you are "forgetting" and x_new is the latest value. You then drop x_forget from the front of your array and store x_new at the end. Instead of an array you might want to use a queue implemented via a linked list.

Categories

Resources