Issue with sound reacting typography using Geomerative

edited April 10 in Library Questions

Hello, I don't mange to deform the typography with the class Attractor (code below). I'd be glad if someone can help me with this issue ! Thanks a lot in advance. Best,L

import geomerative.*;
RGroup myGroup;
RFont font;
RShape shape;
Write words;
RPoint[] myPoints;
float force_radious = 80;
float maxForce = 5;
ArrayList<Attractor>attractors = new ArrayList<Attractor>();
String [] myText = {"Leben ohne musik ist", "einfach ein fehler,"};
final color textColor = color(0, 200);

//----------------SETUP---------------------------------
void setup() {
  size(1920, 1080, JAVA2D);
  smooth();

  RG.init(this); 

  font = new RFont("FreeSans.ttf", 180, CENTER);
  for (int i=0; i< myText.length; i++) {
    words = new Write(myText[i]);
    RGroup myGroup = font.toGroup(myText[i]);
    myGroup = myGroup.toPolygonGroup();
    myPoints = myGroup.getPoints();
  }
  for (int j=0; j< myPoints.length; j++) {
    RPoint rp = myPoints[j];
    Attractor a= new Attractor(rp.x, rp.y);
    attractors.add(a);
  }
}
//----------------DRAW---------------------------------

void draw() {
  background(255);
  translate(width/2, height/1.2);
  for (int j=0; j< myText.length; j++) {
    words = new Write(myText[j]);
  }
  for (Attractor a : attractors) {
    a.attract();
  }
}
//////////////////////////////////////////////

class Attractor {
  PVector pos;

  Attractor(float x, float y) {
    pos = new PVector(x, y);
  }

  void attract() {
    PVector mouse = new PVector (mouseX-width/2, mouseY-height/1.2);
    float d= PVector.dist(pos, mouse);
    if (d < force_radious) {
      PVector desired = PVector.sub(pos, mouse);
      desired.normalize();
      desired.mult(map(d, 0, force_radious, maxForce, 0));
      pos.add(desired);
    }
  }
}

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

import ddf.minim.*;

class Write {

  String words;

  Write(String _words) {
    words= _words;

    for (int i=0; i<myText.length; i++) {
      RGroup myGroup = font.toGroup(myText[i]);
      RPoint[] myPoints = myGroup.getPoints();

      for (int j=0; j<myPoints.length; j++) {
        float x = myPoints[j].x;
        float y = myPoints [j].y;
        pushMatrix(); 
        translate(myPoints[j].x, myPoints[j].y-350+i*200);
        beginShape();
        noFill();
        stroke(textColor);
        strokeWeight(0.05);
        float angle = TWO_PI;
        angle= angle*10;
        rotate(j/angle);
        //bezier(-10*(noise(20)), 30, -10*(noise(10)), 20, -20*noise(20), -20, 10, -10);
        bezier(-10*(noise(20))+mouseX/15, 30+mouseY/10, -10*(noise(10))+mouseX/15, 20+mouseY/15, -20*noise(20)+mouseX/15, -20+mouseY/5, 10+mouseX/15, -10+mouseY/15);
        endShape();
        popMatrix();
      }
    }
  }
}
Tagged:

