Canvas, Ball / Clock inaccurate

227 views
Skip to first unread message

BodyMindPower

unread,
Jan 31, 2019, 4:23:42 AM1/31/19
to MIT App Inventor Forum
I want to expand and contract a ball (radius from 0 to 100). I use Canvas / Ball (Drawing and Animation) and 3 Clocks to set the duration for expanding and contracting. Unfortunately, there are - as often - problems with the clocks. The duration is imprecise and varies. If I set 1 sec duration, the expansion of the ball takes 1.6 to 1.8 sec (depending from the device). At 2 sec it is actually 2.3 to 2.5 sec and so on.

The clocks tick every 10ms when selecting 1 sec. When selecting 2 sec every 20ms and so on.

Is there a way that this works exactly. I would like to add an acoustic metronome to the app, which will tick exactly every sec (1000ms) and show the expired sec continuously (1,2,3, ...). Of course, this has to happen synchronously.

Here is a simple example project with only this aspect. (I have not worked with Canvas so far, so I'm not very familiar with it yet. I also tried solving the problem only with Canvas.DrawCircle, the same thing.)

Thanks,
Anke

Screenshot_1s.jpg
Screenshot_2s.jpg
Designer.jpg
expandContractBall.aia

Ghica

unread,
Jan 31, 2019, 10:18:58 AM1/31/19
to MIT App Inventor Forum
I tried your app, and I looked at the code. I have no time now to correct it, but:
App Inventor is not the right tool to build a really accurate metronome, but probably you are able to get much closer than now.
Why are you using increments of 10ms ?? That is much to short. Your app will not have time to breathe and therefore the timings with be inaccurate.
Why are you moving the ball, while you only want to increase/decrease the size?  That takes processing time!
Probably it is also much more efficient to have only one clock and have a variable that determines whether you are expanding or extracting.

Work some more on it and let us know what your results are.
Cheers, Ghica.

ABG

unread,
Jan 31, 2019, 10:47:34 AM1/31/19
to MIT App Inventor Forum
See the How to Run an Accurate Metronome discussion in
the Waiting and Timing section of FAQ
ABG

TimAI2

unread,
Jan 31, 2019, 11:47:54 AM1/31/19
to MIT App Inventor Forum
@ ABG - do you understand Greg's solution and how it might look in blocks ?

BodyMindPower

unread,
Jan 31, 2019, 12:05:52 PM1/31/19
to MIT App Inventor Forum
Hi Ghica,

Why are you using increments of 10ms ?? 
This is necessary to enlarge the ball smoothly, because you can in-/decrease the radius only by integers.
Why are you moving the ball, while you only want to increase/decrease the size?
I want the ball to be enlarged from its center, not from the edge. It takes the same time if I take this away.
Probably it is also much more efficient to have only one clock and have a variable that determines whether you are expanding or extracting.
I don't think that it is possible to do this with just one clock.

Best regards, Anke

BodyMindPower

unread,
Jan 31, 2019, 12:24:13 PM1/31/19
to MIT App Inventor Forum
Thanks for the link; but I read this already. The metronome is not my problem, but how to in/-decrease the ball in a certain time (1, 2, 3, ..., 10 sec), without having too large deviations (+/- 0.1 sec would still be ok).

Anke

BodyMindPower

unread,
Jan 31, 2019, 12:36:01 PM1/31/19
to MIT App Inventor Forum
Hi Tim,

yes, but the metronome is not the problem, but how to increase the ball in a certain time (1, 2, 3,... sec), without having too large deviations (+/- 0.1 sec would still be ok). Greg's solution does not help in this case.

Anke

TimAI2

unread,
Jan 31, 2019, 12:50:24 PM1/31/19
to MIT App Inventor Forum

BodyMindPower

unread,
Jan 31, 2019, 1:20:21 PM1/31/19
to MIT App Inventor Forum
Yes, I thought about that too. But I am aware of the out of memory errors, if many / large images are used. And I have to create many of those gifs to do that this way.

ABG

unread,
Jan 31, 2019, 2:49:33 PM1/31/19
to MIT App Inventor Forum
I've got some shrinking circle code in this sample
app, if that's any help ...

I haven't tested it for constant speed.
It's more of a puddle simulation.

ABG

TimAI2

unread,
Jan 31, 2019, 3:09:49 PM1/31/19
to MIT App Inventor Forum
^^^ Nice, and no clocks too :)

ABG

unread,
Jan 31, 2019, 3:17:42 PM1/31/19
to MIT App Inventor Forum
I have a thought for the pulsating Ball problem ,
but have not coded it yet.

