Sampling a movement by storing Mouse datas and repeat it one second after. The right sampling :)

PLEASE GO to SEE my NEXT post! Thank you

Hello everybodies,

I would like to be able to record the x and y position of the mouse for a second and then automatically redo that recorded movement.
It would be nice to succeed in creating this function on the code below

Thank you very much :slight_smile:

/**
 * Follow 3  
 * based on code from Keith Peters. 
 * 
 * A segmented line follows the mouse. The relative angle from
 * each segment to the next is calculated with atan2() and the
 * position of the next is calculated with sin() and cos().
 */

float[] x = new float[20];
float[] y = new float[20];
float segLength = 18;

void setup() {
  size(640, 360);
  strokeWeight(9);
  stroke(255, 100);
}

void draw() {
  background(0);
  dragSegment(0, mouseX, mouseY);
  for(int i=0; i<x.length-1; i++) {
    dragSegment(i+1, x[i], y[i]);
  }
}

void dragSegment(int i, float xin, float yin) {
  float dx = xin - x[i];
  float dy = yin - y[i];
  float angle = atan2(dy, dx);  
  x[i] = xin - cos(angle) * segLength;
  y[i] = yin - sin(angle) * segLength;
  segment(x[i], y[i], angle);
}

void segment(float x, float y, float a) {
  pushMatrix();
  translate(x, y);
  rotate(a);
  line(0, 0, segLength, 0);
  popMatrix();
}

Hi @bking,

I just saw that the above code is not from you, have you tried making your own or do you understand what it does?

Also for me it looks like this code is over complicated for nothing. What you need is:

  • Get the mouse coordinates
  • Being able to store positions: use PVector and ArrayList
  • Count for 1 second of time (see millis())
  • Draw the recorded movement with lines (use line and don’t bother with angles and trigonometry)

Good luck :wink:

Hi Joseph,

Thank for yours advices
I tried something else with an other example easier.
Here, the positions of the 90 last frame are in a array. As frame count gets higher ellipses disapper. I tried to store datas from mouse and repeat them after one second but it don’t work :frowning:

/**
 * Storing Input. 
 * 
 * Move the mouse across the screen to change the position
 * of the circles. The positions of the mouse are recorded
 * into an array and played back every frame. Between each
 * frame, the newest value are added to the end of each array
 * and the oldest value is deleted. 
 */
 
int num = 90;
float mx[] = new float[num];
float my[] = new float[num];

float Recordedmx[] = new float[num];
float Recordedmy[] = new float[num];

int indexj[]= new int[num];

boolean Recorded;

int timerFirstLoop;
int timerSecondLoop;

void setup() {
  size(640, 360);
  noStroke();
  fill(255, 153); 
}

void draw() {
  background(51); 
  
  // Cycle through the array, using a different entry on each frame. 
  // Using modulo (%) like this is faster than moving all the values over.
  int which = frameCount % num;
  int whichR = frameCount % num;
  
  mx[which] = mouseX;
  my[which] = mouseY;
  
  
  if (millis()>= timerFirstLoop)  { 
     Recorded=true;
  //   timerFirstLoop=millis ()+2000;
   
  for (int i = 0; i < num; i++) {  stroke(200);      
    // which+1 is the smallest (the oldest in the array)
    int index = (which+1 + i) % num;
    indexj[i]=index;
    Recordedmx[which]= mx[which];
    Recordedmy[which]= my[which];
     
    ellipse(mx[index], my[index], 50, 50);
    // Recorded=false; 
    } 
   }
 
 println (Recorded);

   if ( Recorded==true && millis ()>timerSecondLoop)  { 
     timerSecondLoop=millis ()+2000;

     for (int j = 0; j < num; j++) { stroke(100);      
       int lastIndex= indexj[j];
     //index[j]=lastIndex;
       ellipse(Recordedmx[lastIndex], Recordedmy[lastIndex], 100, 100);
    // ellipse(mx[lastIndex], my[lastIndex], 50, 50);
     }   
 //    Recorded=false;
}
   
}
1 Like

Hello @bking,

You can even replace millis() with frameCount as your timer.
Easy to do and I just did it with your code.

