tu peux essayer ça :
float angle = diffAngle(PI + (frameCount / 5.0) * cos (1000 / 500.0),0);
if(angle > 0 )
phases[0][frameCount % nbMaxDelais]= angle - HALF_PI ; // position du point de depart + vitesse * phi constant ==> ici vitesse du point phases[0] est constante
else
phases[0][frameCount % nbMaxDelais]= 2* PI - angle - HALF_PI;
Pardon, j'avais pas dit merci
J'ai re-bossé la fonction pour m'approcher d'une vague qui se décalle de 0 à PI, puis de PI à 0 automatiquement.
Voici le programme, pour voir ce que je veux il faut dé-commenter la ligne 139, je te laisse faire pour que tu comprennes l'étape de transformation du mouvement.
String debug ="";
// 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 frameRatio = 30;
int nbBall = 10;
int nbMaxDelais = 2000;
float pendulairePhaseX;
float pendulairePhaseY;
// Code pour option de follow
boolean firstFollowingLast = true;
float deltaFollow = PI/180;
boolean firstFollowingStarted = false;
float [][] phases = new float[nbBall][nbMaxDelais];
void setup() {
new PeasyCam(this, 2000);
frameRate(frameRatio);
for (int i = 0; i < nbBall; i++) {
for (int j = 0; j < nbMaxDelais; j++)
phases[i][j] = PI;
}
}
public void settings() {
size(600, 600, P3D);
}
void draw() {
println(frameCount + ": " + ( debug ));
background(0);
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
// ************************** RAPPEL
// phases[0][frameCount % nbMaxDelais]= PI + (frameCount / 5.0) * sin (1000 / 500.0); // position du point de depart + vitesse * phi constanst ==> ici vitesse du point phases[0] est constante
//point O tourne dans le sens anti-horaire à vitesse constante
// phases[0][frameCount % nbMaxDelais]= TWO_PI + (frameCount / 5.0) * sin (frameCount / 50.0); //position du point de depart + vitesse* phase sinusoidale ==> ici vitesse 0 progresse suivant une sinusoidale
//point O tourne dans les deux sens à vitesse non constante
// **************************
float angle = diffAngle(PI + (frameCount / 4.0) * cos (1000 / 500.0),0);
//**** ci dessous pour avoir le point du fond qui oscille de 0 à 180°
if(angle > 0 )
phases[0][frameCount % nbMaxDelais]= (angle - HALF_PI);// position du point de depart + vitesse * phi constant ==> ici vitesse du point phases[0] est constante
else
phases[0][frameCount % nbMaxDelais]= (2* PI - angle - HALF_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, 5 , QUARTER_PI/6); // ici, le temps que les points attendent pour se suivre est de 5 frames, et il faut un espace entre eux de QUARTER_PI/6
drawBall(i, phases[i][frameCount % nbMaxDelais] );
//*** print ("phases[0] "); print(i); print (" "); print (phases[0] [frameCount % nbMaxDelais] );
//*** print ("phases[I] "); print(i); print (" "); print (phases[i] [frameCount % nbMaxDelais] );
//*** println (" ");
}
/*
for(int i = 0; i < nbBall; i++) { //Animation brute sans suivi, juste avec une formule
//drawBall(i, PI + (i * frameCount / 50.0) * cos (frameCount / 500.0) );
}*/
//********************************UTILITE de firstFollowingLast=true or false? je l'ai retiré et je vois pas de différence
// if(frameCount > nbMaxDelais/10 && firstFollowingLast == true && abs(diffAngle(phases[0][frameCount % nbMaxDelais],phases[nbBall-1][frameCount % nbMaxDelais])) < deltaFollow ) {
if(frameCount > nbMaxDelais/10 && abs(diffAngle(phases[0][frameCount % nbMaxDelais],phases[nbBall-1][frameCount % nbMaxDelais])) < deltaFollow ) {
colorMode(RGB, 255, 255, 255);
fill( 0, 0, 255 );
println("diffangle" + ": " + diffAngle(phases[0][frameCount % nbMaxDelais],phases[nbBall-1][frameCount % nbMaxDelais]));
firstFollowingStarted = true;
debug ="First follow last";
println (debug);
}
if(firstFollowingStarted) {
colorMode(RGB, 255, 255, 255);
fill( 255, 0, 0 );
debug ="firstFollowingStarted";
follow(nbBall-1, 0, 5, QUARTER_PI/4); // Modifier les deux derniers paramètres : délais et phase
drawBall(0, phases[0][frameCount % nbMaxDelais] ); // affiche le point 0
}
}
void drawBall(int n, float phase) {
pushMatrix();
translate(-w2, -h2, -1000);
noStroke();
float side = height*0.15*1/nbBall;
float rayon = width/2;
float x = rayon*cos(phase);
float y = rayon*sin(phase);
for (int i = 1; i < nbBall; i++) { // ce for { } est pour contraindre le mouvement à rester sur 180°
if (x >= PI ) {
pendulairePhaseX= map( x, 0, TWO_PI, 1.5*PI, -0.5*PI);
}
if (x >= 0 && x < PI ) {
pendulairePhaseX= map( x, 0, TWO_PI, -0.5*PI, 1.5*PI);
}
if (x <= -PI) {
pendulairePhaseX= map( x, 0, -TWO_PI, 1.5*PI, -0.5*PI);
}
if (x < 0 && x > -PI) {
pendulairePhaseX= map( x, 0, -TWO_PI, -0.5*PI, 1.5*PI );
}
if (y >= PI ) {
pendulairePhaseY= map( y, 0, TWO_PI, 1.5*PI, -0.5*PI);
}
if (y >= 0 && y < PI ) {
pendulairePhaseY= map( y, 0, TWO_PI, -0.5*PI, 1.5*PI);
}
if (y <= -PI) {
pendulairePhaseY= map( y, 0, -TWO_PI, 1.5*PI, -0.5*PI);
}
if (y < 0 && y > -PI) {
pendulairePhaseY= map( y, 0, -TWO_PI, -0.5*PI, 1.5*PI );
}
// x=pendulairePhaseX;
}
// y=pendulairePhaseY; //si on decommente cette ligne vague se decale petit à petit depuis les deux côtés du mouvement de 180° !!!
// translate (x, y, 200+(50*5*n)); // on voit la vague qui se decale petit à petit, chouette, mais sur 360° alors que j'aimerais sur 180°
// translate (pendulairePhaseX, pendulairePhaseY, 200+(50*5*n)); // on voit la vague qui se decale petit à petit, mais sur 90° (à vue de nez)
translate (x, y, 200+(50*5*n)); // on voit la vague comme j'aimerais si on fait ce qui ait dit à la ligne 139
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;
}
Ensuite j'ai fait une video expliquant la fonction pour faire la "meme chose" d'une autre maniere.
https://youtu.be/VDR-ot7tQhs
Voila une petite explication écrite de la fonction que j'ai crée .
Comme dans la transformation des points x, y que j'ai faite dans la fonction de MIKE, le mouvement de l'ensemble des points est contraint entre 0 et PI alors que la donnée qui conduit le mouvement paramétrique des phases x, y (suis pas sûr de l’expression) ici, net.phase[i] est bien une phase allant de 0 à deux PI. Il faut se dire que les données x y parametrent la position d’un point sur un cercle et moi j’ai fait en sorte de voir ses points de 0 à PI.
J’explique tous ca jusqu’à 4 min 14 et comment le point deux suit le 11, mais pas tous le temps, ceci implique un joli décalage dans le suivi de la vague.. Apres 4 min 30 pas la peine d’écouter je cherchais à bien paramétrer la vitesse de l’ensemble de points.
A partir de 10 min 13 jusqu’à la fin de la video, le mouvement est celui que je veux, mais j'aimerais qu'il soit possible à 45 frames par secondes et pas à 5 frames par secondes. Pour eviter les à-coups et avoir un mouvement fluide. A 45 frames/secondes, les points se suivent mais le fait qu'ils attendent 200 ms, fait un mouvement d'ensemble saccadé pas beau.
Je mets ma fonction ici
void formerKeyo() { print (" circularMov "); println (circularMov);
if (circularMov==false ){
memoryi=0;
for (int i = 2; i < 11; i++) {
print ("formerEvent"); print (i); print (" ") ;print (formerEvent[i]) ;
if ( millis()>formerEvent[i]+200 && // si le temps est supérieur de 200 ms par rapport à la dernier fois et que le point i+1 est supérieur de 200 pas par rapport au point i
(((PendularOldLeftVirtualPosition[i] <= PendularLeftVirtualPosition[i+1]+800*0.25) && (PendularLeftVirtualPosition[i]+800*0.25 > PendularLeftVirtualPosition[i+1]) && (PendularOldLeftVirtualPosition[i]< PendularLeftVirtualPosition[i])) ||
((PendularOldLeftVirtualPosition[i]+800*0.25 >= PendularLeftVirtualPosition[i+1]) && (PendularLeftVirtualPosition[i]< PendularLeftVirtualPosition[i+1]+800*0.25)&& (PendularOldLeftVirtualPosition[i] > PendularLeftVirtualPosition[i])))
){
memoryi=i;
formerEvent[i]=millis();
net.phase[i+1]= net.oldPhase[i];//
}
else if (millis()<=formerEvent[i]+200){
memoryi=100*i;
}
}
print ("AVformerEvent"); print (11); print (" "); println (formerEvent[11]) ;
if (millis()>formerEvent[11]+200 && // si le temps est supérieur de 200 ms par rapport à la derniere fois et que le point 11 est supérieur à 200 pas par rapport au point 2
((PendularOldLeftVirtualPosition[11] <= PendularLeftVirtualPosition[2]+800*0.25) && (PendularLeftVirtualPosition[11]+800*0.25 > PendularLeftVirtualPosition[2]) && (PendularOldLeftVirtualPosition[11]< PendularLeftVirtualPosition[11]) ||
((PendularOldLeftVirtualPosition[11]+800*0.25 >= PendularLeftVirtualPosition[2]) && (PendularLeftVirtualPosition[11]< PendularLeftVirtualPosition[2]+800*0.25)&& (PendularOldLeftVirtualPosition[11] > PendularLeftVirtualPosition[11]))
)){
memoryi=11;
formerEvent[11]=millis();
net.phase[2]= net.oldPhase[net.size()-1];
print ("APformerEvent"); print (11); print (" "); println (formerEvent[11]) ;
}
else if (millis()<=formerEvent[11]+200){ // si le temps n'est pas supérieur à 200 ms alors laisse les points suivrent leur propre vitesse
memoryi=12;
}
}
}
Voilà voilà
Le but est de soit faire en sorte que j'ai ma fonction qui puisse bien attendre un certain temps avant de suivre les points, car elle fonctionne à 5 images secondes et pas à 45 images. Ca fait encore plus saccader le mouvement si je passe de 5 à 45. Je vais filmer un exemple demain.
Je pense qu'il faut que je baisse le temps de suivi au fur et à mesure que j'augmente le nombre d'image / sec. Bref je vais essayer.
Ou réussir à trouver cette vague à partir du programme de Mike, ce qui m'a l'air plus saint et plus simple!