The sin(time * fudge factor) function pulses from -1 to +1.

If we set radius to (max_radius * (sin(time * fudge factor) + 1 ) / 2
at every clock tick, that would give a regular pulsation.

The trick here is to get the right fudge factor, to choose between hummingbird and glacier.

ABG

TimAI2

unread,
Jan 31, 2019, 3:35:54 PM1/31/19
to MIT App Inventor Forum

ABG

unread,
Jan 31, 2019, 4:46:12 PM1/31/19
to MIT App Inventor Forum
do you understand Greg's solution and how it might look in blocks ?

Greg's solution sounds like Bresenham's algorithm 
for dropping pixels along a slanted line.

The gum ball machine on my shoulders is unfortunately
currently running  low.

ABG

TimAI2

unread,
Feb 1, 2019, 6:54:08 AM2/1/19
to mitappinv...@googlegroups.com
Worked up a little gif solution, not perfect, but in essence the gif should "tick" @ 1 per second.
I added some blocks to reset the gif every 30 seconds so it keeps up with the app clock

blocksball5.png


ball.zip

BodyMindPower

unread,
Feb 1, 2019, 9:13:03 AM2/1/19
to MIT App Inventor Forum
Hi Tim, thanks for your effort, but the ball5.gif is an empty transparent file / image. Therefore, only the counter is displayed.

TimAI2

unread,
Feb 1, 2019, 10:04:41 AM2/1/19
to MIT App Inventor Forum
Did you load it in a webviewer (animated gifs do not work in an image component). The first frame has a 1x1px red ball so almost transparent :)

BodyMindPower

unread,
Feb 1, 2019, 12:37:38 PM2/1/19
to MIT App Inventor Forum
Yes in a webviewer, but the gif file you attached is empty - there are no frame and no pixel at all.

ABG

unread,
Feb 1, 2019, 12:41:35 PM2/1/19
to MIT App Inventor Forum
See attached for the sin() based radius implementation.
ABG

bouncy_bouncy.aia
Capture.PNG
blocks.png

TimAI2

unread,
Feb 1, 2019, 1:15:38 PM2/1/19
to MIT App Inventor Forum
Nice work ABG

re gif, seems Google Groups does something to it. Have zipped it up and edited post.

ABG

unread,
Feb 1, 2019, 1:25:05 PM2/1/19
to MIT App Inventor Forum
Thanks,

I whipped up a variant on using a label instead of the Canvas,
showing the cumulative beat count instead of the ball.

The Label component is very forgiving of font size.

ABG

bouncy_beats_label.aia
Capture.PNG
Designer.PNG
blocks.png

BodyMindPower

unread,
Feb 2, 2019, 7:40:45 AM2/2/19
to MIT App Inventor Forum
Hello ABG,

Thank you for your great and elegant solution. I needed some time to get through it. I have made some small adjustments since I need the duration to grow and reduce the ball in seconds. I also added a break (Spinner: 0,1, 2, 3, ..., 10 sec) after zooming in and out of the ball. After this break, the ball is not reduced in size from the max radius or increased from r = 0 (of course, as the elapsed time has changed now).

Your solution does not work correctly on devices with Screen.Width > 360. Tested on a device with Screen.Width = 392.

Also the ball starts at the first time with radius r >= 90 on devices with Screen.Width = 360. On devices with Screen.Width = 392 with radius r  >= 98.

Thus, this solution works only AFTER the first start (loop) correctly (how to fix this?). And as long as no breaks are provided and if the Canvas.Width is set to 360 (no problem, I set the Canvas.Width = 360)

Thanks a lot again,
Anke
bouncy_bouncy_2.aia
Screenshot.jpg
blocks.JPG

ABG

unread,
Feb 3, 2019, 3:47:54 PM2/3/19
to MIT App Inventor Forum
I had to apply an old programmer adage 
to your blocks:

If in doubt
rip it out

(not so good advice for my dentist)