2*60 = 2000 in the context of your code and assuming framerate is 60 fps. :)

I do this often when I want to sync to a frame (or frameCount) or just need a simple timer.

:)

1 Like

Thanks Glv;

I tried this, it doesn’t work. I have a problem to recall the same data. Here I recall data one by one each second. It’s strange for me.

/**
 * Storing Input. 
 * 
 * Move the mouse across the screen to change the position
 * of the circles. The positions of the mouse are recorded
 * into an array and played back every frame. Between each
 * frame, the newest value are added to the end of each array
 * and the oldest value is deleted. 
 */

int num = 60;
float mx[] = new float[num];
float my[] = new float[num];

float Recordedmx[] = new float[num];
float Recordedmy[] = new float[num];

int indexj[]= new int[num];

boolean Recorded;

int timerFirstLoop;
int timerSecondLoop;

int frameCountLimit;

int indexRecorded;

void setup() {
    frameRate=30;
  size(640, 360);
  noStroke();
  fill(255, 153); 
}

void draw() {
  background(51); 
 
  
  // Cycle through the array, using a different entry on each frame. 
  // Using modulo (%) like this is faster than moving all the values over.
  int which = frameCount % num;
  int whichR = frameCount % num;
  
  mx[which] = mouseX;
  my[which] = mouseY;
  
  if (millis()>= timerFirstLoop && Recorded==false )  { 
       
  
  //   timerFirstLoop=millis ()+1000;
 
   
  for (int i = 0; i < num; i++) {  stroke(200);      
    // which+1 is the smallest (the oldest in the array)
    int index = (which+1 + i) % num;
  //  indexj[i]=index;
    indexRecorded = (whichR+1 + i) % num;
    Recordedmx[whichR]= mx[which];
    Recordedmy[whichR]= my[which];
    
   
    ellipse(mx[index], my[index], 50, 50);
    // Recorded=false; 
    print ("mx[index]"); print (mx[index]);
    }
    
    
 //   timerFirstLoop=millis ()+1000;
    Recorded=true;
   
 
    }
   
 
  // println (Recorded);

   if ( frameCount >frameCountLimit+60 && Recorded==true)  { 
     frameCountLimit= frameCount ;

      for (int i = 0; i < num; i++) {  stroke(200);      
    // which+1 is the smallest (the oldest in the array)
  //  int index = (which+1 + i) % num;
  //  indexj[i]=index;
    indexRecorded = (whichR+1 + i) % num;
   
    
   
   ellipse(Recordedmx[indexRecorded], Recordedmy[indexRecorded], 100, 100);
   print (" Recordedmx[indexRecorded] "); println (Recordedmx[indexRecorded]);
    // Recorded=false; 
      Recorded=false;
}
 }  
}

Hello @bking,

I just tested it quickly with frameCount and it worked here; that test is long gone…

This is what I was going to share to compare:

boolean recordedm, recordedf;

int timerFirstLoop;
int timerSecondLoop;

int timerStart;
int timerStop;

void setup()
  {
  size(640, 360);
  timerStart = frameCount;
  timerFirstLoop = millis();
  println(frameCount, millis());
  }

void draw()
  {
// frameCount version    
  if (frameCount >= timerStart)
    {
    recordedf = true;
    }

  if (recordedf==true && frameCount>= timerStop)
    {
    timerStop = frameCount + 2*60;
    recordedf = false;
    println("f: ", frameCount, millis());
    }

// millis() version      
  if (millis() >= timerFirstLoop)
    {
    recordedm = true;
    }

  if (recordedm==true && millis()> timerSecondLoop)
    {
    timerSecondLoop = millis() + 2000;
    recordedf = false;
    println("m: ", frameCount, millis());  
   }
  }

I started working with your code and this may have bugs; I write a lot of quick test code.
I just wanted to give you a sense of it… once you grasp timers they are easy to work with.
Lot’s of related stuff on timers in the forum if you search for it.

:)

1 Like

There is indeed a problem with the timer but I think the problem is how to recall the data.
In my program the data arrives at the same time, it does not follow the movement, it means that the data is not recalled exactly as it was stored.
I removed the variable ‘recorded’ true or false too

