Aller au contenu


bvking

Inscrit(e) (le) 29 janv. 2019
Déconnecté Dernière activité juil. 05 2023 02:42
-----

Sujets que j'ai initiés

Tige creuse Vs barre carré creuse ? carbone et télescopique ?

04 juillet 2023 - 12:32

Bonjour,

 

Je fais tourner des barres en L en alu de 100 g et 100 mm.  La barre n'est pas fixée au moteur en son centre mais à 70/30 cm.

Au bout des 70 cm est fixée une masse de 15 g. Cette masse est un sytème de LED.

Les moteurs pas à pas peuvent soutenir un couple de 1.2 N.m soit 122 g/m , si je ne m'abuse. 

 

Sans faire de calcul, la masse de ma barre est trop lourde. Je l'ai choisie en L pour qu'elle soit rigide.

Existent-ils des tiges ou barres creuses que je puisse assembler avec des bagues? ou encore mieux télescopiques? ou plus simplement de un mètre ? (que je découperai ensuite)

 

Je veux garder la dysymetrie 70/ 30 ou 80/20 ou 90/10 (selon que le moteur puisse supporter) pour fixer un bloc de pile du coté des 20 cm pour alimenter à l'autre bout de la tige le système de LED.

 

Grand merci pour vos suggestions.

Benj ;)

 

 

 

 

 


Interpolation à partir d'un pseudo cercle.

14 mars 2023 - 08:33

Bonjour à toutes et tous!

 

Pour un projet artistique, j'echantillonne (sampling) pendant deux secondes un pseudo cercle (pas entièrement fini) tracé à la souris.

Puis cette forme se répète toute seule.

 

J'aimerai ajouter entre le dernier et le premier point tracés, un point d'interpolation qui soit à la moyenne

de la droite affine crée par le premier et le dernier.

 

Il faut essayer de tracer un cercle sur deux secondes. L'enregistrement se fait à chaque changement de seconde.

(mais on est pas censé le savoir).

 

Merci pour votre aide ;) et ce n'est que le début!

int actualSec,lastSec,measure,measureToStartRecording;;
boolean bRecording = false;
boolean mouseRecorded =  true;

class Sample {
  int t, x, y;
  Sample( int t, int x, int y ) {
    this.t = t;  this.x = x;  this.y = y;
  }
}

class Sampler {
  
  ArrayList<Sample> samples;
  int startTime;
  int playbackFrame;
  
  Sampler() {
    samples = new ArrayList<Sample>();
    startTime = 0;
  }
  void beginRecording() {   
    samples = new ArrayList<Sample>();
    playbackFrame = 0;
  }
  void addSample( int x, int y ) {  // add sample when bRecording
    int now = millis();
    if( samples.size() == 0 ) startTime = now;
    samples.add( new Sample( now - startTime, x, y ) );
  }
  int fullTime() {
    return ( samples.size() > 1 ) ? 
    samples.get( samples.size()-1 ).t : 0;
  }
  void beginPlaying() {
    startTime = millis();
    playbackFrame = 0;
    println( samples.size(), "samples over", fullTime(), "milliseconds" );
  }
  
 
  void draw() {
    stroke( 255 );
    
    //**RECORD
    beginShape(LINES);
    for( int i=1; i<samples.size(); i++) {
      vertex( samples.get(i-1).x, samples.get(i-1).y ); // replace vertex with Pvector
      vertex( samples.get(i).x, samples.get(i).y );
    }
    endShape();
    //**ENDRECORD
    
    //**REPEAT
    int now = (millis() - startTime) % fullTime();
    if( now < samples.get( playbackFrame ).t ) playbackFrame = 0;
    while( samples.get( playbackFrame+1).t < now )
      playbackFrame = (playbackFrame+1) % (samples.size()-1);
    Sample s0 = samples.get( playbackFrame );
    Sample s1 = samples.get( playbackFrame+1 );
    float t0 = s0.t;
    float t1 = s1.t;
    float dt = (now - t0) / (t1 - t0);
    float x = lerp( s0.x, s1.x, dt );
    float y = lerp( s0.y, s1.y, dt );
    circle( x, y, 10 );
  }
  
}

Sampler sampler;

