How to draw 2 color circle using Graphics? [Answered]

Posted on
  • I want to draw 2 color circle and rotate it slowly roughly 5 times in a seconds (1 degree per step).

    What is the best way to achieve with smooth animation (no flickering) ?


    1 Attachment

    • sample.png
  • What size will the circle have? 5 times a second fully around seems to me a bit demanding...

    I would approach it the following way:

    think about two hands - a black one and a red one - to take the color of your pic that start in the center out to the border your pic implies.

    Then constantly draw the black one advancing the line into the read zone and the red one advancing into the black zone.

    The be fast, you may precalc the cordinates for one quadrant and then just look up the values. Since hand are only one pixle, the size and number of step relate to each other... Should you run out of time - to much to do - do less steps and draw wide hands: 2 or 3 pixles wide rectangles...

    If you dounle the number of coordinates, ou can avoid drawinalways from center... becasuse of points will not change color for many steps.

  • ...what about this... watch attached .mp4 clip.

    Adjust things to your likings. Notice that below eample was running in emulator when clip was taken. Real behavior can only be seen on real device...

    Since I jhave only 16 circle segments, I chose to fill closed polys of 3 points: center, seg begin and seg end on circumference.

    // baoRotator.js - by allObjects
    
    // uses vertices to define circle shape and rotation angle per step
    
    // declaration of globals
    var vst  // vertices templates, incl. scaling information
      , dIId1 // draw interval id 1 and 2 for clockwise red/blue...
      , dIId2 // ...and counter clockwise yellow/green rotators
      , startStopBtn = BTN2 // to start/stop (go/hlt) rotation
      ;
    
    // prep template vertices to be based of left/top of bounding box
    function iniGls() { // pairs fo x/y coordinates followed by scale
      vst = [98,20,83,56,56,83,20,98,-20,98,-56,83,-83,56,-98,20
            ,-98,-20,-83,-56,-56,-83,-20,-98,20,-98,56,-83,83,-56,98,-20
            ].map((v)=>100+v); vst.push(100); } // prep template ver
    
    // get work vertices for particular origin and radious
    function vs(
         t // template vertices array w/ scale as last item
        ,o // origin left/top of bounding box
        ,r // radius
        ) { var l=t.length-1,s=r/t[l]
              , w=t.map((v,i)=>Math.round(o[i&1]+s*v));
      w[l]=w[0]; w.push(w[1]); // to make go around simpler
      return w; }
    
    // draw rotator (c-w) - two halfs of a circle w/ different
    // color rotating; center of circle w/ radius of r is...
    function draw( // ...at [x=o[0]+r,y=o(1]+r];
         vt   // vertices template
        ,o   // origin (left/top) [x,y] of rotator's bounding box
        ,r   // radius of rotator (circle)
        ,rpm // revolutions per minute
        ,c1  // color one
        ,c2  // color two
        ,c   // (optional) counter clock wise
        ) {
      var v = vs(vt,o,r) // calc directly usable vertices
        , x = o[0]+r, y = o[1]+r // origins in pixels
        , s = (v.length-2) // double the number of circle segments
        , t = 60000/(s/2)/rpm // interval in ms for each segment
        , i = 0, j = Math.round(s/2) // circumf running vars
        , d = function() { // draw segments / wedges
            g.setColor(c1)
             .fillPoly([x,y,v[i++],v[i++],v[i++],v[i--]],1)
             .setColor(c2)
             .fillPoly([x,y,v[j++],v[j++],v[j++],v[j--]],1);
            i=(i<s)?i:0; j=(j<s)?j:0; } // handle going around
        , k = s+2, m; if (c) { // xform vertkces for counter clock
      while (--k>=0){m=v[k];v[k]=v[--k],v[k]=m;} v=v.reverse();}
      return setInterval(d,t); }
    
    function go() { // go
      hlt(); // note the radious is scaled by 100 (eff rad: 15px)
      dIId1 = draw(vst,[10,10],18,20,"#0000FF","#FF0000");
      dIId2 = draw(vst,[50,22], 6,60,"#FFFF00","#00FF00",1); }
    
    function hlt() { // halt
      if (dIId1) dIId1 = clearInterval(dIId1);
      if (dIId2) dIId2 = clearInterval(dIId2); }
    
    function onInit() {
      iniGls();
      go(); // BTN2 starts/stops
      setWatch(function(){ if (dIId1||dIId2) hlt(); else go();
        },startStopBtn,{repeat:true, edge:"rising"});
    }
    
    setTimeout(onInit,999); // for dev'g, remove before upload for save()
    

    3 Attachments

  • Updated the example and code. Dimensions are now all absolute and not some scaled, and scaling is included in vertices. So different vertices can be provided as needed render nicely larger and more efficient smaller 'circles'/'discs'.

  • Thanks @allObjects, I will test it, but it seems you gave me an idea to start my own. :)

    Thanks a lot!!

  • @Abhinav, to get you going on your own was my intension from the very beginning, because last but not least the requirements in the first poast are very frugal.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

How to draw 2 color circle using Graphics? [Answered]

Posted by Avatar for Abhigkar @Abhigkar

Actions