Ratio 12 segment

Hi gentlemen.

I'm sorry to start this thread, but I need help with this feature:

I divided the Circle into 12 segments and every 5 seconds I fill in one segment, a total of 60 seconds = 1 minute. The problem is that my last segment is not filling up. Please advise where there may be a mistake?

I enclose an example of a function, including an error.

Thank you for your help

function drawCircle(dc) {
  	    var handWidth = dc.getWidth();
    	var position = System.getClockTime().sec /5; RATIO;
    	dc.setPenWidth(handWidth/18.3);
    	
    	for (var i = 0; i < 12; ++i) {
    
        if (i < position)
    	{
    		
    		dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK); 
    	   
    	}
    	else
    	{
			
			   	
    	    dc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_BLACK);
    	}		 
	
 
    	   var start = 360 - ( 4 + (30*i)); 
    	   var end = start - 21.1;
    	   dc.drawArc(handWidth/6.2, handWidth/2.47, handWidth/10.5, 1, start+90, end+90); 
  	    }
    
          }

  • Add println calls to your code so you can see what's going on.

  • Add println calls to your code so you can see what's going on.

    This is a good approach.

    Another approach (once you have enough experience) is to think about how your code would work, without even running it.

    System.getClockTime().sec: this ranges from 0 to 59 and is a Number (an integer). When you divide it by 5 (another Number/integer), the answer will be truncated (the part after the decimal will be removed.)

    0 / 5 = 0
    1 / 5 = .20 => 0 (after truncation)
    ...
    5 / 5 = 1
    ...
    9 / 5 = 1.8 => 1 (after truncation)
    10 / 5 = 2
    ...
    14 / 5 => 2
    15 / 5 => 3
    ...
    19 / 5 => 3
    20 / 5 => 4

    ...
    24 / 5 => 4
    25 / 5 => 5
    ...
    55 / 5 => 11
    56 / 5 => 11
    57 / 5 => 11
    58 / 5 => 11
    59 / 5 => 11

    Since the result of the calculation is never greater than 11, the final segment never fills up.

    One way you could the final segment to fill up would be to change the calculation to System.getClockTime().sec / 5.0, so you get a decimal (Float) result.

    Then you'll get results like this:

    0 / 5 = 0
    1 / 5 = 0.2
    ...
    4 / 5  = 0.8
    ...

    55 / 5 = 11
    56 / 5 = 11.2

    57 / 5 = 11.4
    58 / 5 = 11.6
    59 / 5 = 11.8

    This may not be a perfect solution as the state represented by "no segments filled in" will last for 1 second, while the state represented by "all segments filled in " will last for 4 seconds, if I'm reading the code correctly. I think every other state will last for 5 seconds.

    (Note that your graphic actually has 13 states, if you include the state where no segments are filled in.)

  • Thank you for your advice and suggestions. If anyone wants to redo and modify it, I'll just be happy...

  • One of the best ways to learn is by trying stuff out for yourself. With coding, unlike many other things, there's 0 cost to doing so except for your time and effort.

    Or someone else here could spend their time and effort doing your work for you, but that wouldn't help you for the next app....


  • I needed to finish this function last and I write on the forum when I can't get advice. I can't devote my time to reading, because they dedicate that time to their sick son. For that, I was hoping that someone worthy would put my code into the simulator and help me modify it to work. I understand that and thank you for the advice.

  • Did you try the solution I suggested?

    One way you could the final segment to fill up would be to change the calculation to System.getClockTime().sec / 5.0, so you get a decimal (Float) result.
  • I tried it before and it didn't work either, so I decided to start this thread. The only thing that works a little bit is:
    System.getClockTime().sec / 4.9,

  • It works for me, exactly as I described.

    The only substantial change I made to your code (other than changing colors) is to divide by 5.0 instead of 5.

    Every state lasts for 5 seconds, except:

    - No segments (only when secs is 0)

    - All segments (only when secs is 56-59)

    If you think about it, the discrepancy here is because you have 13 states instead of 12, and it's really not consistently defined what it means for a segment to be full. (If it was consistent, you'd either never see all segments full or you'd never see no segments full).

        function drawCircle(dc) {
            var handWidth = dc.getWidth();
            var position = System.getClockTime().sec / 5.0;
            dc.setPenWidth(handWidth / 18.3);
    
            for (var i = 0; i < 12; ++i) {
                if (i < position) {
                    //dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK);
                    dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_BLACK);
                } else {
                    //dc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_BLACK);
                    dc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_BLACK);
                }
    
                var start = 360 - (4 + (30 * i));
                var end = start - 21.1;
                dc.drawArc(handWidth / 6.2, handWidth / 2.47, handWidth / 10.5, 1, start + 90, end + 90);
            }
        }
    
        public function onUpdate(dc as Dc) {
            dc.clear();
            dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
            dc.drawText(dc.getWidth() / 2, 2, 10, System.getClockTime().sec, Graphics.TEXT_JUSTIFY_CENTER);
            drawCircle(dc);
            return;
        }

    Here it is at 4X speedup:

    Original video:

  • Thanks for the help and wouldn't it be possible for the last segment to load .sec / 59 and the first .sec / 5?

    This looks like the first segment is loaded for the first second.

  • If you can define exactly how you want the segments to behave, you can write the code or ask us for help writing the code.

    Otherwise we (or you) are just randomly changing the code until we get the result that we guess you want.

    Sometimes the hardest of part of making an app is gathering requirements, not writing the code.

    As mentioned, you have 13 states, so that's kind of a problem too, since you want to divide 60 seconds into 12 chunks.

    It could be a simple as writing down the state you expect to see for every single value of secs.

    For example, the way it works above is:

    0: no segments
    1-5: 1 segment
    6-10: 2 segments
    ...
    51-55: 11 segments
    ...
    56-59: 12 (all segments)

    (I bolded the cases that are inconsistent with the others.)

    ---

    TL;DR If you could write down either:

    - What you expect for every single value of secs

    - A simple rule which describes what should happen for any value of secs

    It would be easy to write the code.

    I divided the Circle into 12 segments and every 5 seconds I fill in one segment, a total of 60 seconds = 1 minute.

    If we take this statement very literally, then the code would be easy, but it would also mean that you would never see "no segments", because:

    50 secs => 10 segments

    55 secs => 11 segments

    0 secs => 12 segments

    5 secs => 1 segment

    ...

    Alternatively you could say that 0 secs => 0 segments, but then you never see 12 segments.

    So this is a problem where maybe the reqs need to be revisited, once we realize what they're actually calling for.

    But the code is easy to write. Here's a version where you never see 12 segments:

        function drawCircle(dc) {
            var handWidth = dc.getWidth();
            dc.setPenWidth(handWidth / 18.3);
    
            var sec = System.getClockTime().sec;
            for (var i = 0; i < 12; ++i) {
                if ((i + 1) * 5 <= sec) {
                    dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_BLACK);
                } else {
                    dc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_BLACK);
                }
    
                var start = 360 - (4 + (30 * i));
                var end = start - 21.1;
                dc.drawArc(handWidth / 6.2, handWidth / 2.47, handWidth / 10.5, 1, start + 90, end + 90);
            }
    
        }
    

    And here's a version where you never see 0 segments:

        function drawCircle(dc) {
            var handWidth = dc.getWidth();
            dc.setPenWidth(handWidth / 18.3);
    
            var sec = System.getClockTime().sec;
            if (sec < 5) {
                sec = 60;
            }
            for (var i = 0; i < 12; ++i) {
                if ((i + 1) * 5 <= sec) {
                    dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_BLACK);
                } else {
                    dc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_BLACK);
                }
    
                var start = 360 - (4 + (30 * i));
                var end = start - 21.1;
                dc.drawArc(handWidth / 6.2, handWidth / 2.47, handWidth / 10.5, 1, start + 90, end + 90);
            }
    
        }

    If you want something else, you need to write new requirements.

    Thanks for the help and wouldn't it be possible for the last segment to load .sec / 59 and the first .sec / 5?

    But does that make sense? It means that the second last segment would only be filled for 4 seconds, the last segment would only be filled for 1 second, while every other segment would be filled for five seconds. Again, it's not clear what the meaning (to the user) of a "filled segment" is, in that case.

    But, sure, it's your code, you can do anything you want:

        function drawCircle(dc) {
            var handWidth = dc.getWidth();
            dc.setPenWidth(handWidth / 18.3);
    
            var sec = System.getClockTime().sec;
            if (sec == 59) {
                sec = 60;
            }
            for (var i = 0; i < 12; ++i) {
                if ((i + 1) * 5 <= sec) {
                    dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_BLACK);
                } else {
                    dc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_BLACK);
                }
    
                var start = 360 - (4 + (30 * i));
                var end = start - 21.1;
                dc.drawArc(handWidth / 6.2, handWidth / 2.47, handWidth / 10.5, 1, start + 90, end + 90);
            }
    
        }