void setup() {  
  size( 800, 800, P3D );
  frameRate( 30 );  
  sampler = new Sampler();
}

void draw() {
  background( 0 );
  activeSampling();
  stopSampling();
  
  if  (actualSec!=lastSec){
       lastSec=actualSec;
       measure++;
       textSize (100);
       text (measure, 100, 100 );
     }
       actualSec =(int) (millis()*0.001);  // 
 
  if( bRecording) { // draw circle
    circle( mouseX, mouseY, 10 );
    sampler.addSample( mouseX, mouseY );
  }
  
  else {    
  if( sampler.fullTime() > 0 )
        sampler.draw();
  }
}

void mousePressed() {
  bRecording = true;   // draw circle
  mouseRecorded = true;
  measure=0;
}
  
void activeSampling() { 
   if (measure<=1 && measure>=1 &&actualSec!=lastSec && mouseRecorded == true) {
  sampler.beginRecording();
  }
}

void stopSampling() { 
   if (measure<=3 && measure>=3  && actualSec!=lastSec) {  
  mouseRecorded = false;
     //**REPEAT
  bRecording = false;
  sampler.beginPlaying();
  }
}

Ajouter un signal circulaire à un signal circulaire. Essayer de compter les tours

14 octobre 2022 - 08:14

Bonjour,

10 boules tournent dans le sens des aiguilles d'une montre.En appuyant sur 'b', vous voyez un signal circulaire sur les 10 boules puis en appuyant sur 'q', vous pouvez voir un signal circulaire s'ajouter à une balle différente toutes les 200 ms.
J'essaie d'avoir la position absolue de chaque balle. Ensuite, je vais utiliser des positions pour les mettre dans un Arduino pour contrôler les moteurs
J'essaie d'obtenir le nombre de révolutions ; dans ce cas, je peux multiplier la révolution par la position pour avoir la position réelle mais ce n'est pas facile d'avoir le nombre de révolutions.
Peut-être y a-t-il une solution quelque part ? Ou utiliser les phases de chaque balle d'une autre manière ?
Merci beaucoup pour votre aide !
 
import peasy.*;
PeasyCam cam;

// change these for screen size
float w = 600;
float h = 600;

// don't change these
float w2 = w / 2;
float h2 = h / 2;

int nbBall = 10;
//******************         FollowMovement
int formerDecayTime, decayTime;
int networkSize = 12;
int NumberofStep = 6400;
int formerFormerKey;
int formerKey;

float [] phaseFollowLFO= new float[networkSize]; // 
float [] oldPosF= new float[networkSize]; // 
float [] newPosF= new float[networkSize]; //
float [] oldLfoPhase=  new float[networkSize]; //
float [] lfoPhase=  new float[networkSize]; //
float [] LFO=  new float[networkSize]; //
int []  DataToDueCircularVirtualPosition = new int[networkSize ];
//float [] phaseShiftingFollowLFO = new float[12];
float phaseShiftingFollowLFO;
float timeLfo;
int decayTimeLfo;
int formerDecayTimeLfo;
int [] rev = new int[networkSize]; // counter of revolution

float [] newPosX =  new float[12]; //;
float [] oldPosX =  new float[12]; //;

char letter;
boolean doA,doQ;
int oscillatorChange;

int decayTimeBis;
int formerDecayTimeBis;
int formerKeyMetro;

float x,y,displacement,side;

public void settings() {
  size(600, 600, P3D);
} 

void setup(){
 new PeasyCam(this, 2000);
 frameRate(30); 
 formerFormerKey='#';
 key='q';
}

