Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

  • sketch does not run; P2D Error ([...] Please call TIS/TSM in main thread) - Looking for workaround

    Hi there, I've already saw questions about this topic and I'm aware there is still not a real solution for this error. I couldn't find a workaround to allow my sketch to run. Wondering if form the community here I can get some help.

    FYI what I'll want to achive is a creation of a "wordcloud" where the input is a microphone so that people can interact with it saying the word that will be part of the cloud. Still a work in progress. For now the input is a text file.

    Here the code:

    import java.util.Iterator;
    import java.applet.*; 
    import java.awt.*; 
    import java.awt.image.*; 
    import java.awt.event.*; 
    import java.io.*; 
    import java.net.*; 
    import java.text.*; 
    import java.util.*; 
    import java.util.zip.*; 
    import java.util.regex.*; 
    
    PFont font;
    String fontFile = "ArialRoundedMTBold-96.vlw";
    int fSize = 96;
    int maxSize = 192;
    int minSize = 48; 
    String wordFile = "processing.txt";
    
    String[] words;
    int[]  count;
    int most;
    int least;
    float currentSize;
    int currentIndex;
    
    void setup(){
      size(900, 500, P2D);
      colorMode(HSB, TWO_PI, 1, 1, 1);
      rectMode(CORNER);
      background(color(0, 0, 1));
      smooth();
      font = loadFont(fontFile);
      initializeWords();  
      noLoop();
    
    }
    
    void draw() {
      while(currentIndex < words.length) {
        float relsize = map(count[currentIndex],least,most,minSize,maxSize);
        boolean drawn = false;  
        while (!drawn) {
          drawn = drawWord(words[currentIndex], relsize);
          if (!drawn)
           println("redrawing "+words[currentIndex]);
            relsize = relsize * 0.95;
        }
        currentIndex++;
      }  
    }
    
    boolean drawWord(String word, float wordSize) {
      int intSize = (int)wordSize;
      textFont(font, wordSize);
      int w = int(textWidth(word));
      PGraphics g = createGraphics(w, intSize, P2D);
      g.beginDraw();
      g.background(color(0, 0, 1, 0));
      g.fill(color(0,0,0));
      g.textAlign(CENTER, CENTER);
      g.translate(w/2, wordSize/2);
      g.scale(wordSize / fSize);
      g.textFont(font);
      g.text(word, 0, 0);
      g.endDraw();
    
      PGraphics gMask = createGraphics(w, intSize, P2D);
      gMask.beginDraw();
      //gMask.background(color(0, 0, 1, 1));
      gMask.image(g, 0, 0);
      gMask.filter(ERODE);  
      gMask.filter(ERODE);
      gMask.endDraw();
    
      for (int tries=50; tries>0; tries--) {
        int x = (int)random(width-w);
        int y = (int)random(height-intSize);
    
        boolean fits = true;
        for (int dx = 0; dx< w && fits; dx++) {
          for (int dy = 0; dy<intSize && fits; dy++) {
            if (brightness(gMask.get(dx, dy))<0.5) {
              if (brightness(get(x+dx, y+dy))<0.5) {
                fits = false;
              }
            }
          }
        }
        if (fits) {
          image(g, x, y);
          return true;
        }
      }
      return false;
    }
    
    boolean equalColor(color c1, color c2) {
      String h1 = hex(color(c1));
      String h2 = hex(color(c2));
      return h1.equals(h2);
    }
    
    
    void initializeWords() {
      ArrayList ignore = new ArrayList();
      String[] ignoreStrs  = loadStrings("ignore.txt");
      for (int i = 0; i < ignoreStrs.length; i++) {
        ignore.add(ignoreStrs[i].trim().toUpperCase());
      }
      HashMap wordcount = new HashMap();
      String[] lines = loadStrings(wordFile);
      for (int i = 0; i < lines.length; i++) {
        String[] words = split(lines[i], " ");  
        for (int j = 0; j < words.length; j++)  {
          String word = clean(words[j]).toUpperCase();
          if (word.length() == 0) {
            continue;
          }
          if (ignore.contains(word)) {
            continue;
          }
          Integer count = (Integer)wordcount.get(word); 
          if (count == null) {
             wordcount.put(word, new Integer(1));
           }
           else {
             int newCount = count.intValue() + 1;
             wordcount.put(word, new Integer(newCount));
           }
        }
      }
      words = new String[wordcount.size()];
      count = new int[wordcount.size()];
      int idx = 0;
      Iterator it = wordcount.entrySet().iterator();  // Get an iterator
      while (it.hasNext()) {
          Map.Entry me = (Map.Entry)it.next();
          words[idx] = (String)me.getKey();
          count[idx] = ((Integer)(me.getValue())).intValue();
          idx++;
      }
      sortWords();
      String[] sorted = new String[words.length];
      for (int i = 0; i < words.length; i++) {
        sorted[i] = count[i]+" "+words[i];
      }
      most = count[0];
      least = count[count.length-1];
      //saveStrings("totals.txt", sorted);
    
    }
    
    String clean(String word) {
      word = word.trim();
      if (word.endsWith(".") || word.endsWith(",") || word.endsWith(";"))
        word = word.substring(0, word.length() - 1);
      return word.trim();    
    }
    
    
    void sortWords() {
      boolean changed = true;
      while (changed) {
        boolean madeChange = false;
        for (int i = 0; i < count.length-1; i++) {
          if (count[i] < count[i+1]) {
            int temp = count[i];
            String tempW = words[i];
            count[i] = count[i+1];
            words[i] = words[i+1];
            count[i+1] = temp;
            words[i+1] = tempW;
            madeChange = true;
          }
        }
        changed = madeChange;
      }
    }
    

    Info: Processing 3.3.7 macOS High Sierra 10.13.6 Early 2015 Intel Iris Graphics 6100 1536 MB

    Thanks

  • G4P library crashes with multi-window

    hello #Quark

    I have noticed several time instability problems when using the G4P library to generate multiwindows. I'm using G4P builder tool in Processing 3.7. I stripped the code to the bare minimum to narrow down what could generate the error. The code (see below) loads a .obj file, set a .JPG picture as background to main window and rotate the .obj in the main window. It also create an empty window using G4P with P3D randerer.

    If the createGUI() line is commented the code runs for hours with no problem. If I uncomment the createGUI() line, the code crash with the error reported below. The behaviour is different depending upon the platform used:

    • Windows 10 / core i5 / NVIdia GEForce 920MX ==> code fails after few minutes
    • Windows 10 / core i5 / Intel 710 ==> code fails after few 10 of second
    • old MAC with OsX mounain lion + NVIDIA ==> code is really slow but never fails.

    Same behavior if I export the code as .exe. I'm running on both PC Java8.

    I really need to get this stable (not many time left to the end of my project...)... Are you aware about that kind of trouble on Windows10 ? any hint to get it stable ?

    Appreciate very much your help,

    ///////////////////// code////////////////////////////////////////////////////////////

    import g4p_controls.*;
    
    PShape Arr,Tip, Gr, Rd, Pt;
    PShape s;
    float Rx, Ry=80, Rz ,mix=0.0001;
    PImage bg;
    
    public void setup(){
      bg = loadImage("Back.JPG");
      bg.resize(500,650);
      size(500, 650, P3D);
      background(bg);
      s = loadShape("wingXstrmUs.obj");
      createGUI();                                                            //<<====== this is the problematic line
    }
    
    public void draw() {
      background(bg);
      // generate random angles
      Rx=(1-mix)*Rx+mix*radians(random(180));
      Ry=(1-mix)*Ry+mix*radians(random(180));
      Rz=(1-mix)*Rx+mix*radians(random(180));
    
      // draw the object rotation in the main window
      translate(width/2, height/2);
      rotateX (Rx);
      rotateY(Ry);
      rotateZ(Rz);
      scale(4, 4, 4);
      shape(s, 0, 0);
    }
    ////// Below code generated by G4P builder in the GUI tab to generate the empty window
    
    synchronized public void win_draw1(PApplet appc, GWinData data) { //_CODE_:window1:517716:
    appc.background(230);
    } //_CODE_:window1:517716:
    
    // Create all the GUI controls. 
    // autogenerated do not edit
    
    public void createGUI(){
      G4P.messagesEnabled(false);
      G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
      G4P.setCursor(ARROW);
      surface.setTitle("Sketch Window");
      window1 = GWindow.getWindow(this, "Window title", 0, 0, 500, 650, P3D);
      window1.noLoop();
      window1.addDrawHandler(this, "win_draw1");
      window1.loop();
    }
    
    // Variable declarations 
    // autogenerated do not edit
    GWindow window1;
    

    ////////////////////////////// Error generated by Processing

    JRE version: Java(TM) SE Runtime Environment (8.0_162-b12) (build 1.8.0_162-b12)

    Java VM: Java HotSpot(TM) 64-Bit Server VM (25.162-b12 mixed mode windows-amd64 compressed oops)

    Problematic frame:

    C [msvcrt.dll+0x7436f]

    #

    Failed to write core dump. Minidumps are not enabled by default on client versions of Windows

    Could not run the sketch (Target VM failed to initialize). For more information, read revisions.txt and Help ? Troubleshooting

  • Video Delay : Ed Tannenbaum, Recollections

    First -- there is a new forum, I suggest re-posting this there:

    https://discourse.processing.org/

    Second -- I would suggest a very different approach. Instead of accumulating a big stack of DelayImg (in your example, 50), just have a single image. Each frame, draw a silhouette on it in grayscale, and let the results accumulate.

    The minimum gray value, maximum gray value, and increment (how much the gray value steps up each frame) or time scale (how often it should loop) will be configurable.

    When you walk across the screen, your single source image in memory will look something like this:

    Screen Shot 2018-08-31 at 4.28.02 PM

    Now the way to create color effects is through a mapping algorithm that pseudo-colors the grayscale values and produces your visual output. The cycling, chasing, blackouts gaps etc. can all be done on top of that simple grayscale buffer as mapping operations. Each frame, copy the buffer, then march through the pixels array and replace each pixel value according to your color map. If you are cycling, at the end rotate the map array values by one position (e.g. move lowest to highest, or highest to lowest).

    That should give you incredible performance compared to the approach above.

    You should either reserve true black as transparent in a grayscale / RGB buffer or make your buffer type RGBA and initialize it as transparent.

  • How to progressively draw a fractal tree

    Hi everyone, I need to do a school project and I want to build a fractal tree that progressively "grows" using the mouse. how can I do it? this is the code I built:

    void setup() 
    {
    
            fullScreen();
    
     }
    
    int levelsMin = 0;
        int levelsMax = 6;
        float initialLength = 235;
    
        float angleMin = PI/17;
        float angleMax = PI/10;
    
        int pointColor = color(27, 25, 9);
    
       void draw() {
    
    
            background(color(245,247,232));
            stroke(88, 50, 0);
            strokeWeight(7);
    
            float currentAngle = map (mouseX, 0, width, angleMin, angleMax); //mouse control of the branch angle
            int currentLevels = (int)map (mouseY, height,0, levelsMin, levelsMax); //mouse control of the generations count
    
            pushMatrix(); //save the world transformation matrix
            translate (width/2, height); //move the origin to the middle / bottom
           albero (currentLevels, initialLength, currentAngle); //draw first two branches - stems
            popMatrix(); //return to the world coordinate system
        }
    
        void albero (int levels, float length, float angle){
            if (levels>0){  //check if there are any levels left to render
                //destra
                pushMatrix();           //save current transformation matrix
                rotate (angle);         //rotate new matrix to make it point to the right
                line (0,0,0,-length);   //draw line "upwards"
                pushMatrix();           //save current (e.g. new) matrix
                translate(0,-length);   //move the origin to the branch end
                scale (0.85f);          //scale down. fun fact - it scales down also the stroke weight!
               albero (levels-1, length, angle);  //call the recursive function again
                popMatrix();            //return to the matrix of the current line
                popMatrix();            //return to the original matrix
                //second branch - the same story
                pushMatrix();
                rotate (-angle/1.7);
                line (0,0,0,-length);
                pushMatrix();
                translate(0,-length);
                scale (0.85f);
                albero (levels-1, length, angle);
                popMatrix();
                popMatrix();
    
    
            }
    
        }
    
  • How to add a trigger to an oscilloscope program?

    Doing something like this requires to know about the nature of your data, and exactly how you envision your trigger to work. Here I have implemented the concept based on leading edge crossing. White line is based line. Blue line is the current threshold definition. The data from minim is in a range of -1..+1. When displaying, I multiply this data by a normalization factor which I defined as height/2. I set my threshold to 0.4 based on observations from the printInfo() function in my code below. Green line shows the data points.

    The concept is this. If the wave crosses the threshold, capture this crossing point. Set this crossing point as the center of the display (across the sketch width) which means all the data is shifted either to the left or to the right. Because the display width is 512 and the data buffer is 512, if the data is shifted with respect to the leading edge crossing, then it is natural that either the left end or right end will have no data... these data bins were set to zero (Notice this is because I copy the original data to a temporal array before I reset those containers to zero).

    I removed the hsb color definition, added an inversion on the y axis, and instead of calling background(), I am using a fill with alpha to slowly erased my sketch content. So this creates an effect of memory on the display where you can see that previous waves are attenuated and removed after few iterations, and not immediately in the case you call background() function.

    As in an oscilloscope, I work with the time-amplitude domain. However, the examples of the minim is based on a buffer that provides amplitude only, no time information. Then What I do is that I take the index of the array and I set them to be my time. The amplitude from minim is used as my amplitude data, so I get two internal arrays: time and amplitude which store the data to display.

    Kf

    //REFERENCE: https://forum.processing.org/two/discussion/28074/how-to-add-a-trigger-to-an-oscilloscope-program#latest // //Title: Oscilloscope trigger based on the leading edge. //Author: Kfrajer, July 15, 2018

    import ddf.minim.*;
    
    Minim minim;
    AudioInput in;
    color white;
    
    WavePacket wp;
    
    void setup()
    {
      size(512, 200, P2D);
      white = color(255);
    
      minim = new Minim(this);
      minim.debugOn();
    
      in = minim.getLineIn(Minim.STEREO, 512);
    
      wp=new WavePacket(in.bufferSize());
    
      background(0);
    }
    
    void draw()
    {
      //clone wafeform
      wp.loadData(in);
      wp.printInfo();
      wp.searchHThresholdCrossing();
      wp.shiftWaveBasedOnHThreshold();
    
      //This next enables drawing only of those signals above the threshold
      //Remove or comment out if you want to see all the signals
      if (!wp.thresholdFound()) {
        return;
      }
    
      fill(0, 60);
      rect(0, 0, width, height);
      translate(0, height/2);
      scale(1, -1);
      wp.drawBaseLine();
      wp.display();
      wp.drawThresold(); 
    }
    
    
    void stop()
    {
      in.close();
      minim.stop();
      super.stop();
    }
    
    class WavePacket {
    
      final float NORMFACTOR=height/2;
    
      int len;
      FloatList time;
      FloatList amp;
    
      float highThreshold;
      float idxTimeFirstCrossing;
    
      WavePacket(int n) {
        len=n;
        time=new FloatList(len);
        amp=new FloatList(len);
    
        highThreshold=0.4;  //Chosen based on initial observations from printInfo()
    
        println("Size set to ", len);
      }
    
      void loadData(AudioInput in) {    
    
        for (int i = 0; i < in.bufferSize(); i++) {
          time.set(i, i);
          amp.set(i, in.left.get(i));
        }
      }
    
      //It finds index when the curve crosses the threshold for the first time
      void searchHThresholdCrossing() {
    
        idxTimeFirstCrossing = -1;  //Resets
    
        for (int i = 0; i < in.bufferSize(); i++) {
          if (amp.get(i)>=highThreshold) {
            idxTimeFirstCrossing=i;
            return;
          }
        }
      }
    
      boolean thresholdFound() {
        return idxTimeFirstCrossing>=0;
      }
    
      void shiftWaveBasedOnHThreshold() {
    
        int middlePoint=(len/2);
        //If wave did not cross threshold, then define delta time correction as zero
        int deltaTime = thresholdFound() ? int(middlePoint-idxTimeFirstCrossing) : 0;
    
        FloatList tempX=new FloatList();
        FloatList tempY=new FloatList();
    
        //Create temporal containers with shifted tinme data 
        for (int i = 0; i < in.bufferSize(); i++) {
          tempX.set(i, time.get(i)+deltaTime);
          tempY.set(i, amp.get(i));
        }
    
    
        //Zero original containers
        for (int i = 0; i < in.bufferSize() - 1; i++) {
          time.set(i, 0);
          amp.set(i, 0);
        }
    
        //Search for first index
        int idx=0;
        for (; idx < in.bufferSize(); idx++) {
    
          if (tempX.get(idx)<0)
            continue;
    
          break;
        }
    
        //println("Threshold:", highThreshold, "idxTimeFirstCrossing", idxTimeFirstCrossing, "idx:", idx);
    
        //Populate arrays with shifted data using temporal holders
        for (int j=idx; j<len; j++) {
    
          //println(idx);
          //println(int(tempX.get(j)), tempY.get(j));
    
          time.set(int(tempX.get(j)), tempX.get(j));
          amp.set(int(tempX.get(j)), tempY.get(j));
        }
      }
    
      void display() {
        // draw the waveforms
        stroke(0, 250, 10);  //Green
        strokeWeight(2);
        for (int i = 0; i < in.bufferSize(); i++) {
    
          point(i, amp.get(i)*NORMFACTOR);
        }
      }
    
      void drawThresold() {
        stroke(0, 0, 200);  //Blue
        strokeWeight(1);
    
        int step=2;
        for (int k=0; k<len-step*2; k+=step*2)
          line(k, highThreshold*NORMFACTOR, k+step, highThreshold*NORMFACTOR);
      }
    
      void drawBaseLine() {
        stroke(250);  //White
        strokeWeight(1);
        line(0, 0, width, 0);
      }
    
    
      void printInfo() {
        println("Report range: ", amp.min(), amp.max());
        println("Report Norm Factor", NORMFACTOR);
      }
    }
    
  • How can a roguelike have so large maps?

    @TheJeff This might help https://forum.processing.org/two/discussion/20853/scale-translate-ab-comparission#latest

    Please let's continue in the new forum. Don't forget to cross your future post with this one.

    Kf

  • How can a roguelike have so large maps?

    look at scale in the reference

    ;-)

    there is also a new forum now

  • How to switch from one text (using Geomerative) to an other according to a changing duration timer?!

    Hello, I asked a very close question brillantly answered by @jeremydouglas few time ago, now I'd like to have a different duration for each text. In the sketch below the changePhraseTimer() works, but not the changePhraseTimerN(), we don't see the last text and it doesn't loop properly. Could someone help me with this issue please ?! Thanks a lot in advance. L

    import generativedesign.*;
    import geomerative.*;
    // List of a list of points. 1rst the numbre of phrases: 4,  the 2nd indicate the number of points
    RPoint[][] myPoints = new RPoint[5][0];
    RFont font;
    PFont f;
    Attractor attractor;
    
    String [][] phraseSets = new String [4][0];
    String [] FR1 = {
      "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", 
    };
    String [] FR2 = {
      "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"
    };
    String [] FR3 =
      {"Et de pouvoir enfin caresser des obus", 
      "Autres que ceux produits par le pouvoir obtus", 
      "Je rêve de quitter ces boyaux infernaux"
    };
    String [] FR4 = {
      "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"
    };
    
    //TEXT
    final color textColor = color(245);
    int fontSize;
    
    // TIME
    int startTime;
    int initTime;
    int lineSpacing;
    int index;
    int state;
    float duration;
    int dur1;
    
    //----------------SETUP---------------------------------------------------------------------------------------
    
    void setup() {
      size(1920, 1080, JAVA2D);
      //add phrases to list
      phraseSets[0]=FR1;
      phraseSets[1]=FR2;
      phraseSets[2]=FR3;
      phraseSets[3]=FR4;
    
      smooth();
      RG.init(this);
      font = new RFont("FreeSans.ttf", 86, CENTER);
      stroke(textColor);
      strokeWeight(0.05);
      //INIT
      drawPhrases(phraseSets[0]);
    
       // TIME
      startTime=millis();
      initTime=millis();
      index=0;
      lineSpacing =150;
    }
    
    //----------------DRAW----------------------------------------------------------------------------------
    
    void draw() {
      background(255);
      state =0;
    
    
      // TEXTS
      // draw on the center of the screen
      translate(width/2, height/2);
      // draw phrases vertically centered by moving the top up by half the line spaces
      translate(0, -1.0*lineSpacing*(phraseSets[index].length-1)/2.0);
      // loop through lines
      for (int i=0; i< myPoints.length; i++) {
        // draw a line
        for (int j=0; j< myPoints[i].length-1; j++) {
          pushMatrix(); 
          translate(myPoints[i][j].x, myPoints[i][j].y);
          noFill();
          stroke(0, 200);
          strokeWeight(0.25);
          float angle = TWO_PI*10;
          rotate(j/angle);
          bezier(-2*(noise(10)), 10, 25*(noise(10)), -5, 2*noise(5), -15, 10, -3);
          //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);
          popMatrix();
        }
        // move to the next line
        translate(0, lineSpacing);
      }
      //check Timer and redraw phrases if time has passed
    
      changePhraseTimerN();
      //changePhraseTimer(duration*4, phraseSets);
    
    }
    
    //----------------INITIALIZE----------------------------------------------------------------------------------------------------------------------------------------
    void drawPhrases(String [] phrases) {
      myPoints = new RPoint[phrases.length][0];
      for (int j=0; j<phrases.length; j++) {
        RGroup myGroup = font.toGroup(phrases[j]);
        myGroup = myGroup.toPolygonGroup();
        myPoints[j] = myGroup.getPoints();
      }
    }
    
    //----------------TIMER----------------------------------------------------------------------------------------------------------------------------------------
    
    /*void changePhraseTimer( float duration, String [][] phraseSets) {
     duration = sounds[0].length()-150;
     if (millis()-startTime > duration*4) {
     index =(index+1) % phraseSets.length; 
     //drawPhrases(phraseSets[index]);
     //startTime = millis();
     }
     }*/
    
    void changePhraseTimerN() {
      dur1=11500;
    
      if (millis()-startTime > dur1+1400) {
        index =(index+1) % phraseSets[1].length; 
        drawPhrases(phraseSets[index]);
        startTime= millis();
      } else if (millis()-startTime > dur1-800) {
        index =(index+1) % phraseSets[2].length; 
        drawPhrases(phraseSets[index]);
        startTime= millis();
      } else if (millis()-startTime > dur1+1000) {
        index =(index+1) % phraseSets[3].length; 
        drawPhrases(phraseSets[index]);
        startTime= millis();
      } else if (millis()-startTime > dur1*2-8000) {
        drawPhrases(phraseSets[0]);
        startTime= millis();
      }
    }
    
    
    //----------------TEXT ATTRACTOR INIT----------------------------------------------------------------------------------------------------------------------------------------
    void initAttractor(int i) {
      if (i>=4 && i<8) {
        i-=4;
      } else if (i>=8 && i<11) {
        i-=8;
      } else if (i>=11 && i<14) { 
        i-=11;
      } else if (i>14) {
        i=0;
      }
    
      float x = 0;
      float y =-50; 
      // println(i); 
      attractor = new Attractor(x, y, myPoints[i]);
    }
    
    
    class Attractor {
    
      float force_radious = 100;
      float maxForce = 15;
      RPoint position;
      RPoint[] points;
    
      Attractor(float x, float y, RPoint[] p) {
        points = p;
        position = new RPoint(x, y);
      }
    
      void attract() {
    
        for (int i =0; i < points.length; i++) {
    
          float d= points[i].dist(position);
         // println ("d : "+d);
          if (d < force_radious) {   
            RPoint desired = new RPoint(points[i]);
            //points[i]= new RPoint(points[i]);
            //println( "avant x : "+ points[i].x +" y: "+points[i].y);
            desired.sub(position);
            desired.normalize();
            desired.scale(map(d, 0, force_radious, maxForce, 0));
            points[i].add(desired);
             //println( "après x : "+ points[i].x +" y: "+points[i].y);
          }
        }
      }
      void display () {
        stroke(0);
       strokeWeight(2);
      // ellipse (position.x, position.y-750, 30, 30);
      }
      void moveTo(float x, float y){
        position.x=x;
        position.y=y;
    
      }
    }
    
  • Processing (image display) via Arduino ultrasonic sensor

    Hi, I am just starting to explore posibilities to make something work in processing via arduino (sensors). On school exhibition I want to make a picture display that shows one image at the time on the wall (with a projector), depending how close or far person is located from distance sensor. This is a sketch of what I am thinking about:example To see if it really works, I explored some tutorials that explains how to connect Arduino input with Processing. Currently, I have these codes in both programs: for Arduino:

    const int anPin1 = 0;
    long distance1;
    
    void setup() {
      Serial.begin(9600);  // sets the serial port to 9600
    }
    
    void read_sensors(){
      /*
      Scale factor is (Vcc/512) per inch. A 5V supply yields ~9.8mV/in
      Arduino analog pin goes from 0 to 1024, so the value has to be divided by 2 to get the actual inches
      */
      distance1 = analogRead(anPin1)/2;
    }
    
    void print_all(){
      /*
      Serial.print("S1");
      Serial.print("inches");
      */
      Serial.print(" ");
      Serial.print(distance1);
      Serial.println();
    }
    
    void loop() {
      read_sensors();
      print_all();
      delay(50); 
    }
    

    And for Processing:

    import processing.serial.*;  
    Serial myPort;  
    String data="" ;
    PFont  myFont;  
    int distance;
    
    void setup(){
      size(1366,900); // size of processing window
      //background(0);// setting background color to black
    
      myPort = new Serial(this, "/dev/cu.usbmodemfd111", 9600);
      myPort.bufferUntil('\n');
    }
    
    void draw(){
    
      background(0);
      textAlign(CENTER);
      fill(255);
      text(data,820,400);
      textSize(100);
      fill(#4B5DCE);
      text("              Distance :        cm",450,400);
      noFill();
      stroke(#4B5DCE);
    
    }
    
    void serialEvent(Serial myPort){
    
      data=myPort.readStringUntil('\n');
    
    }
    

    And this distance reading works perfect!

    Unfortunately didn’t found any specific example for what i am looking for. So the question is, how can I get, for example, 3 pictures working this way:

    if(distance>60){
    image(photo1, 0, 0); //display first photograpgy
    }
    else if (40<distance<60) {
    image(photo2, 0, 0);
    }
    else if (distance<40) {
    image(photo3, 0, 0);
    }
    

    Do I have to write something like that in draw ()? And how can I get income distance value as number from which depends displayed image? And should I upload any specific library for this? Do i have to write something also again in Arduino code?

    Would be great if someone could suggest any examples or codes for this.

    Hoping for advise, komats!!

  • How to switch from one text to another according to time with the Geomerative library?!

    Dear Chrisir, In fact my problem is linked to the attarctor in my main sketch. I switch from a phrase to the other and the attractor for the lines works too but no the attractor linked to the words !? Don't find why... I tried to debug, but don't succeed. Here is the code: Thanks for your help... best, L

    import generativedesign.*;
    import geomerative.*;
    import ddf.minim.analysis.*;
    import ddf.minim.*;
    // List of a list of points. 1rst the numbre of phrases: 4,  the 2nd indicate the number of points
    RPoint[][] myPoints = new RPoint[5][0];
    RFont font;
    PFont f;
    Attractor attractor;
    
    // Variables for lines
    Attractor_Lines attractor_Lines;
    int xCount=401;
    int yCount=401;
    float gridSizeX=1800;
    float gridSizeY=1000;
    Node [] myNodes;
    float xPos, yPos;
    
    String [][] phraseSets = new String [4][0];
    String [] FR1 = {
      "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", 
    };
    String [] FR2 = {
      "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"
    };
    String [] FR3 =
      {"Et de pouvoir enfin caresser des obus", 
      "Autres que ceux produits par le pouvoir obtus", 
      "Je rêve de quitter ces boyaux infernaux"
    };
    String [] FR4 = {
      "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"
    };
    
    //TEXT
    final color textColor = color(245);
    int fontSize;
    
    //SOUND
    Minim minim;
    AudioPlayer[] sounds;
    FFT fft;
    float bandHeight;
    float soundDuration ;
    float soundDuration1 ;
    String []fileNamesFR= {"FR_01", "FR_02", "FR_03", "FR_04", "FR_05", "FR_06", "FR_07", "FR_08", "FR_09", "FR_10", "FR_11", "FR_12", "FR_13", "FR_14"};
    SoundManager sm;
    
    // TIME
    int startTime;
    int initTime;
    int lineSpacing;
    int index;
    int state;
    float duration;
    float dur1;
    float dur2;
    //----------------SETUP---------------------------------------------------------------------------------------
    
    void setup() {
      size(1920, 1080, JAVA2D);
      //add phrases to list
      phraseSets[0]=FR1;
      phraseSets[1]=FR2;
      phraseSets[2]=FR3;
      phraseSets[3]=FR4;
    
      smooth();
      RG.init(this);
      font = new RFont("FreeSans.ttf", 86, CENTER);
      stroke(textColor);
      strokeWeight(0.05);
      //INIT
      drawPhrases(phraseSets[0]);
    
      // LINES initiate attractor + attractors specs
      myNodes = new Node [xCount*yCount];
      initGrid();
      attractor_Lines = new Attractor_Lines(0, 0);
      attractor_Lines.strength=-160;
      attractor_Lines.ramp = 0.85;
    
      //SOUND
      minim = new Minim(this);
      sounds = new AudioPlayer[fileNamesFR.length];
      for (int idx=0; idx<sounds.length; idx++) {
        sounds[idx] = minim.loadFile(fileNamesFR[idx]+".wav", 2048);
        fft = new FFT(sounds[idx].bufferSize(), sounds[idx].sampleRate());
      }
      soundDuration = 2000;
      sm=new SoundManager(this);
      //}
      // TIME
      startTime=millis();
      initTime=millis();
      index=0;
      lineSpacing =150;
    }
    
    //----------------DRAW---------------------------------------------------------------------------------------------
    
    void draw() {
      background(255);
      state =0;
    
      //SOUNDS ANALYZIS
      for (int idx=0; idx < sounds.length; idx++) {
        fft.forward(sounds[idx].mix);
        for (int i =0; i< fft.specSize(); i++) {
          float bandDB = 10*log(fft.getBand(i)/fft.timeSize());
          bandDB = constrain(bandDB, -1000, 1000);
          bandHeight = map(bandDB*4, 0, -220, 0, height);
          stroke(0);
          //line(i, height, i, bandHeight-fft.getBand(i)*8);
        }
      }
    
    
      // LINES
      if (millis()-startTime > 0) {
        for (int i = 0; i<myNodes.length; i=i+10) {
          pushMatrix();
          translate(myNodes[i].x, myNodes[i].y);
          stroke(0, 100);
          strokeWeight(0.01);
          float noiseXRange = attractor_Lines.x/100.0;
          float noiseYRange = attractor_Lines.y/1000.0;
          float noiseX = map(myNodes[i].x, 0, xCount, 0, noiseXRange/5);
          float noiseY = map(myNodes[i].y, 0, yCount, 0, noiseYRange/5);
          float noiseValue = noise(noiseX, noiseY);
          float angle = noiseValue*TWO_PI;
          rotate(angle);
          line(0, 0, 10, 10);
          popMatrix();
        }
      }
    
      // TEXTS
      // draw on the center of the screen
      translate(width/2, height/2);
      // draw phrases vertically centered by moving the top up by half the line spaces
      translate(0, -1.0*lineSpacing*(phraseSets[index].length-1)/2.0);
      // loop through lines
      for (int i=0; i< myPoints.length; i++) {
        // draw a line
        for (int j=0; j< myPoints[i].length-1; j++) {
          pushMatrix(); 
          translate(myPoints[i][j].x, myPoints[i][j].y);
          noFill();
          stroke(0, 200);
          strokeWeight(0.25);
          float angle = TWO_PI*10;
          rotate(j/angle);
          bezier(-2*(noise(10)), 10, 25*(noise(10)), -5, 2*noise(5), -15, 10, -3);
          //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);
          popMatrix();
        }
        // move to the next line
        translate(0, lineSpacing);
      }
      //check Timer and redraw phrases if time has passed
    
      changePhraseTimerN(dur1, phraseSets);
      sm.update();
      // changePhraseTimer(duration*4, phraseSets);
    }
    
    //----------------INITIALIZE----------------------------------------------------------------------------------------------------------------------------------------
    void drawPhrases(String [] phrases) {
      myPoints = new RPoint[phrases.length][0];
      for (int j=0; j<phrases.length; j++) {
        RGroup myGroup = font.toGroup(phrases[j]);
        myGroup = myGroup.toPolygonGroup();
        myPoints[j] = myGroup.getPoints();
      }
    }
    
    //----------------TIMER----------------------------------------------------------------------------------------------------------------------------------------
    
    /*void changePhraseTimer( float duration, String [][] phraseSets) {
      duration = sounds[0].length()-150;
      if (millis()-startTime > duration*4) {
        index =(index+1) % phraseSets.length; 
        drawPhrases(phraseSets[index]);
        //startTime = millis();
      }
    }*/
    
    void changePhraseTimerN(float dur1, String [][] phraseSets) {
      dur1 = 11200.;
      dur2=7000;
      if (millis()-startTime < dur1) {
        state=0;
      } else if (millis()-startTime < dur1*2-200.) {
        state=1;
      } else if (millis()-startTime < dur1*3-4500.) {
        state=2;
      } else if (millis()-startTime < dur1*4-9500.) {
        state=3;
      } else {
        state=0;
        startTime = millis();
      }
    
      switch(state) {
    
      case 0:
        drawPhrases(phraseSets[0]);
        //println(0);
        index=0;
        break;
      case 1:
        //drawPhrases(phraseSets[1]); 
        index = (index+1) % phraseSets.length;
        println(index);
        startTime = millis();
        drawPhrases(phraseSets[index]);
        // println(1);
        break;
      case 2:
        drawPhrases(phraseSets[2]);
        // println(2);
        break;
      case 3:
        drawPhrases(phraseSets[3]);
        // println(3);
        break;
      }
    }
    
    
    //----------------TEXT ATTRACTOR INIT----------------------------------------------------------------------------------------------------------------------------------------
    void initAttractor(int i) {
      if (i>=4 && i<8) {
        i-=4;
      } else if (i>=8 && i<11) {
        i-=8;
      } else if (i>=11 && i<14) { 
        i-=11;
      } else if (i>14) {
        i=0;
      }
    
      float x = 0;
      float y =-50; 
      // println(i);
      attractor = new Attractor(x, y, myPoints[i]);
    }
    //----------------LINES ATTRACTOR INIT----------------------------------------------------------------------------------------------------------------------------------------
    void updateAttractorLines(float x, float y) {
      attractor_Lines.x=x;
      attractor_Lines.y=y;
    }
    //----------------LINES GRID INIT----------------------------------------------------------------------------------------------------------------------------------------
    void initGrid() {
      int i =0;
      for (int x=0; x<xCount; x++) {
        for (int y=0; y<yCount; y++) {
    
          xPos = x*(gridSizeX /(xCount-1)) + (width-gridSizeX)/2;
          yPos = y*(gridSizeY /(yCount-1)) + (height-gridSizeY)/2;
          myNodes[i] = new Node(xPos, yPos);
          myNodes[i]. setBoundary(0, 0, width, height);
          myNodes[i].setDamping(0.9);
          i++;
        }
      }
    }
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    class Attractor {
    
      float force_radious = 100;
      float maxForce = 15;
      RPoint position;
      RPoint[] points;
    
      Attractor(float x, float y, RPoint[] p) {
        points = p;
        position = new RPoint(x, y);
      }
    
      void attract() {
    
        for (int i =0; i < points.length; i++) {
    
          float d= points[i].dist(position);
         // println ("d : "+d);
          if (d < force_radious) {   
            RPoint desired = new RPoint(points[i]);
            //points[i]= new RPoint(points[i]);
            //println( "avant x : "+ points[i].x +" y: "+points[i].y);
            desired.sub(position);
            desired.normalize();
            desired.scale(map(d, 0, force_radious, maxForce, 0));
            points[i].add(desired);
             //println( "après x : "+ points[i].x +" y: "+points[i].y);
          }
        }
      }
      void display () {
        stroke(0);
       strokeWeight(2);
      // ellipse (position.x, position.y-750, 30, 30);
      }
      void moveTo(float x, float y){
        position.x=x;
        position.y=y;
    
      }
    }
    
    class Attractor_Lines {
      float x=0, y=0;
      float radius =110;
      float strength= 0.55;
      float ramp=0.05;
      float theX;
      float theY;
    
      Attractor_Lines( float theX, float theY) {
        x= theX;
        y = theY;
      }
    
      void attract_Lines (Node theNode) {
    
        float dx = x-theNode.x;
        float dy = y-theNode.y;
        float d= mag(dx, dy);
        if ( d > 0 && d < radius) {
    
          float s = pow(d/radius, 1/ramp);
          float f = s*9*strength*50 * (1/(s+1)+((s-3)/4))/d;
          theNode.velocity.x += dx*f;
          theNode.velocity.y += dy*f;
        }
      }
    }
    
    ////////////////////////////////////////////////////////////////
    
    import ddf.minim.analysis.*;
    import ddf.minim.*;
    
    class SoundManager {
      //SOUND
      Minim minim;
      AudioPlayer[] sounds;
      FFT fft;
      float bandHeight;
      int currentSound;
      String []fileNamesFR1= {"FR_01", "FR_02", "FR_03", "FR_04", "FR_05", "FR_06", "FR_07", "FR_08", "FR_09", "FR_10", "FR_11", "FR_12", "FR_13", "FR_14"};
      float []linesYPositions ={300., 450., 600., 750., 300., 450., 600., 750., 450., 600., 750., 450., 600., 750.};
    
      SoundManager(PApplet app) {
    
        minim = new Minim(app);
        currentSound =-1;
        sounds = new AudioPlayer[fileNamesFR1.length];
        for (int idx=0; idx<sounds.length; idx++) {
          sounds[idx] = minim.loadFile(fileNamesFR1[idx]+".wav", 2048);
          fft = new FFT(sounds[idx].bufferSize(), sounds[idx].sampleRate());
    
        }
      }
    
      void update() {
    
        // SOUND
        if (currentSound ==-1) { 
          startPlaying();
    
        } else if (!sounds[currentSound].isPlaying()) {
          playNext();
        } else { 
    
          fft.forward(sounds[currentSound].mix);
          for (int i =0; i< fft.specSize(); i++) {
            float bandDB = 10*log(fft.getBand(i)/fft.timeSize());
            bandDB = constrain(bandDB, -1000, 1000);
            bandHeight = map(bandDB*4, 0, -220, 0, height);
          }
    
          attractor.moveTo(map(sounds[currentSound].position(), 0, sounds[currentSound].length(), 0, width-100)-width/2, bandHeight/10-300);
          attractor.attract();
    
          updateAttractorLines( attractor_Lines.x = map(sounds[currentSound].position(), 0, sounds[currentSound].length(), 0, width-(100)/2), linesYPositions[currentSound]);
    
          for (int j = 0; j<myNodes.length; j++) {
            attractor_Lines.attract_Lines(myNodes[j]);
            myNodes[j].update();
          }
        }
      }
    
    
      void startPlaying() {
        currentSound=0;
        playCurrentSound();
      }
    
      void playNext() {
    
        currentSound++;
        if (currentSound > sounds.length-1) {
          currentSound=0;
          drawPhrases(phraseSets[0]);
        } 
    
        // fonction restartAnimation
        //drawPhrases(phraseSets[0]);
       playCurrentSound();
    
      } 
    
      void playCurrentSound() {
        sounds[currentSound].rewind();
        sounds[currentSound].play();
        initAttractor(currentSound);
      }
    }
    
  • How to scale text and image to responsive canvas?

    Hi! I'm trying to do a big project, but I'm stuck in a part of it. The canvas I'm working on is responsive, but the text and image aren't. Here's a simple code that make what i'm needing.

    function setup(){ createCanvas(windowWidth,windowHeight); logo = loadImage("logo.png"); }

    function draw(){ background(0); imageMode(CENTER); image(logo, windowWidth / 2, windowHeight / 3, 100, 100); imageMode(CORNER); textSize(30); textAlign(CENTER, CENTER); rectMode(CENTER); text('This is a string of text! This is a string of text!',windowWidth / 2, windowHeight / 2 , windowWidth, windowHeight); }

    This is what it looks on a laptop screen: pic1

    And this is what look on a responsive screen: pic2

    I want to make the text and the image as big and legible than it is on responsive mode. I know that I have to change the lines

    textSize(30); and image(logo, windowWidth / 2, windowHeight / 3, 100, 100);

    but i don't know how. Any tips?

  • Converting Java code to Python

    Here's my Python Mode attempt. However, it's not working yet, it's just pitch black! :-&

    This statement crashes the sketch: geombuffer.update(pg_render) within resizeScreen(). Even when following exactly what it does, it doesn't seem to render anything. :o3

    https://GitHub.com/diwi/PixelFlow/blob/master/src/com/thomasdiewald/pixelflow/java/render/skylight/DwScreenSpaceGeometryBuffer.java#L67-L79

    public void update(PGraphics3D pg_src){
      
      resize(pg_src.width, pg_src.height);
      
      pg_geom.beginDraw();
      updateMatrices(pg_src);
      pg_geom.blendMode(PConstants.REPLACE);
      pg_geom.clear();
      pg_geom.shader(shader);
      pg_geom.noStroke();
      scene_display.display(pg_geom);
      pg_geom.endDraw();
    }
    

    So I'm at loss about it! Sorry. X_X Try finding help on diwi or jdf. ^#(^

    """
     * Depth of Field (DoF) (1.20)
     * Thomas Diewald (diwi) (2017-Oct-07)
     
     * GitHub.com/diwi/PixelFlow/blob/master/examples/Miscellaneous/
     * DepthOfField_Demo/DepthOfField_Demo.java
     
     * Refactor by GoToLoop (v1.4.2) (2018-May-18) (PDE v3.3.5)
     * Forum.Processing.org/two/discussion/27905/
     * converting-java-code-to-python#Item_20
    """
    
    add_library('PixelFlow')
    add_library('peasycam')
    
    from com.jogamp.opengl import GL2
    from processing.opengl import PGL
    
    from java.util import Formatter, Locale
    from jarray import zeros
    
    formatter = Formatter(Locale.ENGLISH)
    
    POSITION = 'position: (%8.2f, %8.2f, %8.2f)\n'
    ROTATION = 'rotation: (%8.2f, %8.2f, %8.2f)\n'
    LOOK__AT = 'look-at:  (%8.2f, %8.2f, %8.2f)\n'
    DISTANCE = 'distance: (%8.2f)\n'
    
    TITLE = __file__[:-5] + '   [fps %6.2f]'
    
    BB_SIZE = 800
    BB_OFFSET = BB_SIZE >> 2
    BB_TOTAL = BB_SIZE + BB_OFFSET
    BB_COORD, BB_DIAM = -BB_TOTAL, BB_TOTAL << 1
    
    XMIN, XMAX = -BB_SIZE, BB_SIZE
    YMIN, YMAX = -BB_SIZE, BB_SIZE
    ZMIN, ZMAX = 0, BB_SIZE
    
    BOX_DIAM = BB_OFFSET + BB_OFFSET/20
    SPH_MIN_D, SPH_MAX_D = BB_OFFSET >> 2, BB_OFFSET >> 1
    
    BOXES, SPHERES = 50, 50
    BOX_RANGE, SPH_RANGE = tuple(range(BOXES)), tuple(range(SPHERES))
    
    CROSS_S, ZFAR = 10, 6000
    MULT_BLUR, FPS = 30, 60
    BLUR_POW, RAD60 = pow(MULT_BLUR, 1/3.0), 60*DEG_TO_RAD
    
    BASE_COL, CROSS_COL = 0x80FFFFFF, 0xd0FFFFFF
    
    SEED, FIXED_SEED = 0, False
    FULLSCREEN, RESIZABLE = False, False
    apply_dof, alt_render = False, False
    
    resized = zeros(1, 'z')
    cube_smooth, cube_facets = DwCube(4), DwCube(2)
    shp_scene = pg_render = pg_dof = pg_tmp = None
    
    def settings():
        if FULLSCREEN: fullScreen(P3D) 
        else: size(this.displayWidth*9/10, this.displayHeight*9/10, P3D)
        noSmooth()
    
    
    def setup():
        frameRate(FPS); cursor(CROSS)
    
        global surf, canv
        surf, canv = this.surface, this.graphics
    
        if RESIZABLE: surf.resizable = True
        surf.setLocation(this.displayWidth - width >> 1, 8)
    
        global peasy
        peasy = PeasyCam(this, -4.083, -6.096, 7, 2000)
        peasy.setRotations(1.085, -.477, 2.91)
    
        global context, dw_filter, dof, param, geombuffer, magnifier
    
        context = DwPixelFlow(this)
        dw_filter = DwFilter.get(context)
        context.print(); context.printGL()
    
        dof = DepthOfField(context)
        param = dof.param
        param.mult_blur = MULT_BLUR
    
        class SceneDisplay(DwSceneDisplay):
            def display(_, canvas): displayScene(canvas)
    
    
        geombuffer = DwScreenSpaceGeometryBuffer(context, SceneDisplay())
    
        mag_h = height/3
        magnifier = DwMagnifier(this, 4, 0, height - mag_h, mag_h, mag_h)
    
    
    def draw():
        setTitle(); resizeScreen(); displaySceneWrap(pg_render)
        dw_filter.gamma.apply(pg_render, pg_render)
    
        apply_dof and applyDoF()
        renderScene()
    
    
    def keyPressed():
        global apply_dof, alt_render, shp_scene
        k = chr(keyCode) if key != CODED else keyCode
    
        if k == 'P' or k == BACKSPACE: noLoop() if this.looping else loop()
        elif k == 'C' or k == CONTROL: printCam()
        elif k == ' ': apply_dof ^= True
        elif k == SHIFT: alt_render ^= True
        elif k == ENTER or k == RETURN: shp_scene = None
    
    
    def applyDoF():
        geom = geombuffer.pg_geom
        dw_filter.gaussblur.apply(geom, geom, pg_tmp, BLUR_POW)
    
        param.focus_pos[0] = map(mouseX + .5, 0, width, 00, 1)
        param.focus_pos[1] = map(mouseY + .5, 0, height, 1, 0)
        dof.apply(pg_render, pg_dof, geombuffer)
    
        dw_filter.copy.apply(pg_dof, pg_render)
    
    
    def renderScene():
        pg = geombuffer.pg_geom if alt_render else pg_render
    
        magnifier.apply(pg, mouseX, mouseY)
        magnifier.displayTool()
    
        DwUtils.beginScreen2D(canv)
        # peasy.beginHUD()
    
        blendMode(REPLACE); image(pg, 0, 0)
        magnifier.display(pg, 0, height - magnifier.h)
    
        fpx = param.focus_pos[0] * width
        fpy = (1 - param.focus_pos[1]) * height
    
        blendMode(EXCLUSION); strokeCap(PROJECT); stroke(CROSS_COL)
        line(fpx - CROSS_S, fpy, fpx + CROSS_S, fpy)
        line(fpx, fpy - CROSS_S, fpx, fpy + CROSS_S)
        blendMode(BLEND)
    
        # peasy.endHUD()
        DwUtils.endScreen2D(canv)
    
    
    def resizeScreen():
        global pg_render, pg_dof, pg_tmp
        w = width; h = height
    
        perspective(RAD60, float(w)/h, 2, ZFAR)
        peasy.feed()
    
        happened = resized[0] = False
        pg_render = DwUtils.changeTextureSize(this, pg_render, w, h, 8, resized)
        happened |= resized[0]
    
        resized[0] = False
        pg_dof = DwUtils.changeTextureSize(this, pg_dof, w, h, 0, resized)
        happened |= resized[0]
    
        resized[0] = False
        pg_tmp = DwUtils.changeTextureSize(this, pg_tmp, w, h, 0, resized,
        GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT)
    
        # geombuffer.update(pg_render)
    
        happened |= geombuffer.resize(pg_render.width, pg_render.height)
        geombuffer.pg_geom.beginDraw()
    
        # geombuffer.updateMatrices(pg_render)
        DwUtils.copyMatrices(pg_render, geombuffer.pg_geom)
    
        geombuffer.pg_geom.blendMode(REPLACE)
        geombuffer.pg_geom.clear()
        geombuffer.pg_geom.shader(geombuffer.shader)
        geombuffer.pg_geom.noStroke()
        geombuffer.scene_display.display(geombuffer.pg_geom)
        geombuffer.pg_geom.endDraw()
    
        return happened | resized[0]
    
    
    def displaySceneWrap(canvas):
        DwUtils.copyMatrices(canv, canvas)
        canvas.beginDraw()
        canvas.background(2)
        displayScene(canvas)
        canvas.endDraw()
    
    
    def displayScene(canvas):
        canvas.directionalLight(255, 255, 255, 200, 600, 400)
        canvas.directionalLight(255, 255, 255, -200, -600, -400)
        canvas.ambientLight(64, 64, 64)
    
        if canvas is geombuffer.pg_geom:
            canvas.background(-1)
            canvas.pgl.clearColor(1, 1, 1, ZFAR)
            canvas.pgl.clear(PGL.COLOR_BUFFER_BIT)
    
        global shp_scene
        if not shp_scene: shp_scene = makeShape()
        canvas.shape(shp_scene)
    
    
    def makeShape():
        scene = createShape(GROUP)
        FIXED_SEED and randomSeed(SEED)
    
        with pushStyle():
            colorMode(HSB, 360, 1, 1); noStroke()
    
            for i in BOX_RANGE:
                px = random(XMIN, XMAX); py = random(YMIN, YMAX)
                sx = random(BOX_DIAM, BOX_DIAM); sy = random(BOX_DIAM, BOX_DIAM)
                sz = random(ZMIN, ZMAX)
    
                fill(random(-45, 45), 1, random(.1, 1))
                shp_box = createShape(BOX, sx, sy, sz)
                shp_box.translate(px, py, sz*.5)
                scene.addChild(shp_box)
    
            for i in SPH_RANGE:
                px = random(XMIN, XMAX); py = random(YMIN, YMAX)
                pz = random(ZMIN, ZMAX); rr = random(SPH_MIN_D, SPH_MAX_D)
    
                fill(random(205, 245), 1, random(.1, 1))
                shp_sphere = createShape(PShape.GEOMETRY)
                shp_sphere.scale(rr); shp_sphere.translate(px, py, pz)
                scene.addChild(shp_sphere)
    
                DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, True)\
                if i&1 else\
                DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, False)
    
            fill(BASE_COL)
            scene.addChild(createShape(RECT, BB_COORD, BB_COORD, BB_DIAM, BB_DIAM))
    
        return scene
    
    
    def clearFormatter(f): f.out().setLength(0)
    
    
    def setTitle():
        clearFormatter(formatter)
        surf.title = formatter.format(TITLE, frameRate).toString()
    
    
    def printCam():
        pos = peasy.position; rot = peasy.rotations
        lat = peasy.getLookAt(); dis = peasy.distance
    
        clearFormatter(formatter)
    
        print formatter.\
        format(POSITION, *pos).format(ROTATION, *rot).\
        format(LOOK__AT, *lat).format(DISTANCE, dis)
    
  • CSV file not found in android but no problem in processing 3

    Here's the code for my sketch that I added to the processing android demo. The problem starts with the ObserverElement. It seems to be trying to read another file using Reader.java

    I think I see why its not working with the demo. The difference is that the demo uses gradle and my sketch that worked was jammed into a project(the clearsky android example) imported from eclipse. Theres some kind of dependency issue maybe.

    package in.omerjerk.processingdemo.sketch;
    
    import java.util.Arrays;
    import java.util.List;
    
    import controlP5.ControlP5;
    import controlP5.DropdownList;
    import controlP5.ScrollableList;
    import controlP5.Textarea;
    import jparsec.ephem.Ephem;
    import jparsec.ephem.EphemerisElement;
    import jparsec.ephem.EphemerisElement.COORDINATES_TYPE;
    import jparsec.ephem.EphemerisElement.FRAME;
    import jparsec.ephem.Functions;
    import jparsec.ephem.Nutation;
    import jparsec.ephem.Target.TARGET;
    import jparsec.ephem.planets.EphemElement;
    import jparsec.ephem.stars.StarElement;
    import jparsec.ephem.stars.StarEphem;
    import jparsec.ephem.stars.StarEphemElement;
    import jparsec.io.ConsoleReport;
    import jparsec.math.Constant;
    import jparsec.observer.LocationElement;
    import jparsec.observer.ObserverElement;
    import jparsec.time.AstroDate;
    import jparsec.time.SiderealTime;
    import jparsec.time.TimeElement;
    import jparsec.time.TimeElement.SCALE;
    import jparsec.time.TimeScale;
    import processing.core.PApplet;
    import processing.core.PFont;
    
    //import jparsec.ephem.IAU2006;
    //import jparsec.ephem.IAU2006.CIO_EPHEMERIS;
    //import jparsec.ephem.planets.JPLEphemeris;
    //import jparsec.math.matrix.Matrix;
    //import jparsec.observer.EarthOrientationParameters;
    
    public class CSVTest2 extends PApplet {
    
    
    
    
    //import java.sql.*;
    //import de.bezier.data.sql.*;
    
    //import java.lang.*;
    
    //import java.time.*;
    
    //SQLite db;
    ControlP5 cp5;
    ControlP5 controlP5;
    Textarea myTextarea;
    
    int Latitude_1 = 39;
    int Lat_minutes = 20;
    int Lat_seconds = 10;
    int Longitude_1 = -77;
    int Lon_minutes = 00;
    int Lon_seconds = 26;
    float Lon = 0;
    float Lat = 0;
    
    //ScrollableList Name1;
        DropdownList Name1;
    ScrollableList Name2;
    String Star1 = " ";
    String Star2 = " ";
    
    String starName = " ";
    float ra = 0;
        String proper = " ";
    float RA = 0;
    float dec = 0;
    double pmra = 0;
    double pmdec = 0;
    double rv = 0;
        int i = 0 ;
    PFont f;
    int z = 18;
        int index = 3;
        int timer;
        int wait = 10000;
    
    
    
    
    public void setup()
    {
     //  size( 100, 100 );
    
    
     f = createFont("Arial",16,true); 
    //  db = new SQLite( this, "hygdata.db" );  // open database file
    
      cp5 = new ControlP5(this);
      controlP5 = new ControlP5(this);
                   List l = Arrays.asList("Procyon","Rasalhague","Dubhe", "Mirphak", "Alkaid","Altair", "Alioth", "Spica", "Betelgeuse", "Capella", "Vega","Polaris", "Menkalinan", "Pollux", "Regulus","Deneb", "Denebola");
      /* add a ScrollableList, by default it behaves like a DropdownList */
    //  Name1 = cp5.addScrollableList("StarName  1")
        Name1 = cp5.addDropdownList("StarName  1")
         .setPosition(20, 270)
         .setSize(300, 200)
         .setBarHeight(50)
         .setItemHeight(50)
         .addItems(l)
         // .setType(ScrollableList.LIST) // currently supported DROPDOWN and LIST
         ;
    
    
         controlP5.addSlider("Latitude_1",0,90,Latitude_1,20,10,255,30);
         controlP5.addSlider("Lat_minutes",0,60,Lat_minutes,20,50,255,30);
         controlP5.addSlider("Lat_seconds",0,60,Lat_seconds,20,90,255,30);
    
         controlP5.addSlider("Longitude_1",-180,180,Longitude_1,20,130,255,30);
         controlP5.addSlider("Lon_minutes",0,60,Lon_minutes,20,170,255,30);
         controlP5.addSlider("Lon_seconds",0,60,Lon_seconds,20,210,255,30);
    
    
           Name2 = cp5.addScrollableList("StarName  2")
         .setPosition(20, 590)
         .setSize(300, 200)
         .setBarHeight(50)
         .setItemHeight(50)
         .addItems(l)
        ; 
    
    
    
    
    
        myTextarea = cp5.addTextarea("txt")
                      .setPosition(420,10)
                      .setSize(950, 720)
                      .setFont(createFont("arial", 20))
                      .setLineHeight(20)
                      .setColor(color(255))
                      .setColorBackground(color(255, 0))
                      .setColorForeground(color(255, 100));
    
        timer = millis();//store the current time
    
    
    }
    
    public void draw() {
     background(0, 0, 0);
        String[] starLines = loadStrings("stardata.csv");
        println("Loaded " + starLines.length + " stars:");
    
        Lat = (float)Latitude_1 + (float)Lat_minutes/60 + (float)Lat_seconds/3600;  //Estimated Latitude
        Lon = (float)Longitude_1 - (float)Lon_minutes/60 - (float)Lon_seconds/3600; //Estimated Longitude
    
       if (Longitude_1 > 0) {
       Lon = (float)Longitude_1 + (float)Lon_minutes/60 + (float)Lon_seconds/3600; //East of Greenwich
       }
    
        for ( i = 0 ; i < starLines.length; i++) {
    
            String[] stars = splitTokens(starLines[i], ", ");
            String proper = (stars[0]);
            String con = (stars[1]);
            double dec = PApplet.parseFloat(stars[2]);
            double ra = PApplet.parseFloat(stars[3]);
            double pmra = PApplet.parseFloat(stars[4]);
            double pmdec = PApplet.parseFloat(stars[5]);
            double rv = PApplet.parseFloat(stars[6]);
    
            ra = ra * 15;
    
            Star1 = Name1.getCaptionLabel().getText();
            if (Star1 == "Procyon") {
                z = 47;
            }
            if (Star1 == "Rasalhague") {
                z = 93;
            }
            if (Star1 == "Dubhe") {
                z = 57;
            }
            if (Star1 == "Mirphak") {
                z = 18;
            }
            if (Star1 == "Alkaid") {
                z = 73;
            }
    
    
            for (int j = 1; j < i; j = i+1) {
    
                try {
    
    
                        if (i == z) {   //14 = Polaris 69 = Dubhe
                            //  AstroDate astro = new AstroDate(2008, 4, 24, 10, 36, 18);
                            AstroDate astro = new AstroDate();
                            //  System.out.println(astro);
                            TimeElement time = new TimeElement(astro, SCALE.UNIVERSAL_TIME_UTC);
                            ObserverElement obs = new ObserverElement("", Lon * Constant.DEG_TO_RAD, Lat * Constant.DEG_TO_RAD, 88, 0);
                            ObserverElement obs0 = obs.clone();
                            EphemerisElement eph = new EphemerisElement(TARGET.Moon, COORDINATES_TYPE.APPARENT, EphemerisElement.EQUINOX_OF_DATE, EphemerisElement.GEOCENTRIC, EphemerisElement.REDUCTION_METHOD.IAU_2009,
                                    FRAME.DYNAMICAL_EQUINOX_J2000, EphemerisElement.ALGORITHM.MOSHIER); //EphemerisElement.ALGORITHM.MOSHIER); //EphemerisElement.ALGORITHM.JPL_DE405); //.ALGORITHM.JPL_DE405);
    
                            eph.correctForPolarMotion = false;   //originally false
                            eph.correctEOPForDiurnalSubdiurnalTides = false;  //originally false
                            eph.correctForEOP = true;  //originally false
                            //    EarthOrientationParameters.clearEOP();
                            Nutation.clearPreviousCalculation();
    
    
                            //    System.out.println("Geodetic location: "+Functions.formatAngleAsDegrees(obs.getLongitudeRad(), 3) + " / "+Functions.formatAngleAsDegrees(obs.getLatitudeRad(), 3) + " / "+obs.getHeight());
                            double TTminusUT1 = TimeScale.getTTminusUT1(time, obs);
                            // Force TT-UT1 as in the example
                            TTminusUT1 = 65.571845f;
                            TimeScale.forceTTminusUT1(time, obs, TTminusUT1);
                            // Force EOP parameters as in the example
                            double UT1minusUTC = -0.387845f, x = -0.002f, y = 0.529f, dx = 0, dy = 0;
                            boolean dxdyAredPsidEpsilon = false;
                            double jd_UTC = TimeScale.getJD(time, obs, eph, SCALE.UNIVERSAL_TIME_UTC);
                            //     EarthOrientationParameters.forceEOP(jd_UTC, eph, UT1minusUTC, x, y, dx, dy, dxdyAredPsidEpsilon);
    
                            double jd_TT = TimeScale.getJD(time, obs, eph, SCALE.TERRESTRIAL_TIME);
                            double jd_UT1 = TimeScale.getJD(time, obs, eph, SCALE.UNIVERSAL_TIME_UT1);
    
                            StarElement star = new StarElement(proper, (double) ra * Constant.DEG_TO_RAD, (double) dec * Constant.DEG_TO_RAD,
                                    0, 0, (float) (pmra * Constant.ARCSEC_TO_RAD / Math.cos((double) dec * Constant.DEG_TO_RAD)),
                                    (float) (pmdec * Constant.ARCSEC_TO_RAD), (float) rv, Constant.J2000, FRAME.ICRF);
                            //  System.out.println("Angular Velocity:  " + pmra);
                            StarEphemElement ephem = StarEphem.starEphemeris(time, obs, eph, star, false);
    
                            eph.isTopocentric = true;
                            ephem = StarEphem.starEphemeris(time, obs, eph, star, false);
                            //   double last = SiderealTime.greenwichMeanSiderealTime(time, obs, eph);
                            double last = SiderealTime.apparentSiderealTime(time, obs, eph);
                            // SiderealTime.
                            eph.correctForPolarMotion = false;  //was true
                            eph.correctEOPForDiurnalSubdiurnalTides = false; //was true
                            eph.correctForEOP = false; //was true
                            Nutation.clearPreviousCalculation();
                            ephem = StarEphem.starEphemeris(time, obs, eph, star, false);
                            // ephem = IAU2006.getStarEphemerisWithRespectCIO(time, obs, eph, star, CIO_EPHEMERIS.topocentric);
    
                            LocationElement loc = ephem.getEquatorialLocation();
    
                            System.out.println(loc);
    
    
                            boolean full_ephem = true;
                            EphemElement sephem = Ephem.getEphemeris(time, obs, eph, true);
                            // ConsoleReport.fullEphemReportToConsole(sephem);
                            String Results = ConsoleReport.getBasicEphemReport(sephem, false);
    
    
    
                            myTextarea.setText(("Geodetic location: " + Functions.formatAngleAsDegrees(obs.getLongitudeRad(), 3) + " / " + Functions.formatAngleAsDegrees(obs.getLatitudeRad(), 3) + " / " + obs.getHeight()) +
                                            "\n" + ("JD TT: " + jd_TT + "\n" + "UT1: " + jd_UT1 + "\n" + "TT-UT1: " + TTminusUT1) + "\n" +
                                            (proper + "  geocentric") + "\n" +
                                            ("RA:  " + Functions.formatValue(ephem.rightAscension * Constant.RAD_TO_DEG / 15.0f, 10)) + "\n" +
                                            ("RA:  " + Functions.formatRA(ephem.rightAscension, 4)) + "\n" +
                                            ("DEC: " + Functions.formatAngleAsDegrees(ephem.declination, 10)) + "\n" +
                                            ("DEC: " + Functions.formatDEC(ephem.declination, 4)) + "\n" + ("GP:  " + loc) + "\n" +
                                            ("Az:  " + Functions.formatValue(ephem.azimuth * Constant.RAD_TO_DEG, 10)) + "\n" +
                                            ("Az:  " + Functions.formatAngle(ephem.azimuth, 4)) + "\n" +
                                            ("Alt:  " + Functions.formatValue(ephem.elevation * Constant.RAD_TO_DEG, 10)) + "\n" +
                                            ("Alt:  " + Functions.formatDEC(ephem.elevation)) + "\n" + "\n" +
                                            //("Local Apparent Sidereal Time::  " + ( ((last)* Constant.RAD_TO_HOUR)+ 4)+"\n"+
                                            ("Local Apparent Sidereal Time::  " + (Functions.formatRA((last))) + "\n" + "\n" +
                                                    //  (Functions.formatRA ((last)))
                                                    ("Basic Ephemeris Report:  " + Results))
                                    //  ("Basic Ephem Report:  "))
                            );
                        }
                    }catch(Exception exc){
                        exc.printStackTrace();
                    }
    
                }
    
    
          //  }
        }
    
    
    
    
    }
    
    
    
    
      public void settings() {  size(1000, 750); }
      static public void main(String[] passedArgs) {
        String[] appletArgs = new String[] { "CSVTest2" };
        if (passedArgs != null) {
          PApplet.main(concat(appletArgs, passedArgs));
        } else {
          PApplet.main(appletArgs);
        }
      }
    }
    
  • Converting Java code to Python

    Hi @solub! It took a long time, but I've just finished refactoring "Depth_of_Field.pde". #:-S

    Now that I've reorganized this sketch, I'm ready to convert it to a ".pyde" file. :)>-

    Just w8 a lil' more. Stay w/ the latest ".pde" file for now: :-\"

    /**
     * Depth of Field (DoF) (1.20)
     * Thomas Diewald (diwi) (2017-Oct-07)
    
     * GitHub.com/diwi/PixelFlow/blob/master/examples/Miscellaneous/
     * DepthOfField_Demo/DepthOfField_Demo.java
    
     * Refactor by GoToLoop (v1.4.2) (2018-May-18) (PDE v3.3.5)
     * Forum.Processing.org/two/discussion/27905/converting-java-code-to-python#Item_18
     */
    
    import com.thomasdiewald.pixelflow.java.DwPixelFlow;
    import com.thomasdiewald.pixelflow.java.geometry.DwIndexedFaceSetAble;
    import com.thomasdiewald.pixelflow.java.geometry.DwCube;
    import com.thomasdiewald.pixelflow.java.geometry.DwMeshUtils;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DepthOfField;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwFilter;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwSceneDisplay;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwScreenSpaceGeometryBuffer;
    import com.thomasdiewald.pixelflow.java.utils.DwMagnifier;
    import com.thomasdiewald.pixelflow.java.utils.DwUtils;
    
    import peasy.PeasyCam;
    
    import com.jogamp.opengl.GL2;
    
    import static java.util.Locale.ENGLISH;
    import java.util.Formatter;
    
    final Formatter formatter = new Formatter(ENGLISH);
    
    static final String POSITION = "position: (%8.2f, %8.2f, %8.2f)\n";
    static final String ROTATION = "rotation: (%8.2f, %8.2f, %8.2f)\n";
    static final String LOOK__AT = "look-at:  (%8.2f, %8.2f, %8.2f)\n";
    static final String DISTANCE = "distance: (%8.2f)\n";
    
    final String TITLE = getClass().getName() + "   [fps %6.2f]";
    
    static final int BB_SIZE = 800, BB_OFFSET = BB_SIZE >> 2;
    static final int BB_TOTAL = BB_SIZE + BB_OFFSET;
    static final int BB_COORD = -BB_TOTAL, BB_DIAM = BB_TOTAL << 1;
    
    static final int XMIN = -BB_SIZE, XMAX = BB_SIZE;
    static final int YMIN = -BB_SIZE, YMAX = BB_SIZE;
    static final int ZMIN = 0, ZMAX = BB_SIZE;
    
    static final int BOX_DIAM = BB_OFFSET + BB_OFFSET/20;
    static final int SPH_MIN_D = BB_OFFSET >> 2, SPH_MAX_D = BB_OFFSET >> 1;
    
    static final int BOXES = 50, SPHERES = 50;
    
    static final int CROSS_S = 10, ZFAR = 6000;
    static final int MULT_BLUR = 30, BLUR_POW = (int) pow(MULT_BLUR, 1/3.0);
    static final float RAD60 = 60*DEG_TO_RAD, FPS = 60;
    
    static final color BASE_COL = 0x80FFFFFF, CROSS_COL = 0xd0FFFFFF;
    
    static final long SEED = 0;
    static final boolean FIXED_SEED = false;
    
    static final boolean FULLSCREEN = false, RESIZABLE = false;
    boolean apply_dof = false, alt_render = false;
    
    final boolean[] resized = new boolean[1];
    
    final DwIndexedFaceSetAble cube_smooth = new DwCube(4), cube_facets = new DwCube(2);
    
    PGraphics3D pg_render, pg_dof, pg_tmp;
    PShape shp_scene;
    
    PeasyCam peasy;
    
    DwPixelFlow context;
    DwFilter dw_filter;
    DepthOfField dof;
    DwScreenSpaceGeometryBuffer geombuffer;
    DwMagnifier magnifier;
    
    void settings() {
      if (FULLSCREEN) fullScreen(P3D);
      else size(displayWidth*9/10, displayHeight*9/10, P3D);
      noSmooth();
    }
    
    void setup() {
      frameRate(FPS);
      cursor(CROSS);
    
      if (RESIZABLE)  getSurface().setResizable(true);
      getSurface().setLocation(displayWidth - width >> 1, 8);
    
      peasy = new PeasyCam(this, -4.083, -6.096, 7, 2000);
      peasy.setRotations(1.085, -.477, 2.91);
    
      dw_filter = DwFilter.get(context = new DwPixelFlow(this));
      context.print();
      context.printGL();
    
      dof = new DepthOfField(context);
      dof.param.mult_blur = MULT_BLUR;
    
      final DwSceneDisplay scene_display = new DwSceneDisplay() {  
        @ Override final public void display(final PGraphics3D canvas) {
          displayScene(canvas);
        }
      };
    
      geombuffer = new DwScreenSpaceGeometryBuffer(context, scene_display);
    
      final int mag_h = height/3;
      magnifier = new DwMagnifier(this, 4, 0, height - mag_h, mag_h, mag_h);
    }
    
    void draw() {
      final PGraphics canv = getGraphics();
      final DepthOfField.Param param = dof.param;
    
      setTitle();
      resizeScreen();
      displaySceneWrap(pg_render, canv);
      dw_filter.gamma.apply(pg_render, pg_render);
    
      if (apply_dof)  applyDoF(param);
      renderScene(param, canv);
    }
    
    void keyPressed() {
      final int k = keyCode;
    
      if (k == ENTER | k == RETURN)  shp_scene = null;
      else if (k == 'C' | k == CONTROL)  printCam();
      else if (k == 'P' | k == BACKSPACE)  looping ^= true;
      else if (k == ' ')  apply_dof ^= true;
      else if (k == SHIFT)  alt_render ^= true;
    }
    
    void applyDoF(final DepthOfField.Param param) {
      final PGraphicsOpenGL geom = geombuffer.pg_geom;
      dw_filter.gaussblur.apply(geom, geom, pg_tmp, BLUR_POW);
    
      param.focus_pos[0] = map(mouseX + .5, 0, width, 00, 1);
      param.focus_pos[1] = map(mouseY + .5, 0, height, 1, 0);
      dof.apply(pg_render, pg_dof, geombuffer);
    
      dw_filter.copy.apply(pg_dof, pg_render);
    }
    
    void renderScene(final DepthOfField.Param param, final PGraphics canv) {
      final PGraphics pg = alt_render? geombuffer.pg_geom : pg_render;
    
      magnifier.apply(pg, mouseX, mouseY);
      magnifier.displayTool();
    
      DwUtils.beginScreen2D(canv);
      //peasy.beginHUD();
    
      blendMode(REPLACE);
      image(pg, 0, 0);
      magnifier.display(pg, 0, height - magnifier.h);
    
      final float fpx = param.focus_pos[0] * width;
      final float fpy = (1 - param.focus_pos[1]) * height;
    
      blendMode(EXCLUSION);
      strokeCap(PROJECT);
      stroke(CROSS_COL);
      line(fpx - CROSS_S, fpy, fpx + CROSS_S, fpy);
      line(fpx, fpy - CROSS_S, fpx, fpy + CROSS_S);
      blendMode(BLEND);
    
      //peasy.endHUD();
      DwUtils.endScreen2D(canv);
    }
    
    boolean resizeScreen() { // dynamically resize render-targets
      final int w = width, h = height;
    
      perspective(RAD60, (float) w/h, 2, ZFAR);
      peasy.feed();
    
      boolean happened = resized[0] = false;
      pg_render = DwUtils.changeTextureSize(this, pg_render, w, h, 8, resized);
      happened |= resized[0];
    
      resized[0] = false;
      pg_dof = DwUtils.changeTextureSize(this, pg_dof, w, h, 0, resized);
      happened |= resized[0];
    
      resized[0] = false;
      pg_tmp = DwUtils.changeTextureSize(this, pg_tmp, w, h, 0, resized, 
        GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT);
    
      geombuffer.update(pg_render);
      return happened | resized[0];
    }
    
    void displaySceneWrap(final PGraphics3D canvas, final PGraphics canv) {
      DwUtils.copyMatrices((PGraphicsOpenGL) canv, canvas);
      canvas.beginDraw();
      canvas.background(2);
      displayScene(canvas);
      canvas.endDraw();
    }
    
    void displayScene(final PGraphics3D canvas) {
      canvas.directionalLight(255, 255, 255, 200, 600, 400);
      canvas.directionalLight(255, 255, 255, -200, -600, -400);
      canvas.ambientLight(64, 64, 64);
    
      if (canvas == geombuffer.pg_geom) {
        canvas.background(-1);
        canvas.pgl.clearColor(1, 1, 1, ZFAR);
        canvas.pgl.clear(PGL.COLOR_BUFFER_BIT);
      }
    
      if (shp_scene == null)  shp_scene = makeShape();
      canvas.shape(shp_scene);
    }
    
    PShape makeShape() {
      final PShape scene = createShape(GROUP);
    
      pushStyle();
      colorMode(HSB, 360, 1, 1);
      noStroke();
    
      if (FIXED_SEED)  randomSeed(SEED);
    
      for (int i = 0; i < BOXES; ++i) {
        final float px = random(XMIN, XMAX), py = random(YMIN, YMAX);
        final float sx = random(BOX_DIAM, BOX_DIAM), sy = random(BOX_DIAM, BOX_DIAM);
        final float sz = random(ZMIN, ZMAX);
    
        fill(random(-45, 45), 1, random(.1, 1));
        final PShape shp_box = createShape(BOX, sx, sy, sz);
        shp_box.translate(px, py, sz*.5);
        scene.addChild(shp_box);
      }
    
      for (int i = 0; i < SPHERES; ++i) {
        final float px = random(XMIN, XMAX), py = random(YMIN, YMAX);
        final float pz = random(ZMIN, ZMAX), rr = random(SPH_MIN_D, SPH_MAX_D);
    
        fill(random(205, 245), 1, random(.1, 1));
        final PShape shp_sphere = createShape(PShape.GEOMETRY);
        shp_sphere.scale(rr);
        shp_sphere.translate(px, py, pz);
        scene.addChild(shp_sphere);
    
        if ((i&1) == 0)
          DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, false);
        else
          DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, true);
      }
    
      fill(BASE_COL);
      scene.addChild(createShape(RECT, BB_COORD, BB_COORD, BB_DIAM, BB_DIAM));
    
      popStyle();
      return scene;
    }
    
    static final void clearFormatter(final Formatter f) {
      ((StringBuilder) f.out()).setLength(0);
    }
    
    void setTitle() {
      clearFormatter(formatter);
      getSurface().setTitle(formatter.format(TITLE, frameRate).toString());
    }
    
    void printCam() {
      final float[] pos = peasy.getPosition();
      final float[] rot = peasy.getRotations();
      final float[] lat = peasy.getLookAt();
      final double  dis = peasy.getDistance();
    
      clearFormatter(formatter);
    
      println(formatter.
        format(POSITION, pos[0], pos[1], pos[2]).
        format(ROTATION, rot[0], rot[1], rot[2]).
        format(LOOK__AT, lat[0], lat[1], lat[2]).
        format(DISTANCE, dis));
    }
    
  • Creating scalable noise patterns from existing images

    Nice. The steganographic complimentary signal / steganographic aspect is very interesting.

    One nice thing about your rect() approach (as opposed to built-in scaling or scaling through direct pixel manipulation) is that you can easily swap out other shapes or transforms for rendering. For example....

    // Scale Pixels to Shapes
    // 2018-05-18 Processing 3.3.6
    // forum.processing.org/two/discussion/26524/creating-scalable-noise-patterns-from-existing-images#latest
    
    PImage img;
    boolean shapeType;
    int SCALE = 16;
    
    void setup() {
      size(512, 512);
      img = loadImage("https" +  "://processing.org/img/processing3-logo.png");
      img.resize(32, 32);
      noStroke();
      ellipseMode(CORNER);
    }
    
    void draw() {
      background(192);
      img.loadPixels();
      for ( int y=0; y<img.width; y++) {
        for ( int x=0; x<img.width; x++) {
          fill(img.get(x, y));
          if(shapeType){
            rect(x*SCALE, y*SCALE, SCALE, SCALE);
          }
          else {
            ellipse(x*SCALE, y*SCALE, SCALE, SCALE);
          }
        }
      }
      noLoop();
    }
    
    void keyPressed(){
      shapeType = !shapeType;
      redraw();
    }
    

    For example:

    ScalePixelsToShapes2--screenshot

  • Creating scalable noise patterns from existing images

    Thanks for sharing you solution, @Sam1945.

    Am I right in understanding based on your description that your code looked something like this?

    // Scale Pixels to Shapes
    // 2018-05-18 Processing 3.3.6
    // forum.processing.org/two/discussion/26524/creating-scalable-noise-patterns-from-existing-images#latest
    
    PImage img;
    boolean shapeType;
    int SCALE = 8;
    
    void setup() {
      size(512, 512);
      img = loadImage("https" +  "://processing.org/img/processing3-logo.png");
      img.resize(64, 64);
      noStroke();
      img.loadPixels();
      for ( int y=0; y<img.width; y++) {
        for ( int x=0; x<img.width; x++) {
          fill(img.get(x, y));
          rect(x*SCALE, y*SCALE, SCALE, SCALE);
        }
      }
    }
    

    ScalePixelsToShapes--screenshot

    Or by "rect object" to you mean a PShape?, e.g.

    createShape(RECT, 0, 0, 5, 5);
    
  • LiquidFun box2d textures?

    LiquidFun can be found in the Add Library listing, it seems to be the best implementation of box2d for processing. Much higher and smoother framerates than the other two listed.

    For a start I would point to the included example box2d_BrickWall and seeing if you can draw the bricks with a rect in place of the box2d rendering.

    Here's my attempt. But this example doesn't move the box2d camera, the box2d_car example does and might be better, that's the part I was having problems with. Basically my scale settings are just tuned by hand to match, can't find a way to get it spot on. I've edited this to draw the bricks with rects instead of the box2d renderer

    edit: I seem to have it kinda figured out enough

     /**
     * 
     * LiquidFunProcessing | Copyright 2017 Thomas Diewald - www.thomasdiewald.com
     * 
     * https://github.com/diwi/LiquidFunProcessing.git
     * 
     * Box2d / LiquidFun Library for Processing.
     * MIT License: https://opensource.org/licenses/MIT
     * 
     */
    
    
    import com.thomasdiewald.liquidfun.java.DwWorld;
    
    import org.jbox2d.collision.shapes.CircleShape;
    import org.jbox2d.collision.shapes.PolygonShape;
    import org.jbox2d.common.Vec2;
    import org.jbox2d.dynamics.Body;
    import org.jbox2d.dynamics.BodyDef;
    import org.jbox2d.dynamics.BodyType;
    import org.jbox2d.dynamics.FixtureDef;
    
    import processing.core.*;
    import processing.opengl.PGraphics2D;
    
    
      //
      // Simple stacking demo.
      //
      //
      // Controls:
      //
      // LMB         ... drag bodies
      // LMB + SHIFT ... shoot bullet
      // MMB         ... add particles
      // RMB         ... remove particles
      // 'r'         ... reset
      // 't'         ... update/pause physics
      // 'f'         ... toggle debug draw
      //
    
    
      int viewport_w = 1280;
      int viewport_h = 720;
      int viewport_x = 230;
      int viewport_y = 0;
    
      boolean UPDATE_PHYSICS = true;
      boolean USE_DEBUG_DRAW = false;
    
      DwWorld world;
      ArrayList<Body> bricks = new ArrayList<Body>();
    
      public void settings(){
        size(viewport_w, viewport_h, P2D);
        smooth(8);
      }
    
      public void setup(){ 
        surface.setLocation(viewport_x, viewport_y);
        reset();
        world.setGravity(new Vec2(0,-32.0));
        frameRate(60);
      }
    
    
      public void release(){
        if(world != null) world.release(); world = null;
      }
    
      public void reset(){
        // release old resources
        release();
    
        world = new DwWorld(this, 20);
    
        // create scene: rigid bodies, particles, etc ...
        initScene();
      }
    
    
      PVector pos = new PVector(0,0);
      public void draw(){
         pos = new PVector(22,32);
         world.transform.setCamera(pos.x, pos.y/2);
    
        if(UPDATE_PHYSICS){
          world.update();
        }
    
    
        PGraphics2D canvas = (PGraphics2D) this.g;
    
        canvas.background(32);
        canvas.pushMatrix();
        world.applyTransform(canvas);
        world.drawBulletSpawnTrack(canvas);
    
        if(USE_DEBUG_DRAW){
          world.displayDebugDraw(canvas);
          // DwDebugDraw.display(canvas, world);
        } else {
         world.bodies.display(canvas);
          world.particles.display(canvas);
        }
        canvas.popMatrix();
    
        pushMatrix();
        scale(20,20);
        //world.transform
        translate(pos.x/-1.0,( pos.y/2 + -18));
         for (Body b : bricks){
           //Vec2 t = b.getTransform();
           pushMatrix();
           // Vec2 l = b.getWorldCenter();
              Vec2 l = b.getWorldCenter();
           translate(32+l.x,36-l.y);
           rotate(-b.getAngle());
           rect(-0.5, 0, 1.00,0.25);
           //println( b.getContactList());
           popMatrix();
         }
        popMatrix();   
    
    
        int num_bodies    = world.getBodyCount();
        int num_particles = world.getParticleCount();
        String txt_fps = String.format(getClass().getName()+ " [bodies: %d]  [particles: %d]  [fps %6.2f]", num_bodies, num_particles, frameRate);
        surface.setTitle(txt_fps);
      }
    
      //////////////////////////////////////////////////////////////////////////////
      // User Interaction
      //////////////////////////////////////////////////////////////////////////////
    
      public void keyReleased(){
        if(key == 'r') reset();
        if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
        if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
      }
    
    
    
      //////////////////////////////////////////////////////////////////////////////
      // Scene Setup
      //////////////////////////////////////////////////////////////////////////////
    
      public void initScene() {
    
        float screen_scale = world.transform.screen_scale;
        float b2d_screen_w = world.transform.box2d_dimx;
        float b2d_screen_h = world.transform.box2d_dimy;
        float b2d_thickness = 20 / screen_scale;
    
        {
    
          float radius = 25 / screen_scale;
          CircleShape circle_shape = new CircleShape();
          circle_shape.setRadius(radius);
    
          FixtureDef fixture_def = new FixtureDef();
          fixture_def.shape = circle_shape;
          fixture_def.density = 10f;
          fixture_def.friction = 0.30f;
          fixture_def.restitution = 0.30f;
    
          BodyDef body_def = new BodyDef();
          body_def.type = BodyType.DYNAMIC;
          body_def.angle = 0.0f;
          body_def.position.x = -1/screen_scale;
          body_def.position.y = b2d_screen_h - 10;
          body_def.bullet = true;
    
          Body circle_body = world.createBody(body_def);
          circle_body.createFixture(fixture_def);
    
          world.bodies.add(circle_body, true, color(64, 125, 255), true, color(0), 1f);
        }
    
        { // Walls
          BodyDef bd = new BodyDef();
          bd.position.set(0, 0);
    
          Body ground = world.createBody(bd);
          PolygonShape sd = new PolygonShape();
    
          float x, y, w, h;
    
          // BOTTOM
          x = 0;
          y = 0;
          w = b2d_screen_w;
          h = b2d_thickness;
          sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
          ground.createFixture(sd, 0f);
    
          // TOP
          x = 0;
          y = b2d_screen_h;
          w = b2d_screen_w;
          h = b2d_thickness;
          sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
          ground.createFixture(sd, 0f);
    
          // LEFT
          x = -b2d_screen_w/2;
          y = +b2d_screen_h/2;
          w = b2d_thickness;
          h = b2d_screen_h - b2d_thickness;
          sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
          ground.createFixture(sd, 0f);
    
          // RIGHT
          x = +b2d_screen_w/2;
          y = +b2d_screen_h/2;
          w = b2d_thickness;
          h = b2d_screen_h - b2d_thickness;
          sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
          ground.createFixture(sd, 0f);
    
          world.bodies.add(ground, true, color(0), !true, color(0), 1f);
        }
    
        createWall(10, 20, 40, 20, 0, 10);
    
      }
    
    
      public void createWall(int numx, int numy, float dimx, float dimy, float tx, float ty){
    
        float scree_scale = world.transform.screen_scale;
    
    
        dimx /= scree_scale;
        dimy /= scree_scale;
    
        tx /= scree_scale;
        ty /= scree_scale;
    
        PolygonShape brick_shape = new PolygonShape();
        brick_shape.setAsBox(dimx*0.5f, dimy*0.5f);
    
        PolygonShape brick_shape2 = new PolygonShape();
        brick_shape2.setAsBox(dimx*0.25f, dimy*0.5f);
    
        FixtureDef fixture_def = new FixtureDef();
        fixture_def.shape = brick_shape;
        fixture_def.density = 40;
        fixture_def.friction = 0.7f;
        fixture_def.restitution = 0.00f;
    
        BodyDef body_def = new BodyDef();
        body_def.type = BodyType.DYNAMIC;
        body_def.angle = 0.0f;
        body_def.allowSleep = true;
    
    
        int scol = color(0);
        int fcol = color(224,128,64);
    
        colorMode(HSB, 360,100,100);
    
        randomSeed(1);
    
        float ox = 0;
        float oy = dimy/2;
        for(int y = 0; y < numy; y++){
    
          float off = 0.5f;
    
          for(int x = 0; x < numx; x++){
            boolean odd_row = (y & 1) == 1;
    
            ox = -numx * dimx * 0.5f;
            ox += odd_row ? dimx * off : 0;
    
            fixture_def.shape = brick_shape;
            if(!odd_row && x == 0){
              fixture_def.shape = brick_shape2;
              ox += dimx * 0.25;
            }
            else if(odd_row && x == (numx-1)){
              fixture_def.shape = brick_shape2;
              ox -= dimx * 0.25;
            }
    
            body_def.position.x = tx + ox + x * (dimx);
            body_def.position.y = ty + oy + y * (dimy);
    
            Body brick = world.createBody(body_def);
            brick.createFixture(fixture_def);
            bricks.add(brick);
            float hsb_h = 20 + random(-3, 3);
            float hsb_s = random(70,60);
            float hsb_b = random(70,100);
            fcol = color(hsb_h, hsb_s, hsb_b);
            world.bodies.add(brick, true, fcol, true, scol, 0.5f);
    
          }
        }
    
        colorMode(RGB, 255);
    
      }
    
  • Sound Library

    MacBook Pro, OSX 10.13.4, Processing 3.3.7. Sound Library example sketch, when run no sound on the left channel, and it crashes on exit.

    /**
     * Processing Sound Library, Example 5
     * 
     * This sketch shows how to use the FFT class to analyze a stream  
     * of sound. Change the variable bands to get more or less 
     * spectral bands to work with. The smooth_factor variable determines 
     * how much the signal will be smoothed on a scale form 0-1.
     */
    
    import processing.sound.*;
    SoundFile   sample;
    FFT         fft;
    AudioDevice device;
    
    // Declare a scaling factor
    int scale = 10;
    
    // Define how many FFT bands we want
    int bands = 16;
    
    // declare a drawing variable for calculating rect width
    float r_width;
    
    // Create a smoothing vector
    float[] sum = new float[bands];
    
    // Create a smoothing factor
    //float smooth_factor = 0.2;
    
    void setup() {
      size(320,240);
      background(0);
    
      // If the Buffersize is larger than the FFT Size, the FFT will fail
      // so we set Buffersize equal to bands
      device=new AudioDevice(this,44100,bands);
    
      // Calculate the width of the rects depending on how many bands we have
      r_width = width/float(bands);
    
      // Load and play a soundfile and loop it. This has to be called 
      // before the FFT is created.
      // loop() crashes at end of file !!!
      sample=new SoundFile(this,"test.mp3");
      sample.play();
      // Create and patch the FFT analyzer
      fft=new FFT(this,bands);
      fft.input(sample);
    }      
    
    void draw() {
      background(0);
      fill(0,128,255);
      noStroke();
      fft.analyze();
      for (int i = 0; i < bands; i++) {
        //sum[i] += (fft.spectrum[i] - sum[i]) * smooth_factor;
        sum[i]=fft.spectrum[i];
        rect( i*r_width, height, r_width, -sum[i]*height*scale );
      }
    }
    
  • Converting Java code to Python

    I'm back with another question, sorry. I still have a persistent issue with the resizeScreen() function and more particularly with thepg_render and pg_tmp grahics buffers variables.

    When running the .pyde script I get the following error messages:

    GammaCorrection.apply shader | GL_ERROR: invalid operation GammaCorrection.apply | GL_ERROR: invalid operation GammaCorrection.apply | GL_ERROR: invalid framebuffer operation

    This occurs at line 110 (Java script) or 58 (Python version):

    DwFilter.get(context).gamma.apply(pg_render, pg_render)

    Do you know what could be the problem here ?

    Here below, for comparison purposes:

    • a shortened version of the original DoF example sketch in Java (working)
    • the Python transcription of this version (not working)

    Java

    import java.util.Locale;
    import com.jogamp.opengl.GL2;
    import com.thomasdiewald.pixelflow.java.DwPixelFlow;
    import com.thomasdiewald.pixelflow.java.geometry.DwCube;
    import com.thomasdiewald.pixelflow.java.geometry.DwMeshUtils;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DepthOfField;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwFilter;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwSceneDisplay;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwScreenSpaceGeometryBuffer;
    import com.thomasdiewald.pixelflow.java.utils.DwMagnifier;
    import com.thomasdiewald.pixelflow.java.utils.DwUtils;
    
    import peasy.*;
    import processing.core.PApplet;
    import processing.core.PConstants;
    import processing.core.PShape;
    import processing.opengl.PGL;
    import processing.opengl.PGraphics3D;
    
    
      boolean START_FULLSCREEN = !true;
    
      int viewport_w = 1280;
      int viewport_h = 720;
      int viewport_x = 230;
      int viewport_y = 0;
    
      // camera control
      PeasyCam peasycam;
    
      // library context
      DwPixelFlow context;
    
      PGraphics3D pg_render;
      PGraphics3D pg_dof;
      PGraphics3D pg_tmp;
    
      DepthOfField dof;
      DwScreenSpaceGeometryBuffer geombuffer;
    
      boolean APPLY_DOF = true;
    
    
      public void settings() {
        if(START_FULLSCREEN){
          viewport_w = displayWidth;
          viewport_h = displayHeight;
          viewport_x = 0;
          viewport_y = 0;
          fullScreen(P3D);
        } else {
          size(viewport_w, viewport_h, P3D);
        }
        smooth(0);
      }
    
    
      public void setup() {
    
        // camera
        peasycam = new PeasyCam(this, -4.083,  -6.096,   7.000, 1300);
        peasycam.setRotations(  1.085,  -0.477,   2.910);
    
        // main library context
        context = new DwPixelFlow(this);
        context.print();
        context.printGL();
    
        // callback for scene display (used in GBAA)
        DwSceneDisplay scene_display = new DwSceneDisplay() {  
          @Override
          public void display(PGraphics3D canvas) {
            displayScene(canvas); 
          }
        };
    
        geombuffer = new DwScreenSpaceGeometryBuffer(context, scene_display);
    
        dof = new DepthOfField(context);
    
        frameRate(1000);
      }
    
    
    
      // dynamically resize render-targets
      public boolean resizeScreen(){
    
        boolean[] RESIZED = {false};
    
        pg_render = DwUtils.changeTextureSize(this, pg_render, width, height, 8, RESIZED);
        pg_dof    = DwUtils.changeTextureSize(this, pg_dof   , width, height, 0, RESIZED);
        pg_tmp    = DwUtils.changeTextureSize(this, pg_tmp   , width, height, 0, RESIZED, GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT);
    
    
        peasycam.feed();
        perspective(60 * DEG_TO_RAD, width/(float)height, 2, 6000);
    
        return RESIZED[0];
      }
    
    
    
      public void draw() {
    
        resizeScreen();
    
        displaySceneWrap(pg_render);
    
        DwFilter.get(context).gamma.apply(pg_render, pg_render);
    
        int mult_blur = 30;
        geombuffer.update(pg_render);
    
        DwFilter.get(context).gaussblur.apply(geombuffer.pg_geom, geombuffer.pg_geom, pg_tmp, (int) Math.pow(mult_blur, 0.33f));
    
    ////      dof.param.focus     = map(mouseX, 0, width, 0, 1);
        dof.param.focus_pos = new float[]{0.5f, 0.5f};
        dof.param.focus_pos[0] = map(mouseX+0.5f, 0, width , 0, 1);
        dof.param.focus_pos[1] = map(mouseY+0.5f, 0, height, 1, 0);
        dof.param.mult_blur = mult_blur;
        dof.apply(pg_render, pg_dof, geombuffer);
    
        DwFilter.get(context).copy.apply(pg_dof, pg_render);
    
    
        DwUtils.beginScreen2D(g);
        {
          blendMode(REPLACE);
          clear();
          image(pg_render, 0, 0);    
        }
        DwUtils.endScreen2D(g);
      }
    
    
    
      public void displaySceneWrap(PGraphics3D canvas){
        canvas.beginDraw();
        DwUtils.copyMatrices((PGraphics3D) this.g, canvas);
        // background
        canvas.blendMode(PConstants.BLEND);
        canvas.background(2);
        displayScene(canvas);
        canvas.endDraw();
      }
    
    
    
      // render something
      public void displayScene(PGraphics3D canvas){
        // lights
        canvas.directionalLight(255, 255, 255, 200,600,400);
        canvas.directionalLight(255, 255, 255, -200,-600,-400);
        canvas.ambientLight(64, 64, 64);
    
        if(canvas == geombuffer.pg_geom){
          canvas.background(255, 255);
          canvas.pgl.clearColor(1, 1, 1, 6000);
          canvas.pgl.clear(PGL.COLOR_BUFFER_BIT);
        }
    
    
        sceneShape(canvas);
      }
    
      PShape shp_scene;
    
      public void sceneShape(PGraphics3D canvas){
        if(shp_scene != null){
          canvas.shape(shp_scene);
          return;
        }
    
        shp_scene = createShape(GROUP);
    
        int num_spheres = 50;
        float bb_size = 800;
        float xmin = -bb_size;
        float xmax = +bb_size;
        float ymin = -bb_size;
        float ymax = +bb_size;
        float zmin =  0;
        float zmax = +bb_size;
    
        colorMode(HSB, 360, 1, 1);
    
        DwCube cube_smooth = new DwCube(4);
        DwCube cube_facets = new DwCube(2);
    
        for(int i = 0; i < num_spheres; i++){
          float px = random(xmin, xmax);
          float py = random(ymin, ymax);
          float pz = random(zmin, zmax);
          float rr = random(50) + 50;
          boolean facets = true;//(i%2 == 0);
    
          float off = 20;
          float base = 225;
          float hsb_h = base + random(-off,off);
          float hsb_s = 1;
          float hsb_b = random(0.1f,1.0f);
          int shading = color(hsb_h, hsb_s, hsb_b);
    
          PShape shp_sphere = createShape(PShape.GEOMETRY);
          if(facets){
            DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, false);
          } else {
            DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, true);
          }
    
          shp_sphere.setStroke(!true);
          shp_sphere.setStroke(color(0));
          shp_sphere.setStrokeWeight(0.01f / rr);
          shp_sphere.setFill(true);
          shp_sphere.setFill(shading);
          shp_sphere.resetMatrix();
          shp_sphere.scale(rr);
          shp_sphere.translate(px, py, pz);
          shp_scene.addChild(shp_sphere);
        }
    
      }
    

    Python

    add_library('PixelFlow')
    add_library('peasycam')
    from com.jogamp.opengl import GL2
    import java.util.Locale
    
    liste = []
    viewport_w = 1280
    viewport_h = 720
    viewport_x = 0
    viewport_y = 0
    FS = False
    
    def settings():
        global viewport_w, viewport_h
        if FS:
            viewport_w = displayWidth
            viewport_h = displayHeight
            viewport_x = 0
            viewport_y = 0
            fullScreen(P3D)
        else:
            size(viewport_w, viewport_h, P3D)
        smooth(0)
    
    
    def setup():
        global context, scene_display, geombuffer, dof, cam
    
        cam = PeasyCam(this, -4.083,  -6.096,   7.000, 1300)
    
        context = DwPixelFlow(this)
        context.print()
        context.printGL()
    
        scene_display = MySceneDisplay() 
        geombuffer = DwScreenSpaceGeometryBuffer(context, scene_display)
        dof = DepthOfField(context)
    
    
    def resizeScreen():
        global pg_render, pg_dof, pg_tmp
        RESIZED = [False]
        pg_render = DwUtils.changeTextureSize(this, None, width, height, 8, RESIZED)
        pg_dof    = DwUtils.changeTextureSize(this, None, width, height, 0, RESIZED)
        pg_tmp    = DwUtils.changeTextureSize(this, None, width, height, 0, RESIZED, GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT)
    
        cam.feed()
        perspective(60 * DEG_TO_RAD, width/float(height), 2, 6000)
    
        return RESIZED[0]
    
    
    def draw():
        resizeScreen()
    
        displaySceneWrap(pg_render)
    
        DwFilter.get(context).gamma.apply(pg_render, pg_render)
    
        mult_blur = 30
    
        geombuffer.update(pg_render)
    
        DwFilter.get(context).gaussblur.apply(geombuffer.pg_geom, geombuffer.pg_geom, pg_tmp, int(Math.pow(mult_blur, 0.33)))
    
        dof.param.focus_pos = float(0.5, 0.5)
        dof.param.focus_pos[0] = map(mouseX+0.5, 0, width, 0, 1)
        dof.param.focus_pos[1] = map(mouseY+0.5, 0, height, 1, 0)
        dof.param.mult_blur = mult_blur
        dof.apply(pg_render, pg_dof, geombuffer)
    
        DwFilter.get(context).copy.apply(pg_dof, pg_render)
    
        DwUtils.beginScreen2D(g)
        blendMode(REPLACE)
        clear()
        image(pg.render,0,0)
        DwUtils.endScreen2D(g)
    
    
    def displaySceneWrap(canvas):
        canvas.beginDraw()
        DwUtils.copyMatrices(this.g, canvas)
        canvas.blendMode(PConstants.BLEND)
        canvas.background(2)
        displayScene(canvas)
        canvas.endDraw()
    
    def displayScene(canvas):
        canvas.directionalLight(255, 255, 255, 200,600,400)
        canvas.directionalLight(255, 255, 255, -200,-600,-400)
        canvas.ambientLight(64, 64, 64)
    
        if canvas == geombuffer.pg_geom:
            canvas.background(255, 255)
            canvas.pgl.clearColor(1, 1, 1, 6000)
            canvas.pgl.clear(PGL.COLOR_BUFFER_BIT)
    
        sceneShape(canvas)
    
    
    def sceneShape(canvas): 
    
        shp_scene = createShape(GROUP)
    
        if shp_scene != None:
            canvas.shape(shp_scene)
            return   
    
        num_spheres = 50
        bb_size = 800
        xmin = -bb_size
        xmax = +bb_size
        ymin = -bb_size
        ymax = +bb_size
        zmin =  0
        zmax = +bb_size
    
        colorMode(HSB, 360, 1, 1)
    
        cube_smooth = DwCube(4)
        cube_facets = DwCube(2)
    
        for i in range(num_spheres):
            px = random(xmin, xmax)
            py = random(ymin, ymax)
            pz = random(zmin, zmax)
            facets = True
    
            off = 20
            base =225
            hsb_h = base + random(-off, off)
            hsb_s = 1
            hsb_b = random(0.1, 1.0)
            shading = color(hsb_h, hsb_s, hsb_b)
    
        shp_sphere = createShape(PShape.GEOMETRY)
        if facets:
            DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, False)
        else:
            DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, True)
    
        shp_sphere.setStroke(False);
        shp_sphere.setStroke(color(0));
        shp_sphere.setStrokeWeight(0.01 / rr);
        shp_sphere.setFill(True);
        shp_sphere.setFill(shading);
        shp_sphere.resetMatrix();
        shp_sphere.scale(rr);
        shp_sphere.translate(px, py, pz);
        shp_scene.addChild(shp_sphere);
    
    
    class MySceneDisplay(DwSceneDisplay): 
        def display(_, canvas): displayScene(canvas)
    
  • Easing (smooth transitions) with functions instead of two variables?

    [Code below] Further down is my preferred solution, written in native JS, but applicable to p5. It's not the solution I wanted, but I think it's the most readable one so far.

    For those who haven't seen this before, this is called "easing"(?), and it's is a way of achieving smooth animations. (I just call it "damping", because that's what I know from vvvv.)

    For most cases, this technique looks far better than instant movements or linearly increasing variables.

    Basically, each time the damping function is called, x.damped gets 5% closer to x.target.

    In this example, x.target is changed from 0 to 100. x.damped then gets incremented by 5% of what's remaining to the target, each frame:

    (0): 0.000 (+5.000)
    (1): 5.000 (+4.750)
    (2): 9.750 (+4.513)
    (3): 14.262 (+4.287)
    (4): 18.549 (+4.073)
    (5): 22.622 (+3.869)
    (6): 26.491 (+3.675)
    (7): 30.166 (+3.492)
    (8): 33.658 (+3.317)
    (9): 36.975 (+3.151)
    (10): 40.126 (+2.994)
    (11): 43.120 (+2.844)
    (12): 45.964 (+2.702)
    (13): 48.666 (+2.567)
    (14): 51.233 (+2.438)
    (15): 53.671 (+2.316)
    (16): 55.987 (+2.201)
    (17): 58.188 (+2.091)
    (18): 60.279 (+1.986)
    (19): 62.265 (+1.887)
    (20): 64.151 (+1.792)
    (21): 65.944 (+1.703)
    (22): 67.647 (+1.618)
    (23): 69.264 (+1.537)
    (24): 70.801 (+1.460)
    (25): 72.261 (+1.387)
    (26): 73.648 (+1.318)
    (27): 74.966 (+1.252)
    (28): 76.217 (+1.189)
    (29): 77.406 (+1.130)
    (30): 78.536 (+1.073)
    (31): 79.609 (+1.020)
    (32): 80.629 (+0.969)
    (33): 81.597 (+0.920)
    (34): 82.518 (+0.874)
    (35): 83.392 (+0.830)
    (36): 84.222 (+0.789)
    (37): 85.011 (+0.749)
    (38): 85.760 (+0.712)
    (39): 86.472 (+0.676)
    (40): 87.149 (+0.643)
    (41): 87.791 (+0.610)
    (42): 88.402 (+0.580)
    (43): 88.982 (+0.551)
    (44): 89.533 (+0.523)
    (45): 90.056 (+0.497)
    (46): 90.553 (+0.472)
    (47): 91.026 (+0.449)
    (48): 91.474 (+0.426)
    (49): 91.901 (+0.405)
    (50): 92.306 (+0.385)
    (51): 92.690 (+0.365)
    (52): 93.056 (+0.347)
    (53): 93.403 (+0.330)
    (54): 93.733 (+0.313)
    (55): 94.046 (+0.298)
    (56): 94.344 (+0.283)
    (57): 94.627 (+0.269)
    (58): 94.895 (+0.255)
    (59): 95.151 (+0.242)
    (60): 95.393 (+0.230)
    etc.
    

    Paste into .html file:

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Page Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <style>
            * {
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    
    <body>
        <canvas></canvas>
        <script>
            const canvas = document.querySelector("canvas");
            const c = canvas.getContext("2d");
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
    
            let mouseX = {target: 0, damped: 0};
            let mouseY = {target: 0, damped: 0};
            let radius = {target: 20, damped: 20};
            let hue = {target: 0, damped: 0};
    
            let frameCount = 0;
            let bigCircle = false;
            let circleSize = 100;
    
            canvas.addEventListener("mousemove", event => {
                mouseX.target = event.layerX;
                mouseY.target = event.layerY;
            });
    
            addEventListener("click", () => {
                bigCircle = !bigCircle;
                if (bigCircle) {
                    radius.target = 100;
                } else {
                    radius.target = 20;
                }
            });
    
            (function draw() {
                damping();
                changeHueEverySecond();
                background();
                cursor();
                requestAnimationFrame(draw);
            })();
    
            function damping() {
                mouseX.damped += 0.05 * (mouseX.target - mouseX.damped);
                mouseY.damped += 0.05 * (mouseY.target - mouseY.damped);
                radius.damped += 0.05 * (radius.target - radius.damped);
                hue.damped += 0.05 * (hue.target - hue.damped);
            }
    
            function changeHueEverySecond() {
                frameCount++;
                if (frameCount % 60 === 0) {
                    hue.target = frameCount;
                }
            }
    
            function background() {
                c.fillStyle = "#ffa";
                c.fillRect(0, 0, canvas.width, canvas.height);
                c.fill();
            }
    
            function cursor() {
                c.fillStyle = `hsl(${hue.damped}, 50%, 50%)`;
                c.beginPath();
                c.arc(mouseX.damped, mouseY.damped, radius.damped, 0, Math.PI * 2);
                c.closePath();
                c.fill();
            }
        </script>
    </body>
    
    </html>
    

    A possible improvement would be to loop over an array or an object in the damping function, but I like being able to use x.damped instead of dampArray[2].damped or dampObject.x.damped for example.