/**
 * Storing Input. 
 * 
 * Move the mouse across the screen to change the position
 * of the circles. The positions of the mouse are recorded
 * into an array and played back every frame. Between each
 * frame, the newest value are added to the end of each array
 * and the oldest value is deleted. 
 */

int num = 180;
float mx[] = new float[num];
float my[] = new float[num];

float Recordedmx[] = new float[num];
float Recordedmy[] = new float[num];

int indexj[]= new int[num];

boolean Recorded;

int timerFirstLoop;
int timerSecondLoop;

int frameCountLimit;

int indexRecorded;

void setup() {
  frameRate(60);
  
  size(640, 360);
  noStroke();
  fill(255, 153); 
}

void draw() {
  background(51); 
 
  
  // Cycle through the array, using a different entry on each frame. 
  // Using modulo (%) like this is faster than moving all the values over.
  int which = frameCount % num;
  int whichR = frameCount % num;
  
  
  mx[which] = mouseX;
  my[which] = mouseY;
  

  for (int i = 0; i < num; i++) {  stroke(200);      
    // which+1 is the smallest (the oldest in the array)
    int index = (which+1 + i) % num;
  //  indexj[i]=index;
    indexRecorded = (whichR+1 + i) % num;
    Recordedmx[whichR]= mx[which];
    Recordedmy[whichR]= my[which];
    
   
    ellipse(mx[index], my[index], i, i);
    //  
    print ("mx[index]"); print (mx[index]);
   //  timerFirstLoop=millis ()+1000;
   // Recorded=false;
    
     if (millis()>= timerSecondLoop  )  { ///&& Recorded==false
       timerSecondLoop=millis ()+1000;
         for (int j = 0; j < num; j++) {  stroke(200);      
    // which+1 is the smallest (the oldest in the array)
  //  int index = (which+1 + i) % num;
  //  indexj[i]=index;
    indexRecorded = (whichR+1 + j) % num;
  
   ellipse(Recordedmx[indexRecorded], Recordedmy[indexRecorded], 20, 20);
   print (" Recordedmx[indexRecorded] "); println (Recordedmx[indexRecorded]);
    // Recorded=false; 
   //   Recorded=true;
    }
    }
  }
}

Hello,

It is not easy for me to look at other code and often just reduce it to something simple at first and build on that…

This is what I wrote quickly:

int num = 180;

float mx[] = new float[num]; // Future
float my[] = new float[num]; // Future

float rx[] = new float[num];
float ry[] = new float[num];

void setup() 
  {
  size(800, 200);
  noStroke();
  fill(255, 0, 0, 50); 
  println("Start Drawing!");
  }

void draw() 
  {
  int i = int(frameCount%180);
  if(frameCount>0 && frameCount<180)
    {
    rx[i] = mouseX;
    ry[i] = mouseY;
    circle(rx[i], ry[i], 10); 
    }  

  if(frameCount>180)
    {
    circle(rx[i]+400, ry[i], 10); 
    } 
  
  if(frameCount>2*180)
    {
    frameCount = 0; // Resets frameCount. -1 will run setup() again!
    background(255);
    }
  }

It records mouseX and mouseY for 180 frames and plays them back on right side 180 frames (3 seconds) later and repeats.

PVectors, ArrayLists, timing, etc. would follow… and then maybe a Class

I code mostly for fun these days and to engage my mind.

:)

2 Likes

Very good, very nice thanks man. I will use it to record position of one motor that i move myself in order to reproduce this position on others motors aligned one by one with a litlle time delay. In this manner, i will try to follow a music and seeing what beautiful effect, this group of motors will do. I hope to show u this tomorrow or Monday.
Too,
Do you think you might manage to repeat the recorded movement by beginning by the end? It would be a intersting effect i guess :wink:

Hi glv,
Just to tell you that I have tried to adapt your program with mills() instead frameCount, because I really need to use mills() to have a really constant loop of x millisecondes.

I tried this but it doesn’t work well. See u. :slight_smile:

int num = 3600;

int timer1, timer2;



float mx[] = new float[num]; // Future

float my[] = new float[num]; // Future



float rx[] = new float[num];

float ry[] = new float[num];

boolean Recorded;