Answers

  • Somewhere around line 82 the attractors should interact with the points

    Or you display the attractors as points

  • Hi Chrisir, thank you very much for answering. I've just made an attempt, but still lost in translation!?

    import geomerative.*;
    RGroup myGroup;
    RFont font;
    RShape shape;
    Write words;
    RPoint[] myPoints;
    
    ArrayList<Attractor>attractors = new ArrayList<Attractor>();
    String [] myText = {"Leben ohne musik ist", "einfach ein fehler,"};
    final color textColor = color(0, 200);
    
    //----------------SETUP---------------------------------
    void setup() {
      size(1920, 1080, JAVA2D);
      smooth();
    
      RG.init(this); 
    
      font = new RFont("FreeSans.ttf", 180, CENTER);
      for (int i=0; i< myText.length; i++) {
        words = new Write(myText[i]);
        RGroup myGroup = font.toGroup(myText[i]);
        myGroup = myGroup.toPolygonGroup();
        myPoints = myGroup.getPoints();
      }
    
        Attractor a= new Attractor(mouseX-width/2, mouseY-height/1.2);
        attractors.add(a);
    
    
    }
    //----------------DRAW---------------------------------
    
    void draw() {
      background(255);
      translate(width/2, height/1.2);
    
      for (int j=0; j< myText.length; j++) {
        words = new Write(myText[j]);
      }
      for (int j=0; j< myPoints.length; j++) {
        RPoint rp = myPoints[j];
        for (Attractor a : attractors) {
          a.attract(rp.x, rp.y);
        }
      }
    }
    //////////////////////////////////////////////
    
    
    class Attractor {
      PVector pos;
      float x=0, y=0;
      float force_radious = 80;
      float maxForce = 5;
    
      Attractor(float theX, float theY) {
        x= theX;
        y = theY;
      }
    
      void attract(float x1, float y1) {
        for (int j=0; j<myPoints.length; j++) {
          x1 = myPoints[j].x;
          y1= myPoints [j].y;
        }
        pos = new PVector(x1, y1);
        PVector mouse = new PVector (x, y);
        float d= PVector.dist(mouse, pos);
        if (d < force_radious) {
          PVector desired = PVector.sub(mouse, pos);
          desired.normalize();
          desired.mult(map(d, 0, force_radious, maxForce, 0));
          pos.add(desired);
        }
      }
    }
    
    //////////////////////////////////////////////
    
    import ddf.minim.*;
    
    class Write {
    
      String words;
    
      Write(String _words) {
        words= _words;
    
        for (int i=0; i<myText.length; i++) {
          RGroup myGroup = font.toGroup(myText[i]);
          RPoint[] myPoints = myGroup.getPoints();
    
          for (int j=0; j<myPoints.length; j++) {
            //float x = myPoints[j].x;
            //float y = myPoints [j].y;
            pushMatrix(); 
            translate(myPoints[j].x, myPoints[j].y-350+i*200);
    
            beginShape();
            noFill();
            stroke(textColor);
            strokeWeight(0.05);
            float angle = TWO_PI;
            angle= angle*10;
            rotate(j/angle);
            //bezier(-10*(noise(20)), 30, -10*(noise(10)), 20, -20*noise(20), -20, 10, -10);
            bezier(-10*(noise(20))+mouseX/15, 30+mouseY/10, -10*(noise(10))+mouseX/15, 20+mouseY/15, -20*noise(20)+mouseX/15, -20+mouseY/5, 10+mouseX/15, -10+mouseY/15);
            endShape();
            popMatrix();
          }
        }
      }
    }
    
  • I think that the bracket } must be much later, around line 75

    Usage of x1,y1 is misleading

  • thank you very much dear Chrisir I'll have a look a bit later on today and will keep you posted with my attempts ;))

  • @lolonulu Is this post related to https://forum.processing.org/two/discussion/27705/how-to-attract-repulse-points-of-a-text-with-the-geomerative-library#latest? If it is, please ask koogs to close the second one. Reason: duplicate post.

    Kf

  • Dear kfrajer, yes sorry I shouldn't have duplicate the post but modify it...I'll know for the next time. I ask to Koogs. Sorry for the inconvenients and thanks for warning me.

  • Dear Chrisir, Thank you very much for your help. I renamed my variables and move the bracket later (line 75) as you suggested, but still the attract function is uneffective!?

        import geomerative.*;
        RGroup myGroup;
        RFont font;
        RShape shape;
        Write words;
        RPoint[] myPoints;
    
        ArrayList<Attractor>attractors = new ArrayList<Attractor>();
        String [] myText = {"Leben ohne musik ist", "einfach ein fehler,"};
        final color textColor = color(0, 200);
    
        //----------------SETUP---------------------------------
        void setup() {
          size(1920, 1080, JAVA2D);
          smooth();
    
          RG.init(this); 
    
          font = new RFont("FreeSans.ttf", 180, CENTER);
          for (int i=0; i< myText.length; i++) {
            words = new Write(myText[i]);
            RGroup myGroup = font.toGroup(myText[i]);
            myGroup = myGroup.toPolygonGroup();
            myPoints = myGroup.getPoints();
          }
            Attractor a= new Attractor(mouseX-width/2, mouseY-height/1.2);
            attractors.add(a);
        }
        //----------------DRAW---------------------------------
    
        void draw() {
          background(255);
          translate(width/2, height/1.2);
    
          for (int j=0; j< myText.length; j++) {
            words = new Write(myText[j]);
          }
          for (int j=0; j< myPoints.length; j++) {
            translate(myPoints[j].x, myPoints[j].y);
            RPoint rp = myPoints[j];
            for (Attractor a : attractors) {
              a.attract(rp.x, rp.y);
            }
          }
        }
    
        //////////////////////////////////////////////
    
        class Attractor {
          PVector pos;
          float x=0, y=0;
          float force_radious = 120;
          float maxForce = 5;
    
          Attractor(float theX, float theY) {
            x= theX;
            y = theY;
          }
    
          void attract(float pointX, float pointY) {
            for (int j=0; j<myPoints.length; j++) {
              pointX = myPoints[j].x;
              pointY= myPoints [j].y;
    
              pos = new PVector(pointX, pointY);
              PVector mouse = new PVector (x, y);
              float d= PVector.dist(mouse, pos);
              if (d < force_radious) {
                PVector desired = PVector.sub(mouse, pos);
                desired.normalize();
                desired.mult(map(d, 0, force_radious, maxForce, 0));
                pos.add(desired);
              }
            }
          }
        }
    
        //////////////////////////////////////////////
    
        import ddf.minim.*;
    
        class Write {
    
          String words;
    
          Write(String _words) {
            words= _words;
    
            for (int i=0; i<myText.length; i++) {
              RGroup myGroup = font.toGroup(myText[i]);
              RPoint[] myPoints = myGroup.getPoints();
    
              for (int j=0; j<myPoints.length; j++) {
                //float x = myPoints[j].x;
                //float y = myPoints [j].y;
                pushMatrix(); 
                translate(myPoints[j].x, myPoints[j].y-350+i*200);
                beginShape();
                noFill();
                stroke(textColor);
                strokeWeight(0.05);
                float angle = TWO_PI;
                angle= angle*10;
                rotate(j/angle);
                //bezier(-10*(noise(20)), 30, -10*(noise(10)), 20, -20*noise(20), -20, 10, -10);
                bezier(-10*(noise(20))+mouseX/15, 30+mouseY/10, -10*(noise(10))+mouseX/15, 20+mouseY/15, -20*noise(20)+mouseX/15, -20+mouseY/5, 10+mouseX/15, -10+mouseY/15);
                endShape();
                popMatrix();
              }
            }
          }
        }
    
  • edited April 10

    Did you write this code?

    I don’t understand it at all.

    For example you have only one attractor, line 27, and here mouse won’t work!

    Then compare line 38 and 61 ???

    Basically a duplicate

    Then you define pos (line 72) but never display it

    Or write it back into myPoints

    I am sorry I am not at home and can’t really do something for you

  • Dear Chrisir, Yes unfortunately I wrote this mess...! Here is below a version that works (the attraction), but unfortunately I lose the deformation of the text due to the rotation (rotate (i/angle)).How can I write a clean code without losing this effect?! Thank you very much for your help, I appreciate.

    import geomerative.*;
    RGroup myGroup;
    RGroup myGroup1;
    RFont font;
    RShape shape;
    
    RPoint[] myTextPoints;
    float force_radious = 80;
    float max_force = 5;
    ArrayList<Vehicle> vehicles = new ArrayList<Vehicle>();
    
    String[]myText = {"Heimat", "Patrie"};
    

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

    void setup() {
      size(1920, 1080);
      colorMode(HSB, 360, 100, 100, 100);
    
      RG.init(this);  
    
      font = new RFont("GUNPLAY.TTF", 450, CENTER);
    
      for (int i=0; i< myText.length; i++) {
    
        RGroup myGroup = font.toGroup(myText[i]);
        myGroup = myGroup.toPolygonGroup();
        myTextPoints = myGroup.getPoints();
    
        for (int j = 0; j < myTextPoints.length; j++) {
    
          RPoint rp = myTextPoints[j];
          Vehicle v = new Vehicle(rp.x, rp.y+i*400);
          vehicles.add(v);
        }
      }
    }
    
    ////////////////////////////////////////////////////////////////////////
    
    void draw() {
      background(36, 100, 86);
    
      translate(width/2, height*2/4);
      for (Vehicle v : vehicles) {
        v.update();
        v.write();
      }
    }
    

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

    class Vehicle {
      PVector pos;
      float r = 1;
      float maxSpeed = 10;
      float maxForce = 1;
    
      Vehicle(float x, float y) {
        pos = new PVector(x, y);
      }
     void write() {
        float r =1;  
        noFill();
        stroke(236, 51, 37);
        strokeWeight(r);
        beginShape();
        pushMatrix();
        translate(pos.x, pos.y);
       float angle= TWO_PI*10;
       rotate(10/angle);
        bezier(-20*(noise(20))+mouseX/25, 20, -40*(noise(10)), 30, -20*noise(20), -30, 20, -30);
        // bezier(-10*(noise(10))/2+mouseX/35, -5/noise(20)-mouseY/50, 20*(noise(10))+mouseX/65, -60-mouseY/100, 10*noise(20), 30, -20, -10+mouseY/25*noise(mouseX/50));
        popMatrix();
        endShape();
      }
      void update() {
        PVector mouse= new PVector(mouseX-width/2, mouseY-height *2/4);
        float d = PVector.dist(pos, mouse);
        if (d < force_radious) {
          PVector desired =PVector.sub(pos, mouse);
          desired.normalize();
          desired.mult(map(d, 0, force_radious, max_force, 0));
          pos.add(desired);
        }
      }
    }
    
  • WELL you wrote it but did you copy it from somewhere else?

    In the first version with attractors I would start by adding let‘s say 10 attractors to the list in a dor loop in setup using random (width), random(height) instead of mouse...

    Then you need to check that the attractors really influence the points you display. So write the result pos back to myPoints.

    By bringing in a new version (vehicles) you ignored what I previously wrote and didn’t try to implement it.

    Delete line 19. the rotation

  • Thank you so much Chrisir I will try to do so. In fact the vehicle version is the previous version of the same code! I wanted to implement it a with some classes. The attractor idea comes from the Generative design library that proposes attractors and nodes classes... But I thought to write a version with PVectors. I am still a newbie and often copy some portions of code, but I try to improve!

  • To copy things and plug them together is good and fully ok

    But you need to read and understand it. Well not fully but so that it works.

    As for the attractors you are on the right track but display the values of pos after line 72

    ellipse (pos.x,pos.y,6,6);

    Get rid of the duplicate for loop over myPoints and check if the values from myPoints are changed, get into pos and then are displayed.

    I am not at home and can’t run it.

  • Dear Chrisir, I did what you sugested: get rid of the duplicate loop over myPoints, erased the rotate, made a bunch of attractors, and added ellipse to display pos. But I'm still stuck at the same point how to get myPoints changed values into pos and display them ?! Sorry I don't get it.

    import geomerative.*;
    RGroup myGroup;
    RFont font;
    RShape shape;
    Write words;
    RPoint[] myPoints;
    int attractorsNb = 50;
    ArrayList<Attractor>attractors = new ArrayList<Attractor>();
    String [] myText = {"Leben ohne musik ist", "einfach ein fehler,"};
    final color textColor = color(0, 200);
    
    //----------------SETUP---------------------------------
    void setup() {
      size(1920, 1080, JAVA2D);
      smooth();
    
      RG.init(this); 
    
      font = new RFont("FreeSans.ttf", 180, CENTER);
      for (int i=0; i< myText.length; i++) {
        words = new Write(myText[i]);
        RGroup myGroup = font.toGroup(myText[i]);
        myGroup = myGroup.toPolygonGroup();
        myPoints = myGroup.getPoints();
      }
      for (int i =0; i< attractorsNb; i++) {
        Attractor a = new Attractor(random(width), random(height));
        attractors.add(a);
      }
    }
    
    //----------------DRAW---------------------------------
    
    void draw() {
      background(255);
      translate(width/2, height/1.2);
    
      for (int j=0; j< myText.length; j++) {
        words = new Write(myText[j]);
      }
      for (int j=0; j< myPoints.length; j++) {    
        for (Attractor a : attractors) {
          RPoint rp = myPoints[j];
          a.attract(rp.x, rp.y);
          a.display();
          //println(rp.x);
        }
      }
    }
    
    //////////////////////////////////////////////
    
    class Attractor {
      PVector pos;
      float x=0, y=0;
      float force_radious = 120;
      float maxForce = 5;
    
      Attractor(float theX, float theY) {
        x= theX;
        y= theY;
      }
    
      void attract(float pointX, float pointY) {
       pos = new PVector(pointX, pointY);
        PVector mouse = new PVector (x, y);
        float d= PVector.dist(mouse, pos);
        if (d < force_radious) {
          PVector desired = PVector.sub(mouse, pos);
          desired.normalize();
          desired.mult(map(d, 0, force_radious, maxForce, 0));
          pos.add(desired);
        }
      }
      void display () {
        noStroke();
         fill(0);
          ellipse (pos.x, pos.y, 10, 10);
      }
    }
    
    class Write {
    
      String words;
    
      Write(String _words) {
        words= _words;
    
        for (int i=0; i<myText.length; i++) {
          RGroup myGroup = font.toGroup(myText[i]);
          RPoint[] myPoints = myGroup.getPoints();
    
          for (int j=0; j<myPoints.length; j++) {
            pushMatrix(); 
            translate( myPoints[j].x, myPoints[j].y-350+i*200);
            beginShape();
            noFill();
            stroke(textColor);
            strokeWeight(0.05);
            //float angle = TWO_PI*10;
            //rotate(j/angle);
            bezier(-10*(noise(20)), 30, -10*(noise(10)), 20, -20*noise(20), -20, 10, -10);
            //bezier(-10*(noise(20))+mouseX/15, 30+mouseY/10, -10*(noise(10))+mouseX/15, 20+mouseY/15, -20*noise(20)+mouseX/15, -20+mouseY/5, 10+mouseX/15, -10+mouseY/15);
            endShape();
            popMatrix();
          }
        }
      }
    }
    
  • Comment out line 39

    Try comment out line 71

  • Thanks Chrisir, commenting line 39 it looks like the pos of the ellipse change, but not the text written with bezier lines! I tride to comment line 71, but no apparent result...

  • But now you can find out which line is doing what and fix it.

    you write the letter AND pos.

    Only pos is changed by attractors.

    You can make void attrac into PVector and return either pos or when the if clause doesn’t apply (else part) return the original values

    Then go in draw and use the received PVector and copy it into myPoints

  • ok I will do so, here is the 1rst step :

    PVector attract(float pointX, float poitY){
    pos= new PVector(pointX, pintY);
    PVector mouse = new PVector (x,y);
    float d= PVector.dist(mouse, pos);
    if(d < force_radious){
    PVector desired = PVector.sub(mouse, pos);
    desired.normalize();
    desired.mult(map(d, 0, force_radious, maxForce, 0));
    pos.add(desired);
    }
    return pos;
    }
    

    is it wright ? But how to use the return pos, I don't know. Sorry for my ignorance. I had a look on the documentation and in the forum but I could find a way...

  • edited April 11 Answer ✓

    At last, I am at home and took a look.

    Boy... so many errors.... it would take me ages to explain all this. First thing was to kill class Write; utter nonsense.

    I had to replace your font "FreeSans.ttf" in the code - but I put it back in now for you.

    you can hit any key to reset the image.

    as you can see, each attractor is working twice (since you have 2 lines of text) and there is an offset to it (the letters are moving to a place other than the attractor but proportional to its position)

    Best, Chrisir ;-)

    import geomerative.*;
    
    //RGroup myGroup;
    RFont font;
    //RShape shape;
    //Write words;
    RPoint[][] myPoints=new RPoint[2][2];
    
    boolean firstTime=true; 
    
    int attractorsNb = 12;
    ArrayList<Attractor>attractors = new ArrayList<Attractor>();
    
    String [] myText = {
      "Leben ohne musik ist", 
      "einfach ein fehler"
    };
    
    final color textColor = color(0, 200);
    
    //----------------SETUP---------------------------------
    
    void setup() {
      size(1920, 1080, JAVA2D);
    
      smooth();
      RG.init(this); 
      font = new RFont("FreeSans.ttf", 180, CENTER); // changed this !!!!!!!!!     "FreeSans.ttf"    !!!!!!!!!!!!!!!
      stroke(textColor);
      strokeWeight(0.05);
    
      initAll();
    }
    
    //----------------DRAW---------------------------------
    
    void draw() {
      background(255);
      translate(width/2, height/1.2);
    
      for (int j=0; j< myPoints.length; j++) {    
        for (int j2=0; j2 < myPoints[j].length; j2++) {
    
          for (Attractor a : attractors) {
            RPoint rp = myPoints[j][j2];
            PVector temp=a.attract(rp.x, rp.y);
            myPoints[j][j2].x=temp.x;
            myPoints[j][j2].y=temp.y;
            a.display();
            // println(rp.x);
          }
    
          pushMatrix(); 
          translate( myPoints[j][j2].x, myPoints[j][j2].y-350+j*200);
          //beginShape();
          noFill();
          //float angle = TWO_PI;
          //rotate(j/angle);
          bezier(-10*(noise(20)), 30, -10*(noise(10)), 20, -20*noise(20), -20, 10, -10);
          //bezier(-10*(noise(20))+mouseX/15, 30+mouseY/10, -10*(noise(10))+mouseX/15, 20+mouseY/15, -20*noise(20)+mouseX/15, -20+mouseY/5, 10+mouseX/15, -10+mouseY/15);
          //endShape();
          popMatrix();
        }
      }
    }
    
    // -------------------------------------------------------------------
    
    void keyPressed() {
    
      initAll();
    }
    
    // -------------------------------------------------------------------
    
    void initAll() {
    
      attractors.clear();
    
      for (int i=0; i < myText.length; i++) {
        RGroup myGroup = font.toGroup(myText[i]);
        myGroup = myGroup.toPolygonGroup();
        myPoints[i] = myGroup.getPoints();
      }
    
      for (int i = 0; i< attractorsNb; i++) {
        Attractor a = new Attractor(random(width)-width/2, random(height)-height/2);
        attractors.add(a);
      }
    }
    
    //////////////////////////////////////////////
    
    class Attractor {
    
      PVector posLetterVector;
      float x, y;
      PVector posAttractorVector;
    
      float force_radious = 120;
      float maxForce = 5;
    
      Attractor(float theX, float theY) {
        x = theX;
        y = theY;
        posAttractorVector = new PVector (x, y);
      } // constr 
    
      PVector attract(float pointX, float pointY) {
    
        // calculate the impact of this attractor on given points float pointX, float pointY and return the result as PVector
    
        posLetterVector = new PVector(pointX, pointY);
        float d = PVector.dist(posAttractorVector, posLetterVector);
        if (d < force_radious) {
          // calc and return change 
          PVector desired = PVector.sub(posAttractorVector, posLetterVector);
          desired.normalize();
          desired.mult(map(d, 0, force_radious, maxForce, 0));
          posLetterVector.add(desired);
          return posLetterVector;
        } else {
          // otherwise just return the given parameters 
          return new PVector(pointX, pointY);
        }
      }
    
      void display () {
        // show the attractor itself 
        fill(255, 0, 0);
        ellipse (posAttractorVector.x, posAttractorVector.y, 10, 10);
      }
    }
    //
    
  • Dear Chrisir, Many many thanks to you. Yes I've made so many errors... At least this time I haven't copied and tried by myself! But I have so much to learn! I now understand many things... Thanks to you. I was on the track for the attractors but so far with my stupid 'write class'. Thank you very much for taking some precious time to help me. I'll credit you if I manage to finish my project ;)) Best wishes, L

Sign In or Register to comment.