How do I make a clock second hand move with 4 jumps/ticks per second? - swift4

EDIT: Needed help to get exactly 3 ticks per second, but that's not possible because of fractions. Double checking the real life clock I realized it actually moves 4 ticks per second, I'm thinking a quarter second is even and should be able to be exact. Updated the question since I can't get that to work either:
I'm building a clock that has three options of how the second hand will move. I've successfully made the seconds move 6° per second (1 "tick" per second) and one option with a seamless sweep (0.006° per millisecond). But I can't get my formula to work for my third option: having the second hand move exactly 4 times per second, i.e. 1.5° every quarter of a second).
This is the line of code for the second hand (I use CGAffiateTransform later, hence the radians):
let quarterSecond = round(millisecond * 4.0 / 1000.0)
let tickingSeconds = (((1.5 * π / 180) * quarterSecond) + ((6.0 * π / 180) * second))
This does what I want but I don't like the round as it makes the movement inexact. The whole timer interval is set to 0.001 and I have a hard time believing that you can't make the second hand move precisely 4 "ticks" per second without doing some uneven jerks every now and then.
Any ideas?

What you intuitively think as ticking is how often your expression changes value.
Here, your entire expression is constant except for second. Which means that your expression can only change when second change. If it is an integer, it can only change every second.
You need a variable that changes thrice a second, you can approximate that using millisecond and a truncation (to remove the fractional part):
let thrice_a_second = (millisecond * 3.0 / 1000.0).round()
Only then you can use that expression to compute the new position, knowing that it increases by 1 thrice a second.

Related

Simulink - Output 1 every 30 seconds, 0 otherwise

I need a subsystem that needs to output 1 at interval or 30 seconds or slightly over 30 seconds.
Written in matlab code it should work like that
function y = fcn(time,uplinkTimeInterval)
%#codegen
persistent lastTriggerTime
if isempty(lastTriggerTime)
lastTriggerTime = 0;
end
if time>=lastTriggerTime || time == 0
y = 1;
lastTriggerTime = time + uplinkTimeInterval;
else
y = 0;
end
end
where ulplinkTimeInterval is 30 seconds. Of course I tried to use the matlab function block with this code but for some reason it does not work (in debug mode I can see that y takes value 1 as it should but it simply does not ouput the value outside the block), therefore I wanted to use blocks but I do not know how to do it.
Thanks very much for your help
You can make this logic relatively easily with code or blocks. As you requested a solution using blocks, here it is!
Use the clock block to keep track of time, and some constant block to determine the interval (in seconds) at which to give 1 instead of 0.
Use the memory block to delay the clock signal by 1 timestep, so we can compare consecutive steps' values.
Divide the times by the interval, and round down, to give how many intervals have passed.
Finally, compare consecutive "number of intervals passed" using a relational operator. If more intervals have passed on the upper line, then you have just stepped over the interval threshold.
Note: this will return a 0 for every timestep where you have not crossed a new interval, and a 1 at each individual timestep where you have. The accuracy of the output will depend on the step size of your model.
Edit: It may be clearer / easier to just add the memory block after the floor block, so you are only doing the division / rounding once. It would still allow you to do a comparison to the previous time step. That would look like:
Easiest way to do this is with a just a single Pulse Generator block, set to have a "high" of 1 every 30 seconds. That is shown as part of the image below. The signal will be high for whatever the percentage of the period is specified in the block dialog.
If for some reason you really need to use a subsystem then use a Triggered and Enabled Subsystem (See top right of image). Feed the same pulse signal into both the trigger and the enable port, and set the outport inside the subsystem to have Output when disabled to reset, and to have an Initial Output of 0 (See the lower right of the image).
The model below shows how to do this. In this instance the pulse has been set to have a period of 30s with the rising edge happening every 1% of that period (See the top left of the image).
The output signal will be high for one time step every time the input rises (assuming the trigger is set to rising edge.)

How do I get a SKAction to repeat itself after a random period of time

I currently have the below code that happily repeats an action every 2 seconds, but I want it to happen at a completely random period of time, e.g sometime between 1 and 10 seconds, I tried a few different lines of code using arch4random of which none worked. I'm hoping its a simple fix, any advice is greatly appreciated.
Thanks runAction(SKAction.repeatActionForever(SKAction.sequence([SKAction.runBlock(callBird), SKAction.waitForDuration(2.0)])))
If you are trying to randomize a duration parameter, a
+ waitForDuration:withRange: will do the job.
runAction(
SKAction.repeatActionForever(
SKAction.sequence([SKAction.runBlock({/*do your stuff*/}),
SKAction.waitForDuration(2, withRange: 3) ])))
From the docs :
Each time the action is executed, the action computes a new random
value for the duration. The duration may vary in either direction by
up to half of the value of the durationRange parameter.
Means that if a duration is set to 2 and a range parameter is set to 3, a possible duration value will vary between 0.5 and 3.5.

Why isn't Time.deltaTime equal to the sum of element.deltaTime in all the elements of Input.accelerationEvents?