The whole approach of tracking the radius to decide where you
are in a cycle is fragile, because you can easily miss 
a particular radius value (the clock isn't fast enough)
and it doesn't distinguish between upward and downward slopes
in the sine curve.

It's much simpler to just use the elapsed amount of time
and the seconds per rep (repetition).
The floor() function (or round) or ceiling() function
applied to elapsed seconds / seconds per rep
gives you a clean current count for comparison purposes.

(I see you switched from beats per minute to seconds,
so I assume this is for slower exercises like bar bells,
where it takes multiple seconds to complete each repetition.)

Regarding the different canvas sizes,
I removed a block where I presumptuously
assume Portrait mode, setting Canvas Height to Width,
and instead used the minimum of Height and Width to determine
maximum radius.

Regarding starting the radius at 0,
I achieved this by introducing a constant
phase_offset, initially -90 degrees, to shift the sine wave
to make it start at a trough, instead of in the middle of its
upwards slope.

I also reset the constant 30 to 60 where you turn
seconds to minutes.  I am holding to
the full sine wave cycle in my presentation,
not just an ascending phase.  Any other interpretation
opens up a can of worms.

I am unsure about the purpose of your hold spinner.
I assume it is meant to limit how many seconds the exercise 
is allowed to run?

I saw no point to the Clock for the Hold function, so
I ripped it out.

ABG




Capture2_ABG.PNG
blocks2_ABG.png
bouncy_bouncy_2_ABG.aia

BodyMindPower

unread,
Feb 4, 2019, 11:17:43 AM2/4/19
to mitappinv...@googlegroups.com
Hello ABG,

Thank you very much for your effort.
It's about a breathing / meditation app, so you can have breaks (hold breath) between breaths.

One loop:
Inhale: 2-10 sec
Pause (hold): 0-10 sec
Exhale: 2-10 sec
Pause (hold): 0-10 sec
...
For instance:
One possible breathing exercise is (4-4-4-4):
- Inhale for 4 sec
- Hold your breath for 4 sec
- Exhale for 4 sec
- Hold your breath for 4 sec
and so on ...

Example gif (2-2-2-2) how this part of the app should work
https://drive.google.com/file/d/1ppesVkjupNovxCAu1hTWiS5pvU_k3_7N/view

To do all this with animated gifs (as Tim suggested), I would need almost 10^4 (= 10000) gifs if I only want to call the webviewer once and my math skills are right. Also if I do that with 3D (Java).

Since the user usually has to do this with eyes closed, an (acoustic) metronome is needed, so that the user has an orientation for counting each sec.
 

I reset back to 30, because I need for instance 10 sec for inhaling and 10 sec for exhaling.
So far I have not taken a closer look at your new aia; I need some time to get through it and integrate the breaks (pause).

You can see that someone with a much better mathematical understanding is working here than the "Normal One".
"I am the Normal One" (J. Klopp, Liverpool coach).


Anke

ABG

unread,
Feb 4, 2019, 12:22:42 PM2/4/19
to MIT App Inventor Forum
Thank you for posting the details.

This looks more like a slow moving player piano type app,
where each exercise could be described using a multi-column
table of parameters feeding a linear equation r(t) incorporating the
sin() function, one row per exercise phase, 4 rows total.

An external variable (your spinner) could determine the timing factor.
The Canvas geometry would determine the maximum radius.

In the parameter table, the columns could include:
  1. a constant  to be added to the time varying part, for the hold phases' amplitude
  2. a phase offset to be feed to the sin) function, to control in/out start phase,
  3. a multiplier (1/0) for the sin() term, to enable/disable the sin() variance,
  4. a word to be spoken by text to speech (TTS) at start of cycle (in/hold/out/hold)
Each row of the table would describe a half-cycle of the sine wave's period.

Are there any other features to add, like pause/resume or stop-after-n-cycles?

Here are some sample apps with player piano mechanisms, for reference:

ABG


ABG

unread,
Feb 6, 2019, 12:42:26 PM2/6/19
to MIT App Inventor Forum
See attached for a working example, with metronome tick.

(I tried speech output, but it was too slow to keep up.)

ABG
breathe.aia
Capture.PNG
Designer.PNG
Tick.mp3
blocks.png

BodyMindPower

unread,
Feb 6, 2019, 3:21:32 PM2/6/19
to MIT App Inventor Forum
Fantastic! I have tried it with your last aia and have always come up with new problems. I also tried to incorporate a sound (in_1s.ogg, 1 sec, loop) for inhaling and a second sound (out_1s.ogg) for exhaling, each fading in and out for 1 second. For that the TaifunPlayer extension is needed for seamless (gapless) looping. The blocks have become so complicated that I will rather not post them.

I'll definitely need some time to understand the logic of your new aia. I will try to integrate the other features (sounds for in- / exhaling, stop exercise after x min / reps, ...) and post the result here.

Thank you for your amazing work. After this crash course with you I will probably be able to prepare students for the math exam.

Anke
in_1s.ogg
out_1s.ogg
Reply all
Reply to author
Forward
0 new messages