void draw() {
  background (0);
  
  lfoPattern();
   if (key=='b' || key=='c') {
     formerKeyMetro =  key; // choose mode to "follow"  
     }

  if (formerKeyMetro == 'b' ){
    splitTimeLfo();
    
   if (key=='q' || key=='a') {
     letter = key;   
     }
  switch(letter) {
    case 'q': 
    doA=false;
    doQ=true;
    break;
    case 'a': 
    doA=true;
    doQ=false;
    break;
     
    }
    
   if (formerFormerKey == '#') { //  && doA==true
    // lfoPattern();
      print ("  normal " + frameCount + " lfoPhase[1] " + lfoPhase[1] + " lfoPhase[2] " + lfoPhase[2]);    println (   ); 
      for (int i = 2; i <  networkSize-0; i+=1) { 
       LFO[i] = lfoPhase[1]%TWO_PI; 
   if (LFO[i]<0){        
       LFO[i] = phaseFollowLFO[i] -  LFO[i];
       DataToDueCircularVirtualPosition[i]= int (map (LFO[i], 0, -TWO_PI, NumberofStep, 0)); 

       newPosX[i]= map (DataToDueCircularVirtualPosition[i], NumberofStep, 0, 0, -TWO_PI);
  }
       
   else
       LFO[i] = phaseFollowLFO[i] +  LFO[i];
       DataToDueCircularVirtualPosition[i]= (int) map (LFO[i], 0, TWO_PI, 0, NumberofStep);

       newPosX[i]= map (DataToDueCircularVirtualPosition[i], 0, NumberofStep, 0, TWO_PI);
 
   }
  
   if (LFO[oscillatorChange]<0){        
       LFO[oscillatorChange] = phaseFollowLFO[oscillatorChange]-LFO[oscillatorChange]; 
       DataToDueCircularVirtualPosition[oscillatorChange]= int (map (LFO[oscillatorChange], 0, -TWO_PI, NumberofStep, 0)); 

       newPosX[oscillatorChange]= map (DataToDueCircularVirtualPosition[oscillatorChange], NumberofStep, 0, 0, -TWO_PI);
  }
       
   else
       LFO[oscillatorChange] = phaseFollowLFO[oscillatorChange]+LFO[oscillatorChange];
       DataToDueCircularVirtualPosition[oscillatorChange]= (int) map (LFO[oscillatorChange], 0, TWO_PI, 0, NumberofStep);

       newPosX[oscillatorChange]= map (DataToDueCircularVirtualPosition[oscillatorChange], 0, NumberofStep, 0, TWO_PI);
  }
 
   if (doQ==true ){
    lfoPattern();
   //   followSignalLfo(frameRatio);
  //   pendularPattern(); // offset with lfo oscillator by osillator
    print ("  q " + frameCount + " "); print ("  mov+LfoPhase  ");    println (LFO[oscillatorChange]  ); 
    for (int i = 2; i <  networkSize-0; i+=1) { 
     phaseFollowLFO[oscillatorChange]= PI/10*-oscillatorChange; // to understand
  //   phaseFollowLFO[oscillatorChange]= lfoPhase[1];
     LFO[oscillatorChange]=  LFO[i]+phaseFollowLFO[i];  // add offset given by pendularPattern
     LFO[oscillatorChange]=  LFO[i]%TWO_PI; 
  
   
    if (LFO[i]<0){
   
     DataToDueCircularVirtualPosition[i]= int (map (LFO[i], 0, -TWO_PI, NumberofStep, 0)); 
      

       newPosX[oscillatorChange]= map (DataToDueCircularVirtualPosition[i], NumberofStep, 0, 0, -TWO_PI);
  //   newPosX[i]= LFO[i];
       }
       
   else
    
    DataToDueCircularVirtualPosition[i]= (int) map (LFO[i], 0, TWO_PI, 0, NumberofStep);  
    
    newPosX[oscillatorChange]= map (DataToDueCircularVirtualPosition[i], 0, NumberofStep, 0, TWO_PI);
    
     } //
 
   }
  //   doQ=false;
  key='#';// key='a'; // formerFormerKey = '#';

     for (int i = 2; i <  networkSize-0; i+=1) {
    drawBall(i, newPosX[i] );
    println ("  newPosX[i]" +    newPosX[i]  ); 
  }
   countRevsCaseB();
    for (int i = 2; i <  networkSize-0; i+=1) {
 
    oldPosX[i]=   newPosX[i] ; 
  }
  } 
 println(" formerFormerKey " + char (formerFormerKey) + " formerKey " + char (formerKey) + " key " + key)  ;
 formerFormerKey= formerKey;
 formerKey=key;
}  