Time.deltaTime gives you the time passed in the last frame.
Input.accelerationEvents contains an array of the last reads of the accelerometer and its time.
I'd guess that after
totalTime = 0;
foreach (AccelerationEvent element in Input.accelerationEvents){
totalTime +=element.deltaTime;
}
the result would be equal to Time.deltaTime, but it isn't. What am I missing?
The AccelerationEvent.deltaTime variable returns the amount of time since the last sampling of the device's accelerometer. However, this sampling is not guaranteed to be synchronized with game framerate (even though both aim to achieve 60Hz), and as such the sum of the deltaTime of all Input.accelerationEvents during a frame may not equate the Time.deltaTime of that frame.
The the Unity documentation mentions something to this effect:
[...] In reality, things are a little bit more complicated – accelerometer
sampling doesn’t occur at consistent time intervals, if under
significant CPU loads. As a result, the system might report 2 samples
during one frame, then 1 sample during the next frame.
One way to visualize this is with the following (assume each dash is one arbitrary unit of time):
Frames completed:
1-----2-----3-----4-----5-----6-----7-----8-----9-----
Accelerometer samples made:
1-----2-----3-----4------5-----6---7-----8-----9-----
Note that while frame6 is being completed, both sample6 and sample7 were made. However, although frame6.deltaTime = 5, the sum of sample6.deltaTime + sample7.deltaTime = 5 + 3 = 8. As a result, their times don't match up.
Hope this helps! Let me know if you have any questions.
Here's what they say in Unity documentation regarding accelerometer http://docs.unity3d.com/Manual/MobileInput.html
Unity samples the hardware at a frequency of 60Hz and stores the result into the >variable. In reality, things are a little bit more complicated – accelerometer >sampling doesn’t occur at consistent time intervals, if under significant CPU >loads. As a result, the system might report 2 samples during one frame, then 1 >sample during the next frame
Also don't forget that
AccelerationEvent.deltaTime is Amount of time passed since last accelerometer measurement.
And Time.deltaTime is the time in seconds it took to complete the last frame.
Those values are independent and there is no reason for them to be equal to each other.

Operating system- Time Slice

Suppose a multiprogramming operating system allocated time slices of 10 milliseconds and the machine executed an average of five instructions per nanosecond.
How many instructions could be executed in a single time slice?
please help me, how to do this.
This sort of question is about cancelling units out after finding the respective ratios.
There are 1,000,000 nanoseconds (ns) per 1 millisecond (ms) so we can write the ratio as (1,000,000ns / 1ms).
There are 5 instructions (ins) per 1 nanosecond (ns) so we can write the ratio as (5ins / 1ns).
We know that the program runs for 10ms.
Then we can write the equation like so such that the units cancel out:
instructions = (10ms) * (1,000,000ns/1ms) * (5ins/1ns)
instructions = (10 * 1,000,000ns)/1 * (5ins/1ns) -- milliseconds cancel
instructions = (10,000,000 * 5ins)/1 -- nanoseconds cancel
instructions = 50,000,000ins -- left with instructions
We can reason that it is at least the 'right kind' of ratio setup - even if the ratios are wrong or whatnot - because units we are left with instructions, which is matches the type of unit expected in the answer.
In the above I started with the 1,000,000ns/1ms ratio, but it could also have done 1,000,000,000ns/1,000ms (= 1 second / 1 second) and ended with the same result.

iphone BPM tempo button

i want to create a button that allows the user to tap on it and thereby set a beats per minute. i will also have touches moved up and down on it to adjust faster and slower. (i have already worked out this bit).
what are some appropriate ways to get the times that the user has clicked on the button to get an average time between presses and thereby work out a tempo.
Overall
You best use time() from time.h instead of an NSDate. At the rate of beats the overhead of creating an NSDate could result in an important loss of precision.
I believe time_t is guaranteed to be of double precision, therefore you're safe to use time() in combination with difftime().
Use the whole screen for this, don't just give the user 1 small button.
Two idea
Post-process
Store all times in an array.
Trim the result. Remove elements from the start and end that are more than a threshold from the average.
Get the average from the remaining values. That's your speed.
If it's close to a common value, use that.
Adaptive
Use 2 variables. One is called speed and the other error.
After the first 2 beats calculate the estimated speed, set error to speed.
After each beat
queue = Fifo(5) # First-in, first-out queue. Try out
# different values for the length
currentBeat = now - timeOflastBeat
currentError = |speed - currentBeat|
# adapt
error = (error + currentError) / 2 # you have to experiment how much
# weight currentError should have
queue.push(currentBeat) # push newest speed on queue
# automatically removes the oldest
speed = average(queue)
As soon as error gets smaller than a certain threshold you can stop and tell the user you've determined the speed.
Go crazy with the interface. Make the screen flash whenever the user taps. Extra sparks for a tap that is nearly identical to the expected time.
Make the background color correspond to the error. Make it brighter the smaller the error gets.
Each time the button is pressed, store the current date/time (with [NSDate date]). Then, the next time it's pressed, you can calculate the difference with -[previousDate timeIntervalSinceNow] (negative because it's subtracting the current date from the previous), which will give you the number of seconds.