A metronome code I'm working on, sort of

float radius = (min(width, height)/2)*0.22;

// it's supposed to determine what the length of the hand is
void setup(){
    size(480,480);
    stroke(55);
    strokeWeight (4);
}

//run-of-the-mill setup
void draw(){
    background (255);
    stroke(0);
    float time = millis()/10;
    float sec= map(time,0,1000,0,TWO_PI)-HALF_PI;
    float cx = width/2;
    float cy = height/2;
    float time2 = millis();
    float direction1 = cx*cos(sec)*radius;
    float direction2 = cy*sin(sec)*radius;
    //variables, cx cy to center the origin
    if(time2%1000==0){
        direction1 *=-1;
        direction2 *=-1;
    }
    // i may have gotten my trigonometry completely wrong, 
    // but this is SUPPOSED to reverse the direction of the
    // moving line every 1 second, but nothing happens. 
    // What do I do wrong?
    line(cx, cy, direction1 , direction2);
}   

So what's supposed to happen is that every one second the direction of the moving hand reverses, but nothing happens except for a smoothly running hand going across the screen. What did I do wrong?

Additionally: how do I limit the length of my hand? I think I set it too long but I'm not sure why/how...

Tagged:

Answers

  • edited October 2017

    ==0 in line if(time2%1000==0){ won‘t work

    it’s running too slow to meet exactly 1000 every time

    Instead store oldTime : oldTime = millis();

    Then compare to current time and check with millis() :

    if ( oldTime + 1000 <= millis() ) {
        // event 
        oldTime = millis();
    }
    
  • float radius = (min(width, height)/2)*0.22;

    width and height are 100 before size() is called. so this will not be what you are expecting.

  • To understand why, try these test sketches:

    int w = width;
    int h = height;
    
    void setup(){
      println("global:", w, h);
      size(480,480);
      println("  size:", width, height);
      exit();
    }
    

    global: 100 100
    size: 480 480

    void draw(){
      println(millis());
      if(frameCount>5) exit();
    }
    

    322
    340
    355
    374
    389
    407

  • edited October 2017

    a few errors:

    Error on radius

    you were using width and height before size in defining radius in line 1. It's not defined before size() command though. So radius was always wrong.

    Error on center

    here

        float direction1 = cx*cos(sec)*radius;
        float direction2 = cy*sin(sec)*radius;
    

    you had an obvious typo, center must be added not multiplied:

        float direction1 = cx + cos(sec)*radius;
        float direction2 = cy + sin(sec)*radius;
    

    Time and angle

    Also I found it hard to use time and correct angle both.

    So I decided to strip the sketch down and use the angle (named time) as a turning point on both sides left and right.

    I was adjusting the speed (I was adding a value to the angle, called time in my sketch) so that it came out at one second as a turning point.

     float timeAdd=0.0262;  // speed
    

    I fail the math to dive deeper into it. In theory, this

    sec= map(time%1000, 0, 1000, -TWO_PI, TWO_PI)-HALF_PI;
    

    was very good.

    Best, Chrisir ;-)

    here is the entire code

    // https : // forum.processing.org/two/discussion/24752/a-metronome-code-i-m-working-on-sort-of#latest
    
    final float CENTER_METRONOME = - HALF_PI; 
    
    float radius; 
    int oldTime; 
    boolean goRight=true; 
    float time = CENTER_METRONOME ; // CENTER 
    float timeAdd=0.0262;  // speed
    
    void setup() {
    
      size(480, 480);
    
      // it's supposed to determine what the length of the hand is
      radius = (min(width, height)/2)*0.44;
    
      stroke(55);
      strokeWeight (4);
      oldTime = millis();
    }
    
    //run-of-the-mill setup
    void draw() {
      background (255);
    
      stroke(0);
      time = time + timeAdd;
    
      //-TWO_PI/4-TWO_PI/8; 
      //time /= 10; 
      //if (goRight)
      //  sec= map(time%1000, 0, 1000, -TWO_PI, TWO_PI)-HALF_PI;
      //else 
      //sec= map(time%1000, 0, 1000, TWO_PI, -TWO_PI)-HALF_PI;
    
      //position
      //variables, cx cy to center the origin
      float cx =  width/2;
      float cy =  height/2;
      float time2 = millis();
    
      float direction1 = cx + cos(time)*radius;
      float direction2 = cy + sin(time)*radius;
    
      fill(0); 
      text("angle ="
        +time
        + " \nin range of "
        +str(CENTER_METRONOME- QUARTER_PI  ) 
        + " to " 
        + str( CENTER_METRONOME + QUARTER_PI ), 
        44, 44); 
    
      // oldTime + 1000 <= millis() || 
      if (time <= CENTER_METRONOME  - QUARTER_PI  || 
        time >= CENTER_METRONOME + QUARTER_PI ) {
    
        // event 
        println("event change "+millis()+ "; difference = "+ str( millis()-oldTime ) );
        oldTime = millis();
        goRight=!goRight;
        timeAdd*=-1;
      }
    
      // i may have gotten my trigonometry completely wrong, 
      // but this is SUPPOSED to reverse the direction of the
      // moving line every 1 second, but nothing happens. 
      // What do I do wrong?
      line(cx, cy, direction1, direction2);
      stroke(255, 0, 0); 
      point(cx, cy);
    }   
    
  • edited October 2017 Answer ✓

    ah, I solved it!

    Here is a better version, that works not with adding something to the angle but with a proper timer.

    The times are also measured, they vary between 1000 and 1016 millis on windows system but are almost accurate.

    // https : // forum.processing.org/two/discussion/24752/a-metronome-code-i-m-working-on-sort-of#latest
    
    final float METRONOME_CENTER = - HALF_PI;  // angle north 
    final float METRONOME_RANGE  =  QUARTER_PI; // to the left and to the right  
    
    // center
    float cx;
    float cy;
    
    // radius 
    float radius; 
    
    int time2;
    int oldTime; 
    
    boolean goRight=true; 
    float angle = METRONOME_CENTER ; // angle at CENTER 
    
    float direction1;
    float direction2;
    
    String strText = "";
    
    void setup() {
    
      size(480, 480);
    
      // it's supposed to determine what the length of the hand is
      radius = (min(width, height)/2)*0.55;
    
      //variables, cx cy to center the origin (its position)
      cx =  width/2;
      cy =  height/2;
    
      stroke(55);
      stroke(0);
      strokeWeight (4);
      oldTime = millis();
    }
    
    //run-of-the-mill setup
    void draw() {
      background (255);
    
      // this should be between 0 and 1000 
      time2 =  millis() - oldTime ;
    
      if (goRight) {
        angle = map(time2, 0, 1000, 
          METRONOME_CENTER  - METRONOME_RANGE, METRONOME_CENTER + METRONOME_RANGE  );
      } else {
        angle = map(time2, 0, 1000, 
          METRONOME_CENTER + METRONOME_RANGE, METRONOME_CENTER  - METRONOME_RANGE );
      }
    
      // top of the hand: 
      direction1 = cx + cos(angle)*radius;
      direction2 = cy + sin(angle)*radius;
    
      fill(0);
      text(strText, 44, 44); 
      //text("angle ="
      //  +angle
      //  + " \nin range of "
      //  +str(METRONOME_CENTER - METRONOME_RANGE   ) 
      //  + " to " 
      //  + str( METRONOME_CENTER + METRONOME_RANGE ), 
      //  44, 44); 
    
      //time based 
      if (oldTime + 1000 <= millis()) { 
        // event (turning point left or right)
        strText=str(millis()-oldTime); 
        //println("event change "
        //  + millis()
        //  + "; difference = "
        //  + str( millis()-oldTime ) );
        oldTime = millis();
        goRight = !goRight;
      } // if 
    
      // i may have gotten my trigonometry completely wrong, 
      // but this is SUPPOSED to reverse the direction of the
      // moving line every 1 second, but nothing happens. 
      // What do I do wrong?
      line(cx, cy, direction1, direction2);
      //  stroke(255, 0, 0); 
      //  point(cx, cy);
    }   
    
  • The times are also measured, they vary between 1000 and 1016 millis on windows system but are almost accurate.

  • edited October 2017

    After extensive study of your code, I managed to solve the problem. Thanks for helping me!

Sign In or Register to comment.