void setup() 

  {

  size(800, 200);

  noStroke();

  fill(255, 0, 0, 50); 

  println("Start Drawing!");

  }



void draw() 

  {

  int i = int(millis()%2000);

  if(i>=0 && i<=1000)

    {
      

    rx[i] = mouseX;

    ry[i] = mouseY;

    circle(rx[i], ry[i], 10); 

    }  
    Recorded=true;
    if(Recorded=true)
 //  timer1=millis();
    {
} 
  println (i);

  if(i> 1000)

    {
    //  timer1=millis()+1000;
    circle(rx[i-1000]+400, ry[i-1000], 10); 
    
// background(255);
    } 
  Recorded=false;
  

   if(millis()> timer2)

    {
      timer2=millis()+2000;

   i=0;
  //  frameCount = -1; // Resets frameCount. -1 will run setup() again!
    }    
  }

Here a solution to record 2 sec mouse x and mouse y
Play it automatically for 2 sec.
To record again, you have to press quickly the mouse at the end of the 2 second replayed.

int num = 40*2; // you need normally 45 frames/s, so to record and play 1 sec, you should need 90 frames
int numberSec = 4;

float mx[] = new float[num]; // Future
float my[] = new float[num]; // Future

float rx[] = new float[num];
float ry[] = new float[num];

int beginTime,endTime,TimeMiddleElapsed,LastTimeMiddleElapsed,Timer,Timer2,LastTimeElapsed;

public void settings() { // with this setting, you only need 160 frames to do 4 secondes
  size(600, 600, P3D);
} 

void setup() 
  {
  LastTimeMiddleElapsed=1980;
  LastTimeElapsed=4000-20;
  frameRate (45);
  size(600, 600);
  noStroke();
  fill(255, 0, 0, 50); 
  println("Start Drawing!");
  }
  
void draw() 
  {   
  samplingMovement();
  }
  
void samplingMovement() {

    Timer= millis()%2000;
    Timer2 = millis()%4000;
   //  print ("             Timer  "); print (Timer);
   //  print ("             Timer2  "); println ( Timer2);
    int i = int(frameCount%(20*4));
    if(frameCount>=0 && frameCount<=20*4+0 )
    {
    if(frameCount<=1) { 
     int timeElapsed= endTime-beginTime; 
     print (" timeElapsed"); println (timeElapsed);
     beginTime=millis();
     background(0);     
    } 
    if(frameCount>0 && Timer<=2000 && Timer2>=2000 )  // record 2 secondes  
    {
    rx[i] = mouseX;
    ry[i] = mouseY;
    mx[i] = rx[i];
    my[i] = ry[i];
    fill(255, 0, 0, 50); 
    circle(rx[i], ry[i], 10); 
    }    
   }  
   
    int middleTime = millis(); 
    int TimeMiddleElapsed = middleTime -beginTime;
    
    if ( TimeMiddleElapsed >=1970 && TimeMiddleElapsed <=2030 || (frameCount >=20*4+1 && frameCount <=20*4+1)) {  
       LastTimeMiddleElapsed=TimeMiddleElapsed;
       print (frameCount); print ("  TimeMiddleElapsed "); println ( TimeMiddleElapsed);
       } 
     
    if(frameCount>=20*4+1 ) // begin to replay for 2 sec
    {
    circle(mx[i]+400, my[i], 10); 
  //  print (frameCount); print (" ry' "); print (i); print ("  "); println (ry[i]);
    print (frameCount); print (" ry "); print (i); print ("  "); print (ry[i]);
    print (" my "); print (i); print ("  "); println (my[i]);
    } 
  
    if(frameCount>=2*20*4 && frameCount<=2*20*4+0  ) //
    {
      
    endTime=millis();
    int timeElapsed= endTime-beginTime; 
    LastTimeElapsed= timeElapsed;
     print (" LastTimeElapsed"); println (LastTimeElapsed);
    Timer=0;
    Timer2=0;
    background(255);
    
       // frameCount = -1; // Resets frameCount. -1 will run setup() again!

    frameCount = 161; // Restart only recorded loop
    }
    
    if (mousePressed==true && frameCount>=161
     ) {
    frameCount = 0; // Restart main loop
     }      
}