void countRevsCaseB() { // ============================================= Ter NE PAS TOUCHER LE COMPTEUR ou Reduire l'espace avant et apres 0 pour eviter bug à grande vitesse
  
  for (int i = 0; i <  networkSize; i++) { 
    // decrement caused by negative angular velocity
    // both positive angles || both negative angles || positive-to-negative angle
    //   if (//(net.oldPhase[i] < 0.25 * PI && net.phase[i] > 1.75 * PI) ||//
    if (
      ((oldPosX[i] < 0.25 *PI && oldPosX[i]>0)  && (newPosX[i] > -0.25* PI && newPosX[i] <0))  || 
      (oldPosX[i] < -1.75 * PI && newPosX[i] > -0.25 * PI)// ||
      ) {

      rev[i]--;
 
    } else { // if you do twice there is a funny bug
      //    decompte[i]  ++; 
      //   revolution[i]=0;
    }
    // increment caused by positive angular velocity
    // both positive angles || both negative angles || negative-to-positive angle

    if (
      ((oldPosX[i] > -0.25 *PI && oldPosX[i]<0)  && (newPosX[i] < 0.25* PI && newPosX[i] >0))  || 
      (oldPosX[i] > 1.75 * PI && newPosX[i] < 0.25*PI)
      ) {
      rev[i]++;
    } else {

    }
      print (" revolution "); print ( i); print ("  "); println (rev[i]);
  }
 
 } 
 
void  splitTimeLfo() { 
    
  if (formerDecayTimeLfo>decayTimeLfo){
  oscillatorChange=oscillatorChange+1;
 // key='q';
  } 
  formerDecayTimeLfo = decayTimeLfo; 

   int splitTimeLfo = millis()%200; // linear time  to change " oscillator " each 200 ms
   
         oscillatorChange=oscillatorChange%12;
     if (oscillatorChange<=0) {
         oscillatorChange=2;
         }
         decayTimeLfo = splitTimeLfo;
         print (" oscillatorChange "); println ( oscillatorChange ); 
      
}

void lfoPattern() {
    float signal1 = PI + (frameCount / 10.0) * cos (1000 / 500.0)*-1;
    float signal2 = PI + (frameCount / 11.0) * cos (1000 / 500.0)*-1;
 
    if (signal1 > 0 )
     lfoPhase[1]= signal1%TWO_PI;  // gauche droite vers le hau.t CIRCULAR MODE usefull ?// diffAngle(angle, HALF_PI);//% TWO_PI  // position du point de depart + vitesse * phi constant  ==> ici vitesse du point phases[0] est constante
    else
     lfoPhase[1]= signal1%TWO_PI;
    
     if (signal2 > 0 )
     lfoPhase[2]= signal2%TWO_PI;  // gauche droite vers le hau.t CIRCULAR MODE usefull ?// diffAngle(angle, HALF_PI);//% TWO_PI  // position du point de depart + vitesse * phi constant  ==> ici vitesse du point phases[0] est constante
    else
     lfoPhase[2]= signal2%TWO_PI;
     
  //  print (" lfoPhase[1] "); print (lfoPhase[1]);   print (" lfoPhase[2] "); println (lfoPhase[2]);
    
  }

void drawBall(int n, float phase) {
//  print (n); print (" "); println (phase);
  pushMatrix();
  translate(-w2, -h2, -1000);
  noStroke();
  float side = height*0.15*1/nbBall;
  float rayon = width/2;
  
  x = rayon*cos(phase); //-300 à 300
  y = rayon*sin(phase);
  
  translate (x, y, 200+(50*5*n)); // 
  translate (100, 100, 200+(50*5*n));
  colorMode(RGB, 255, 255, 255);
  fill( 0, 255, 0 );
  sphere(side*3);
  popMatrix();
}

 


Suivre un signal avec un décalage en temps et non en frame.

12 septembre 2022 - 11:34

Bonjour,

 

Une balle [0] oscillant entre 0 et PI est suivie par 9 autres balles sans décalages temporels. Elles ont donc le meme signal.

J'aimerais, en appuyant une fois sur la flèche droite, que les balles de 1 à 9 autres suivent la balle 0 avec 1 à 9 * 500 ms seconde de retard.

J'ai un premier  programme qui fonctionne, les balles suivent bien le signal avec 10, 20 ... frame de retard.

