Who knows well Geomerative?!

Dear all,
I face an issue I can’t solve for days despite the great help I received in this forum from @kll who helped me a lot. Unfortunately we didn’t find a way out. In the code below I deform+enlarge a text letter by letter according to mouse position. I find a way to keep each letter at different sizes but not the deformation. Once the mouse is more than 100px away from the letter, the text takes back its original form! How to keep it deformed?! I hope someone can help. Thanks a lot in advance.
L

import geomerative.*;
import ddf.minim.analysis.*;
import ddf.minim.*;

String soundNameFR = "FR_01";
Minim minim;
AudioPlayer soundsFR;
FFT fftFR;
float bandHeightFR;

int x, y;
String [] message={"music is like a mountain path"};
color textColor=0;
RFont f;
RShape [] gShape = new RShape[message.length];
float fontSize=110;
int splitGlyph = 120;
RPoint[][] pointsP;
float r = random(5, 20);
WordAttractor attractorW;
int tChildCount;
characterSpec characters;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(1920, 1080);
  RG.init(this);
  f = new RFont("SFNSText.ttf", int( fontSize), LEFT);

  minim=new Minim(this);
  soundsFR=minim.loadFile("FR_01.wav", 512);
  soundsFR.play();
  fftFR= new FFT(soundsFR.bufferSize(), soundsFR.sampleRate());
  for (int l =0; l<message.length; l++) {
   characters = new characterSpec( gShape[l], message[l]); 
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void draw() {

  background(0);
  smooth();
  soundFFTAnalyse();
  //pushMatrix();
  translate(200, height/2);  
  for (int l =0; l<message.length; l++) {    
    characters.update();  
    characters.display();
  }
 // popMatrix();
}


void soundFFTAnalyse() {
  AudioPlayer fr = soundsFR;
  fftFR.forward(fr.mix);
  for (int i=0; i<fftFR.specSize(); i++) {
    float bandDBFR = 10*log(fftFR.getBand(i)/fftFR.timeSize());
    bandHeightFR = map(bandDBFR*4, 0, -220, 0, height);
    constrain(bandHeightFR, 0, 1000);
    noStroke();
    fill(255, 0, 0);
    ellipse(fr.position()/10, bandHeightFR/20, 5, 5);
  }
} 

class characterSpec {

  RShape bShape;
  String m;
  RShape  letterShapes;
  float maxForce=2;
  float radiousForce=100;

  characterSpec(RShape _letterShapes, String _m) {

    letterShapes=_letterShapes;
    m = _m;
    pointsP= new RPoint [m.length()][splitGlyph];
    bShape = new RShape();    
    bShape = f.toShape(m); 
    RShape [] letterShapes = bShape.children;
    letterShapes = bShape.children;
    tChildCount = bShape.children.length;
  }

  void update() {
    for (int k = 0; k < tChildCount; k++) {
      //float posX=map(soundsFR.position(), 200, soundsFR.length(), 200, width-200); 
      //float posY=bandHeightFR/4;
      float posX = mouseX; 
      float posY = mouseY;
      float d= dist(posX, 0, bShape.children[k].getCenter().x, 0);
      float sx= map(d, 0, 100, 1, 1.01);
      //sx=abs(sx);
      //float r= map(d, 0, 100, 0, -TWO_PI);
      if (d<100) {
        bShape.children[k].scale(sx, bShape.children[k].getCenter());
        //bShape.children[k].rotate(r, bShape.children[k].getCenter());
      }
      for (int j=0; j<splitGlyph; j++) {
        float frac=(1.0/splitGlyph);  
        pointsP[k][j]=bShape.children[k].getPoint(j*frac);
        attractorW= new WordAttractor(posX-200, posY-500, pointsP[k][j]);
        attractorW.attract();
      }
    }
  }

  void display() {
    for (int k = 0; k < tChildCount; k++) {
      for (int j=0; j<splitGlyph; j++) {
        pushMatrix();
        translate(pointsP[k][j].x, pointsP[k][j].y);
        stroke(255);
        beginShape();
        noFill();
        strokeWeight(0.2);
        float angle = TWO_PI/18;
        rotate(angle*j/4+noise(pointsP[k][j].x)/20);
        bezier(-5*(noise(5)), 5, -10*(noise(2)), 5, -5*noise(10), -5, 5, -5);
        endShape();
        popMatrix();
      }
    }
  }
}

class WordAttractor {

  float force_radious = 100;
  float maxForce = 50;
  RPoint position;
  RPoint points;
  float pX;
  float pY;

  WordAttractor(float x, float y, RPoint p) {
    points =p;
    position = new RPoint(x, y);
  }

  void attract() {

    float d= points.dist(position);
    if (d < force_radious) {   
      RPoint desired = new RPoint(points);
      desired.sub(position);
      desired.normalize();
      desired.scale(map(d, 0, force_radious, maxForce, 0));
      points.add(desired);
    }
  }
}
1 Like

Hi,

It would help a lot to have all your files so we can also run it on our side.

Hi @jb4x thanks for your answer, sorry for that, in fact I don’t use minim nor sound in my example, just mouseX and mouseY as variables. Regarding the font, any .ttf font can be loaded from your computer.
Otherwise I can send you a font, but on the forum I can only send pics I think?! Tell if u can run it please. Thks a lot!

Do u need the font?! Thks

Remark:

When you move the mouse through one letter, it changes like with a lense.
This is achieved by the WordAttractor class in the code.
You want to make this change permanent.
But: Which moment do you want to be permanent? When the mouse leaves the letter again or is at its center? Here is one solution that works with the minimal distance to the points.

Solution:

here is one solution that records the distances in a 2D array

the result is not too beautiful

it works with the data when the mouse has the minimal distance to the points. It stores this as WordAttractor and shows it

search the three 2D arrays which names start with “list...” - they are parallel to pointsP

Chrisir

import geomerative.*;
import ddf.minim.analysis.*;
import ddf.minim.*;

String soundNameFR = "FR_01";
Minim minim;
AudioPlayer soundsFR;
FFT fftFR;
float bandHeightFR;

int x, y;
String [] message={"music is like a mountain path"};
color textColor=0;
RFont f;
RShape [] gShape = new RShape[message.length];
float fontSize=110;
int splitGlyph = 120;

RPoint[][] pointsP;
WordAttractor[][] listWordAttractors;  
float[][] listDistMap; 
PVector[][] listPV;

float r = random(5, 20);
WordAttractor attractorW;
int tChildCount;
characterSpec characters;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(1920, 1080);
  RG.init(this);
  f = new RFont("BRITANIC.TTF", int( fontSize), LEFT);

  minim=new Minim(this);
  soundsFR=minim.loadFile("jingle.mp3", 512);
  soundsFR.play();
  fftFR= new FFT(soundsFR.bufferSize(), soundsFR.sampleRate());
  for (int l =0; l<message.length; l++) {
    characters = new characterSpec( gShape[l], message[l]);
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void draw() {

  background(0);
  smooth();
  soundFFTAnalyse();
  //pushMatrix();
  translate(200, height/2);  
  for (int l =0; l<message.length; l++) {    
    characters.update();  
    characters.display();
  }
  // popMatrix();
}


void soundFFTAnalyse() {
  AudioPlayer fr = soundsFR;
  fftFR.forward(fr.mix);
  for (int i=0; i<fftFR.specSize(); i++) {
    float bandDBFR = 10*log(fftFR.getBand(i)/fftFR.timeSize());
    bandHeightFR = map(bandDBFR*4, 0, -220, 0, height);
    constrain(bandHeightFR, 0, 1000);
    noStroke();
    fill(255, 0, 0);
    ellipse(fr.position()/10, bandHeightFR/20, 5, 5);
  }
} 

// ======================================================================

class characterSpec {

  RShape bShape;
  String m;
  RShape  letterShapes;
  float maxForce=2;
  float radiousForce=100;

  characterSpec(RShape _letterShapes, String _m) {

    letterShapes=_letterShapes;
    m = _m;
    pointsP= new RPoint [m.length()][splitGlyph];

    listWordAttractors = new WordAttractor [m.length()][splitGlyph]; //
    listDistMap = new float  [m.length()][splitGlyph]; //
    for (int k = 0; k < m.length(); k++) {
      for (int j=0; j<splitGlyph; j++) {
        listDistMap[k][j]=1000000;
      }
    }
    listPV = new PVector  [m.length()][splitGlyph]; //

    bShape = new RShape();    
    bShape = f.toShape(m); 
    RShape [] letterShapes = bShape.children;
    letterShapes = bShape.children;
    tChildCount = bShape.children.length;
  }

  void update() {
    for (int k = 0; k < tChildCount; k++) {
      //float posX=map(soundsFR.position(), 200, soundsFR.length(), 200, width-200); 
      //float posY=bandHeightFR/4;
      float posX = mouseX; 
      float posY = mouseY;
      float d    = dist(posX, 0, bShape.children[k].getCenter().x, 0);
      float sx   = map(d, 0, 100, 1, 1.01);
      //sx=abs(sx);
      //float r= map(d, 0, 100, 0, -TWO_PI);
      if (d<100) {
        bShape.children[k].scale(sx, bShape.children[k].getCenter());
        //bShape.children[k].rotate(r, bShape.children[k].getCenter());
      }

      for (int j=0; j<splitGlyph; j++) {
        float frac=(1.0/splitGlyph);  

        pointsP[k][j]=bShape.children[k].getPoint(j*frac);

        float dist1 = dist(posX-200, posY-500, 
          pointsP[k][j].x, pointsP[k][j].y);
        if (k==4&&j==19)
          println(dist1);
        if (dist1 < listDistMap[k][j]) {
          listDistMap[k][j]=dist1; 
          listPV[k][j] = new PVector(posX-200, posY-500); 
          listWordAttractors[k][j] = new WordAttractor(listPV[k][j].x, listPV[k][j].y, pointsP[k][j]);
        }
        listWordAttractors[k][j].points = pointsP[k][j];
        listWordAttractors[k][j].attract();
      }
    }
  }

  void display() {
    for (int k = 0; k < tChildCount; k++) {
      for (int j=0; j<splitGlyph; j++) {
        pushMatrix();
        translate(pointsP[k][j].x, pointsP[k][j].y);
        stroke(255);
        beginShape();
        noFill();
        strokeWeight(0.2);
        float angle = TWO_PI/18;
        rotate(angle*j/4+noise(pointsP[k][j].x)/20);
        bezier(-5*(noise(5)), 5, -10*(noise(2)), 5, -5*noise(10), -5, 5, -5);
        endShape();
        popMatrix();
      }
    }
  }
}

// ======================================================================

class WordAttractor {

  float force_radious = 100;
  float maxForce = 50;
  RPoint position;
  RPoint points;
  float pX;
  float pY;

  WordAttractor(float x, float y, RPoint p) {
    points = p;
    position = new RPoint(x, y);
  }

  void attract() {
    float d= points.dist(position);
    if (d < force_radious) {   
      RPoint desired = new RPoint(points);
      desired.sub(position);
      desired.normalize();
      desired.scale(map(d, 0, force_radious, maxForce, 0));
      points.add(desired);
    }
  }
}
//
1 Like

here is a similar version but with a little more control.

You must hold the key now to store data.

Hold the key, move the mouse. Then release the key. The data (points) of the release moment is stored.

Chrisir


import geomerative.*;
import ddf.minim.analysis.*;
import ddf.minim.*;

String soundNameFR = "FR_01";
Minim minim;
AudioPlayer soundsFR;
FFT fftFR;
float bandHeightFR;

int x, y;
String [] message={"music is like a mountain path"};
color textColor=0;
RFont f;
RShape [] gShape = new RShape[message.length];
float fontSize=110;
int splitGlyph = 120;

RPoint[][] pointsP;
WordAttractor[][] listWordAttractors;  
float[][] listDistMap; 
PVector[][] listPV;

float r = random(5, 20);
WordAttractor attractorW;
int tChildCount;
characterSpec characters;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(1920, 1080);
  RG.init(this);
  f = new RFont("BRITANIC.TTF", int( fontSize), LEFT);

  minim=new Minim(this);
  soundsFR=minim.loadFile("jingle.mp3", 512);
  soundsFR.play();
  fftFR= new FFT(soundsFR.bufferSize(), soundsFR.sampleRate());
  for (int l =0; l<message.length; l++) {
    characters = new characterSpec( gShape[l], message[l]);
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void draw() {

  background(0);
  smooth();
  soundFFTAnalyse();
  //pushMatrix();
  translate(200, height/2);  
  for (int l =0; l<message.length; l++) {    
    characters.update();  
    characters.display();
  }
  // popMatrix();
}


void soundFFTAnalyse() {
  AudioPlayer fr = soundsFR;
  fftFR.forward(fr.mix);
  for (int i=0; i<fftFR.specSize(); i++) {
    float bandDBFR = 10*log(fftFR.getBand(i)/fftFR.timeSize());
    bandHeightFR = map(bandDBFR*4, 0, -220, 0, height);
    constrain(bandHeightFR, 0, 1000);
    noStroke();
    fill(255, 0, 0);
    ellipse(fr.position()/10, bandHeightFR/20, 5, 5);
  }
} 

// ======================================================================

class characterSpec {

  RShape bShape;
  String m;
  RShape  letterShapes;
  float maxForce=2;
  float radiousForce=100;

  characterSpec(RShape _letterShapes, String _m) {

    letterShapes=_letterShapes;
    m = _m;
    pointsP= new RPoint [m.length()][splitGlyph];

    listWordAttractors = new WordAttractor [m.length()][splitGlyph]; //
    listDistMap = new float  [m.length()][splitGlyph]; //
    for (int k = 0; k < m.length(); k++) {
      for (int j=0; j<splitGlyph; j++) {
        listDistMap[k][j]=1000000;
      }
    }
    listPV = new PVector  [m.length()][splitGlyph]; //

    bShape = new RShape();    
    bShape = f.toShape(m); 
    RShape [] letterShapes = bShape.children;
    letterShapes = bShape.children;
    tChildCount = bShape.children.length;
  }

  void update() {
    for (int k = 0; k < tChildCount; k++) {
      //float posX=map(soundsFR.position(), 200, soundsFR.length(), 200, width-200); 
      //float posY=bandHeightFR/4;
      float posX = mouseX; 
      float posY = mouseY;
      float d    = dist(posX, 0, bShape.children[k].getCenter().x, 0);
      float sx   = map(d, 0, 100, 1, 1.01);
      //sx=abs(sx);
      //float r= map(d, 0, 100, 0, -TWO_PI);
      if (d<100) {
        bShape.children[k].scale(sx, bShape.children[k].getCenter());
        //bShape.children[k].rotate(r, bShape.children[k].getCenter());
      }

      for (int j=0; j<splitGlyph; j++) {
        float frac=(1.0/splitGlyph);  

        pointsP[k][j]=bShape.children[k].getPoint(j*frac);

        float dist1 = dist(posX-200, posY-500, 
          pointsP[k][j].x, pointsP[k][j].y);

        // if (dist1 < listDistMap[k][j]) {
        if (keyPressed&&dist1 < 200) {
          listDistMap[k][j]=dist1; 
          listPV[k][j] = new PVector(posX-200, posY-500); 
          listWordAttractors[k][j] = new WordAttractor(listPV[k][j].x, listPV[k][j].y, pointsP[k][j]);
        }

        if (pointsP[k][j]!=null&&listWordAttractors[k][j]!=null) {
          listWordAttractors[k][j].points = pointsP[k][j];
          listWordAttractors[k][j].attract();
        }
      }
    }
  }

  void display() {
    for (int k = 0; k < tChildCount; k++) {
      for (int j=0; j<splitGlyph; j++) {
        pushMatrix();
        translate(pointsP[k][j].x, pointsP[k][j].y);
        stroke(255);
        beginShape();
        noFill();
        strokeWeight(0.2);
        float angle = TWO_PI/18;
        rotate(angle*j/4+noise(pointsP[k][j].x)/20);
        bezier(-5*(noise(5)), 5, -10*(noise(2)), 5, -5*noise(10), -5, 5, -5);
        endShape();
        popMatrix();
      }
    }
  }
}

// ======================================================================

class WordAttractor {

  float force_radious = 100;
  float maxForce = 50;
  RPoint position;
  RPoint points;
  float pX;
  float pY;

  WordAttractor(float x, float y, RPoint p) {
    points = p;
    position = new RPoint(x, y);
  }

  void attract() {
    float d= points.dist(position);
    if (d < force_radious) {   
      RPoint desired = new RPoint(points);
      desired.sub(position);
      desired.normalize();
      desired.scale(map(d, 0, force_radious, maxForce, 0));
      points.add(desired);
    }
  }
}
//
2 Likes

Dear Chrisir,

THANK YOU SO MUCH :smile: !! Your solution is so gooood!
Though I’m not sure I understand everything: it looks like you give the letters’point the value of the listWordAttractors, replacing the min value by the actual value of the deformed points?!

   listWordAttractors[k][j].points = pointsP[k][j];
        listWordAttractors[k][j].attract();

Thanks a lot I learn so much thanks to you. Would you mind if I ask you some questions in a next message? Now I need to move. Allthe best, L

1 Like

Not at all.

I am glad you like it!

The basic idea is simple: When we want the letters to keep their position after the mouse is gone, we need to store the mouse position and tell the WordAttractor to use the stored position.

But the storing only works when we don’t store the mouse position throughout but only when the mouse is close to the letter. Hence I check for the min distance and store the mouse position then when the distance is minimal (or when key is als pressed).

I am using these 2D arrays for this:

RPoint[][] pointsP;
WordAttractor[][] listWordAttractors;  
float[][] listDistMap; 
PVector[][] listPV;

The pointsP was there already

2 Likes

Dear @Chrisir,
Back to Processing after a big wave of work…!
Sorry to be back to you so late but I had two questions regarding the solutions you wrote me.
Why chosing such a high value? In order that the factual distances will never reach such a value?!

and one more stupid question:
why did you wrote this condition:

 if (k==4&&j==19)

to make a test?!
Sorry to annoy you this this kind of details, but it’s to be sure I understood the whole and to be able to think about it and reuse it when needed. Thank you very much.
By the way, I reload this project but I present a different version in an exhibition in Karlsruhe(Germany), and I credited you since you already helped me a lot last year! Thank you very much for your support and great help.
best wishes,
L

I set this very high since i do a < comparison against this value later and I want to make sure that one value is smaller than it so the condition is at least one time true

The k==4 line is just a test - i needed to know what kind of values we have kind of in the middle of it

Thank you very much @Chrisir !! Okay, perfect that’s what I understood!! But not sure of me…
And :

 float dist1 = dist(posX-200, posY-500, 
          pointsP[k][j].x, pointsP[k][j].y);

correspond to the min distance, right?!

That’s right

is the minimum distance.

I posted 2 versions, in the 2nd is keypressed && dist<200

Yes, thank you very much the 2nd version offers more control and allow to choose the moment you want to store the points positions and that’s really great ;)) Thank you very much for taking time to explain me.
Best,
L

1 Like

Dear @Chrisir,

Sorry to bother again, but I face a new problem with an array of String for the same sketch, should I create a new topic or post it here?!
Thanks in advance,

L

I guess here

Chrisir

Thanks a lot.
It’s really stupid but when I use the multilines text in the Characters’ class it takes the 1rst line of the String as reference, if the next line is longer it throws back an ArrayIndexOutOfBoundsException error…
How can I specify a specific number of char for each line in my update() function please?!
Thanks a lot.
Best,
L

ps: I’ve added the “-” char just to check out if I can visualize the whole text and thet the programm effectiveley takes the first line as reference.

import processing.pdf.*;
import geomerative.*;
import ddf.minim.analysis.*;
import ddf.minim.*;

String soundNameFR = "FR_01";
Minim minim;
AudioPlayer soundsFR;
FFT fftFR;
float bandHeightFR;

int x, y;
String []  message=
  {"On me dit de te haïr et je m'y efforce----------", 
  "Je t'imagine cruel, violent, implacable----", 
  "Mais à te voir je n'ai bientôt plus de force------", 
  "Et de te blesser je suis bien incapable----------------", 

  "Tous mes camarades combattent avec rage-------------", 
  "Et pleurent la nuit au souvenir des supplices--", 
  "Infligés à leurs frères qui sont du même âge----", 
  "et rêvent comme eux de toucher une peau lisse--------------", 

  "Et de pouvoir enfin caresser des obus-------------", 
  "Autres que ceux produits par le pouvoir obtus-", 
  "Je rêve de quitter ces boyaux infernaux-----------------", 

  "De laisser ces furieux des deux bords du Rhin---------", 
  "Et de pouvoir embrasser ta chute de rein-------", 
  "Et porter notre amour sur les fonts baptismaux"
};

color textColor=0;
RFont f;

float fontSize=60;
int splitGlyph = 120;
RPoint[][] pointsP;
float r = random(5, 20);
WordAttractor attractorW;
// We create 3 new lists parallel to pointsP
// List of attractors, one per glyph
WordAttractor [][] listWordAttractors;
// List of all the distances between all the attractors and the pointsP
float [][] listDistMap;
// List of vectors to replace the pointsP coordinates
PVector [][] listPV;
int tChildCount;

characterSpec []characters = new characterSpec[message.length];
RShape [] gShape = new RShape[message.length]; 



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(1920, 1920);
  RG.init(this);
  f = new RFont("SFNSText.ttf", int( fontSize), LEFT);

println(message.length);
  minim=new Minim(this);
  soundsFR=minim.loadFile("FR_01.wav", 512);
  soundsFR.play();
  fftFR= new FFT(soundsFR.bufferSize(), soundsFR.sampleRate());
  for (int i=0; i<message.length; i++) {
    characters[i]= new characterSpec( gShape[i], message[i]);
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void draw() {

  background(0);
  smooth();
  soundFFTAnalyse();
  translate(400, 100);

  for (int i=0; i<message.length; i++) {
    // println("i"+":"+i);
    //translate(50, 50);
    if (i%4==0) {
      translate(0, -10);
    }
    if (i<=3) {
      translate(i*20, 0);
    } else if (i>3 && i<=6) {
      translate(-280, 0);
      translate(i*45, 0);
    } else if (i==7) {
      translate(-150, 0);
    } else if (i>=8 && i<=10 ) {
      translate(-200, 0);
      translate(i*25, 0);
    } else if (i>10 && i <=13) {  
      translate(-35, 0);
      translate(i*-1, 0);
    }
    if (i<=8 && i%4==0) {
      translate(0, 40);
    } else if (i>8 && i%3==0) {
      translate(50, 0);
    }
    if (i==11) {
      translate(50, 40);
    }
    if (i==12 ) {
      translate(-40, 0);
    }
    translate(0, i+1*50);
    characters[i].update();
    characters[i].display();
  }
}

void soundFFTAnalyse() {
  AudioPlayer fr = soundsFR;
  fftFR.forward(fr.mix);
  for (int i=0; i<fftFR.specSize(); i++) {
    float bandDBFR = 10*log(fftFR.getBand(i)/fftFR.timeSize());
    bandHeightFR = map(bandDBFR*4, 0, -220, 0, height);
    constrain(bandHeightFR, 0, 1000);
    noStroke();
    fill(255, 0, 0);
    //ellipse(fr.position()/10, bandHeightFR/20, 5, 5);
  }
}

class characterSpec {
  String m;
  RShape bShape;
  RShape letterShapes;

  characterSpec(RShape _bShape, String _m) {

    //letterShapes =_letterShapes;
    bShape=_bShape;
    m=_m;
    pointsP= new RPoint [m.length()][splitGlyph];

    listWordAttractors= new WordAttractor [m.length()][splitGlyph];
    listDistMap = new float [m.length()][splitGlyph];
    for (int i=0; i<m.length(); i++) {
      for (int j=0; j<splitGlyph; j++) {
        listDistMap[i][j]=100000;
      }
    }
    listPV = new PVector[m.length()][splitGlyph];

    bShape= new RShape();
    bShape= f.toShape(m);
    RShape[]letterShapes = bShape.children;
    letterShapes = bShape.children;
    tChildCount = bShape.children.length;
  }

  void update() {

    for (int k=0; k<tChildCount; k++) {
     // println("tChildCount"+":"+tChildCount);
      float posX = map(soundsFR.position(), 200, soundsFR.length(), 200, width-200);
      float posY = bandHeightFR/10-350;
      //println(k);
      float d= dist(posX, 0, bShape.children[k].getCenter().x, 0);
      float sx=map(d, 0, 100, 1, 1.5);

      if (d<100) {
        bShape.children[k].scale(sx, bShape.children[k].getCenter());
      }
      for (int j=0; j<splitGlyph; j++) {      

        float frac =(1.0/splitGlyph);
        pointsP[k][j]=bShape.children[k].getPoint(j*frac);
        float dist1 = dist(posX-200, posY+100, pointsP[k][j].x, pointsP[k][j].y);
        if (dist1 < listDistMap[k][j]) {

          //  On remplace toutes les distances possibles entre la souris et les points par la distance minimale
          listDistMap[k][j]=dist1;
          listPV[k][j]=new PVector(posX-200, posY+100);
          listWordAttractors[k][j]=new WordAttractor(listPV[k][j].x, listPV[k][j].y, pointsP[k][j]);
        }
        listWordAttractors[k][j].points = pointsP[k][j];
        listWordAttractors[k][j].attract(); 
        pushMatrix();
        if (m==" ") {
          pointsP[k][j].x+=20*k;
        }
        pointsP[k][j].x-=120;
        pointsP[k][j].x+=10*k;
        popMatrix();
      }
    }
  }

  void display() {
    for (int k=0; k< tChildCount; k++) {
      for (int j=0; j<splitGlyph; j++) {
        pushMatrix();
        translate(pointsP[k][j].x, pointsP[k][j].y);
        beginShape();
        stroke(255);
        noFill();
        strokeWeight(0.5);
        float angle = TWO_PI/18;
        rotate(angle*j/4+noise(pointsP[k][j].x)/20);
        bezier(-3*(noise(5)), 3, -6*(noise(2)), 3, -4*noise(10), -3, 3, -3);
        endShape();
        popMatrix();
      }
    }
  }
}

class WordAttractor {

  float force_radious = 200;
  float maxForce = 15;
  RPoint position;
  RPoint points;
  float pX;
  float pY;

  WordAttractor(float x, float y, RPoint p) {
    points =p;
    position = new RPoint(x, y);
  }

  void attract() {

    float d= points.dist(position);
    if (d < force_radious) {   
      RPoint desired = new RPoint(points);
      desired.sub(position);
      desired.normalize();
      desired.scale(map(d, 0, force_radious, maxForce, 0));
      points.add(desired);
    }
  }
}

I don’t have time atm…

sry…

Dear @Chrisir,
Thanks for your answer. No problem, whenever you will have time…
I guess I need to make a list of the different message[] length in order to pass the values into the update(),
I will give it a try!
cu soon

Atm I had problems to start the sketch - it had an error with map() saying „-Infinity… invalid…“

I have the problem once the animation is over but it compiles…