Mais je veux qu'elles suivent le signal en fonction de l'incrementation d'un temps et non par l'incrementation par image ( par la fonction frameCount qui s'actualise dans la main loop).

Comment puis je faire?

J'ai fait une variable qui s'actualise avec la fonction millis() qui s'actualise bien avec l'horloge du processeurs et non par frameCount.

Ca fonctionne, mais mon incrementation temporelle n'est pas precise.

Aussi, je n'arrive pas à récupérer les positions des balles qui suivent la balle 0.

 

Merci pour vos signaux éclairés!

 

PS: Ici est le programme où frameCount est remplacé par frameCountBis qui s'actualise avec millis() 

String debug ="";
String dataToControlMotor;
boolean way;

// MANAGE PERSPECTIVE
import peasy.*;

// change these for screen size
float w = 1000;
float h = 800;

// don't change these
float w2 = w / 2;
float h2 = h / 2;

int nbBall = 9;
int nbMaxDelais = 2000;
float pendulairePhase;
float formerDecayTime, decayTime;
int frameCountBis = 0;
int lastSec, sec, countSec;

// Code pour option de follow
boolean firstFollowingLast = true;
float deltaFollow = PI/180;
boolean firstFollowingStarted = false;

float [][] phases = new float[nbBall][nbMaxDelais];
int[] phaseToMotor;
float [] phaseMapped;

float x, y;

float Phase;

int d, k; // to modulate parameter of phase and time offset

int frameRatio;

public void settings() {
  size(600, 600, P3D);  
}

void setup() {
  new PeasyCam(this, 2000);
  frameRatio=30;
  countSec=0;
  k=1;
  

  frameRate(frameRatio);
  for (int i = 0; i < nbBall; i++) {
    phaseToMotor= new int [nbBall];
    phaseMapped= new float [nbBall];

    for (int j = 0; j < nbMaxDelais; j++)
      phases[i][j] = PI;
  }
}

void draw() {
  background(0);
  if (lastSec>=sec){
  background (100);
  countSec++;
  };
  
  if (formerDecayTime>=decayTime){
      frameCountBis=frameCountBis+1;
  } 
   
   formerDecayTime = decayTime;
   decayTime = (millis()*1)%20;// counter actualise 20 times in on sec
   lastSec= sec; 
   sec=millis()%1000;
    
  println(frameCount + ": " + frameRatio + " : incrementTime " + frameCountBis + " Sec " + second() + " : sec " + countSec  + " decayT "  + decayTime + " : decay en ms " + d*50)   ;
 
  rotate(- TWO_PI  ); //TO change the beginning of the 0 (cercle trigo) and the cohesion point to - HALF_PI
  translate(width/2, -height/2, -1000);// To set the center of the perspective

  if (!firstFollowingStarted) {
    float signal = diffAngle(PI + (frameCountBis /4) * cos (1000 / 250.0), 0);

    print ("signal ");
    print ( signal );
    
    float deltaFollow = PI/180;
     
  if (signal > 0 )
      phases[0][frameCountBis/1 % nbMaxDelais]= diffAngle(signal, HALF_PI);//% 
  else
      phases[0][frameCountBis/1 % nbMaxDelais]= diffAngle(2* PI, signal + HALF_PI);//% TWO_PI
      drawBall(0, phases[0][frameCountBis  % nbMaxDelais]); // affiche le point 0. NE PAS AFFICHER SINON IL APPARAIT EN DOUBLE
  }

  for (int i = 1; i < nbBall; i++) {
    debug ="Normal follow ";
    //   follow( i-1, i, 20 * i, 0);  // Modifier les deux derniers paramètres : délais et phase
    follow( i-1, i, d, k*QUARTER_PI/8);  // ici, le temps que les points attendent pour se suivre est de d frames, et il faut un espace entre eux de QUARTER_PI/8

    //*****   drawBall(i, phaseMapped[i] );
    drawBall(i, phases[i][frameCountBis*1 % nbMaxDelais] );

  }   
      float balle0;
      float balle1;
      float balle2;
      
  balle0 = phases[0][frameCountBis  % nbMaxDelais];
  balle1 = phases[1][frameCountBis  % nbMaxDelais];
  balle2 = phases[2][frameCountBis  % nbMaxDelais];
  
    println(" balle0 " + balle0 + " balle1 " + balle1 + " balle2 " + balle2)  ;


}

void drawBall(int n, float phase) {
  pushMatrix();
  translate(-w2, -h2, -1000);
  noStroke();
  float side = height*0.15*1/nbBall;
  float rayon = width/2;
  
  x = rayon*cos(phase); //-300 à 300
  y = rayon*sin(phase);
  
  translate (x, y, 200+(50*5*n)); // 
  translate (100, 100, 200+(50*5*n));
  colorMode(RGB, 255, 255, 255);
  fill( 0, 255, 0 );
  sphere(side*3);
  popMatrix();
}

void follow( int target, int follower, int delais, float deltaphase) {
  int step = frameCountBis % nbMaxDelais;
  int followedStep = (step + nbMaxDelais - delais) % nbMaxDelais;
  phases[follower][step] = diffAngle(phases[target][followedStep] + deltaphase, 0);
}

float diffAngle(float angle1, float angle2) { // return the difference angle1 - angle2 between two angle between -PI PI
  float result = angle1 - angle2;
  while (result > PI) {
    result -= 2 * PI;
  }
  while (result < -PI) {
    result += 2 * PI;
  }
  return result;
}

void keyPressed () {
   
  if (keyCode == UP) {
    frameRatio=frameRatio+5;
    frameRatio=frameRatio%65;
 
      if (frameRatio <=0 ){
       frameRatio=5;
      }
       frameRate(frameRatio);  
  }
  if (keyCode == DOWN) {
   
  if (frameRatio <=5 ){
       frameRatio=5;
      }
       frameRatio=frameRatio-1;
  }
       frameRate(frameRatio); // pas dans le void draw
  
  if (keyCode == RIGHT) {
       println(" right INCREASE timeOffset ")  ; //
       d+= 10; // incremente de demi sec. I need to increment 1282 to have 60 sec. So one sec is 1282/60 => 21.5 incrementations/sec
       d=d%65;
       print ("d= timeOffsetRatio: ");
       println (d);
  }

  if (keyCode == LEFT) {
      println(" left INCREASE phase shifting"); //
      d-=10; // incremente de demi sec
     }
  }

programme avec FrameCount

String debug ="";
String dataToControlMotor;
boolean way;

// MANAGE PERSPECTIVE
import peasy.*;

// change these for screen size
float w = 1000;
float h = 800;

// don't change these
float w2 = w / 2;
float h2 = h / 2;

int nbBall = 9;
int nbMaxDelais = 2000;
float pendulairePhase;
float formerDecayTime, decayTime;
int frameCountBis = 0;
int lastSec, sec, countSec;

// Code pour option de follow
boolean firstFollowingLast = true;
float deltaFollow = PI/180;
boolean firstFollowingStarted = false;

float [][] phases = new float[nbBall][nbMaxDelais];
int[] phaseToMotor;
float [] phaseMapped;

float x, y;

float Phase;

int d, k; // to modulate parameter of phase and time offset

int frameRatio;

public void settings() {
  size(600, 600, P3D);  
}

void setup() {
  new PeasyCam(this, 2000);
  frameRatio=30;
  countSec=0;
  k=1;
  

  frameRate(frameRatio);
  for (int i = 0; i < nbBall; i++) {
    phaseToMotor= new int [nbBall];
    phaseMapped= new float [nbBall];

    for (int j = 0; j < nbMaxDelais; j++)
      phases[i][j] = PI;
  }
}

void draw() {
  background(0);
  if (lastSec>=sec){
  background (100);
  countSec++;
  };
  
  if (formerDecayTime>=decayTime){
      frameCountBis=frameCountBis+1;
  } 
   
   formerDecayTime = decayTime;
   decayTime = (millis()*1)%20;// counter actualise 20 times in on sec
   lastSec= sec; 
   sec=millis()%1000;
    
  println(frameCount + ": " + frameRatio + " : incrementTime " + frameCountBis + " Sec " + second() + " : sec " + countSec  + " decayT "  + decayTime + " : decay en ms " + d*50)   ;
 
  rotate(- TWO_PI  ); //TO change the beginning of the 0 (cercle trigo) and the cohesion point to - HALF_PI
  translate(width/2, -height/2, -1000);// To set the center of the perspective

  if (!firstFollowingStarted) {
    float signal = diffAngle(PI + (frameCount /4) * cos (1000 / 250.0), 0);

    print ("signal ");
    print ( signal );
    
    float deltaFollow = PI/180;
     
  if (signal > 0 )
      phases[0][frameCount/1 % nbMaxDelais]= diffAngle(signal, HALF_PI);//% 
  else
      phases[0][frameCount/1 % nbMaxDelais]= diffAngle(2* PI, signal + HALF_PI);//% TWO_PI
      drawBall(0, phases[0][frameCount  % nbMaxDelais]); // affiche le point 0. NE PAS AFFICHER SINON IL APPARAIT EN DOUBLE
  }

  for (int i = 1; i < nbBall; i++) {
    debug ="Normal follow ";
    //   follow( i-1, i, 20 * i, 0);  // Modifier les deux derniers paramètres : délais et phase
    follow( i-1, i, d, k*QUARTER_PI/8);  // ici, le temps que les points attendent pour se suivre est de d frames, et il faut un espace entre eux de QUARTER_PI/8

    //*****   drawBall(i, phaseMapped[i] );
    drawBall(i, phases[i][frameCount*1 % nbMaxDelais] );

  }   
      float balle0;
      float balle1;
      float balle2;
      
  balle0 = phases[0][frameCount  % nbMaxDelais];
  balle1 = phases[1][frameCount  % nbMaxDelais];
  balle2 = phases[2][frameCount  % nbMaxDelais];
  
    println(" balle0 " + balle0 + " balle1 " + balle1 + " balle2 " + balle2)  ;
}

void drawBall(int n, float phase) {
  pushMatrix();
  translate(-w2, -h2, -1000);
  noStroke();
  float side = height*0.15*1/nbBall;
  float rayon = width/2;
  
  x = rayon*cos(phase); //-300 à 300
  y = rayon*sin(phase);
  
  translate (x, y, 200+(50*5*n)); // 
  translate (100, 100, 200+(50*5*n));
  colorMode(RGB, 255, 255, 255);
  fill( 0, 255, 0 );
  sphere(side*3);
  popMatrix();
}

void follow( int target, int follower, int delais, float deltaphase) {
  int step = frameCount % nbMaxDelais;
  int followedStep = (step + nbMaxDelais - delais) % nbMaxDelais;
  phases[follower][step] = diffAngle(phases[target][followedStep] + deltaphase, 0);
}

float diffAngle(float angle1, float angle2) { // return the difference angle1 - angle2 between two angle between -PI PI
  float result = angle1 - angle2;
  while (result > PI) {
    result -= 2 * PI;
  }
  while (result < -PI) {
    result += 2 * PI;
  }
  return result;
}

void keyPressed () {
   
  if (keyCode == UP) {
    frameRatio=frameRatio+5;
    frameRatio=frameRatio%65;
 
      if (frameRatio <=0 ){
       frameRatio=5;
      }
       frameRate(frameRatio);  
  }
  if (keyCode == DOWN) {
   
  if (frameRatio <=5 ){
       frameRatio=5;
      }
       frameRatio=frameRatio-1;
  }
       frameRate(frameRatio); // pas dans le void draw
  
  if (keyCode == RIGHT) {
       println(" right INCREASE timeOffset ")  ; //
       d+= 10; // incremente de demi sec. I need to increment 1282 to have 60 sec. So one sec is 1282/60 => 21.5 incrementations/sec
       d=d%65;
       print ("d= timeOffsetRatio: ");
       println (d);
  }

  if (keyCode == LEFT) {
      println(" left INCREASE phase shifting"); //
      d-=10; // incremente de demi sec
     }
  }

Répéter un mouvement et le synchroniser sur un tempo.

17 août 2022 - 05:44

Bonjour,

Pour mon projet de machine artistique, j'ai besoin de sampler un mouvement et le jouer en boucle. Ce sample doit être caler sur le tempo!

Mais, y' a un petit problème, je m'explique:

 

Je dessine un mouvement avec la souris pendant deux secondes.

Il est répété en boucle en commençant exactement sur le début d'une nouvelle seconde.

Le problème est que le nombre d'image par seconde n'est pas constant. 

Des fois, il faut 27 image/sec, des fois 28. 

J'observe donc des décalages. Il faudrait que j'arrive à jouer cette boucle exactement par son début toutes les deux secondes.

Le défaut sur deux secondes est minimale, mais sur 8 secondes j'ai des décalages plus important.

Il faut trouver un moyen d'avoir la même donné toute les deux sec.

 

Merci pour vos contributions.

 

Mon programme ci-dessous. NB pour créer un mouvement mouvement il suffit de presser la souris. Le dessin commencera a être enregistré

au début de la période de deux secondes et exactement au changement de seconde.

//int num = 40; // you need normally 45 frames/s but actually with a 3D setting you  need only 40 frames
int num = 27; // you need normally 30 frames/s but actually with a 3D setting you  need only 26.33 frames
int numberSec = 2;

float mx[] = new float[num*numberSec]; // memorised frame played 
float my[] = new float[num*numberSec]; // 

float rx[] = new float[num*numberSec]; // recorded frame
float ry[] = new float[num*numberSec]; 

int beginTime,endTime,TimeMiddleElapsed,LastTimeMiddleElapsed,LastTimeElapsed;
int frame;
int restartTimer;
float Timer,Timer2;

boolean  mouseRecorded;
boolean synchroMeasure;
boolean beginSampling, endSampling;
int lastLastSec,lastSec,actualSec; 

public void settings() { // 
  size(600, 600, P3D);
} 

void setup() 
  {
  endSampling= false;
  synchroMeasure= false;
  mousePressed=false;
  mouseRecorded=false;

  frameRate (30);
  
  noStroke();
  fill(255, 0, 0, 50); 
  println("Start Drawing!");
  }
  
void draw(){  
  
     if  (lastLastSec!=lastSec){         
     print( "                 SAMPLING MODE " ) ;  print( " LASTLASTSEC " ) ; print( lastLastSec ) ; print( " LASTLAST%2 " ); print( lastLastSec%2 );
     print( " ACTUAL " ) ; print( actualSec ) ; print( " ACTUAL " ) ; print( actualSec ) ; print( " ACTUAL " ) ; println( actualSec ) ;
       
     lastLastSec=lastSec;
     synchroMeasure=true;
     background(40, 40, 255);  
     
     }
     else synchroMeasure=false;
    
     if  (actualSec!=lastSec){
         lastSec=actualSec;   
     }
         
    actualSec = second()%(numberSec+1);  // Values from 0 - x number of secondes
    samplingMovement(numberSec);
  }
  
void samplingMovement(float timeSec) {

     if (mousePressed==true)
      {
       mouseRecorded=true; 
     }  
    
      if(synchroMeasure==true && lastLastSec>=numberSec && lastLastSec<=numberSec){
      beginSampling=false;
     }    

     if (mouseRecorded==true  && synchroMeasure==true && lastLastSec<=0// 
     ) {
       print (" Restart Record ");  print (" Restart Record ");  println (" Restart Record ");
    mouseRecorded=false;
    endSampling= false;
    beginSampling=true;
    frame = 0; //
     }
     
    frame=frame+1;
     
    int i = int(frame%(num*timeSec+0)); // number of datas record = number of frame/ s  multipled by secondes
   
    if( beginSampling==true ) // frame>=0 &&
    {  
    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); 
    if (frame%1<=0) {
    print (" frame "); print (frame); print (" ry "); print (i); print ("  "); println (ry[i]);   // 
    }   
   }
   
    if( endSampling==true ) // begin to replay for 2 sec . If I Add frame>num*timeSec+1, there is no effect   
    {
    circle(mx[i]+400, my[i], 10);  
    if (frame%1<=0) {
    print (" frame "); print (frame); print (" ry "); print (i); print ("  "); println (ry[i]);   // 
    } 
     } 
    if(synchroMeasure==true && lastLastSec>=timeSec && lastLastSec<=timeSec){ // important to put condition here! or on the of the main loop
    endSampling=true;
   }   
}