Text array in p5js

Hello there,

I am trying to reproduce an old sketch in p5js but I ran into troubles...

Here is the code

var fontRegular, fontBold

var offset = 20
var z = 0.0

function preload(){

    fontRegular = loadFont("assets/Regular.otf")
    fontBold = loadFont("assets/Bold.otf")
}


function setup() {

    createCanvas(windowWidth, windowHeight)
    colorMode(HSB,360, 100, 100);

}

function draw() {

    background(5)       

    var chars = "+ — I O"
    var splitString = split(chars, " ");

    textFont(fontRegular);
    fill(0,0,100).strokeWeight(0).textSize(20)
    text(s, 10, 10, 200, 80)

    for ( var x = offset; x < width - offset; x += offset){
        for (var y = offset; y < height - offset; y += offset){


            var nl = map(noise(z, x/450.0, y/450.0), 0, 1, 0, 3)

            text(chars[nl], x, y)
        }
    }

    z = z + .0006

}

Console is given me an error from the p5.js library: p5.js:12854 Uncaught TypeError: Cannot read property 'toString' of undefined

This is the original sketch that works perfectly in Processing:

float z = 0.0;
PFont myFont;
int offset = 18;

void setup(){
  size(500,700);
  pixelDensity(displayDensity());
  //colorMode(HSB, 360,300,360);
  noStroke();
  myFont = createFont("MaisonNeue-Bold", 10);
  textFont(myFont);
  textAlign(CENTER, CENTER);

}

void draw() {

  background(255);
  String[] chars = split("+ — I O + C", ' ');

  for ( int x = offset*3; x < width-offset*2; x +=offset){
    for ( int y = offset*3; y < height-offset*2; y += offset){

      int nl = (int) map(noise(z, x / 450.0, y / 450.0), 0, 1, 0, 7);

      fill(0);
      rectMode(CENTER);
      if ((y - 16) % (2) == 0){
        text(chars[nl], x,y );}
        else{
        text(chars[nl], x + 8 ,y);
        }

    }
  }

  z = z + .006;

}

I'm guessing I am doing something wrong with arrays in p5js...

Any suggestions?

Thank you!

Answers

  • edited August 2016 Answer ✓

    First of all, your sketch won't run because s isn't defined. (While you're at it, might as well get rid of those fonts as well, since they have nothing to do with the problem and just get in the way.)

    But after I define s (I just set it to "abc") then I see the error in the JavaScript console.

    On the same line as the error, I also see a link to p5.js:15538. I click that to determine that the problem is in the text() function. That tells me that something is wrong with chars[nl].

    Okay, so knowing that, I print out the value of nl. Turns out it's 1.4792704460346342. Does this make sense?

    chars[1.4792704460346342]
    

    Probably not. Maybe you meant to convert nl into an int before using it as an array index?

    Notice that you do this in the original code:

    int nl = (int) map(noise(z, x / 450.0, y / 450.0), 0, 1, 0, 7);
    

    You might want to check out the int() function.

  • edited August 2016 Answer ✓

    var nl = map(noise(z, x/450, y/450), 0, 1, 0, 3)

    There are many ways in order to truncate the fractional part of a number in JS. 2 of my favorites are:

    1. double ~~ -> const nl = ~~map(noise(z, x/450, y/450), 0, 1, 0, 3)
    2. | 0 -> const nl = map(noise(z, x/450, y/450), 0, 1, 0, 3) | 0
  • edited August 2016

    wow!

    thank you so much for the help.

    @GoToLoop now I wonder if these ways to truncate the fractional part are rounding my numbers up or down

  • The int() function is designed for exactly this purpose, and it matches the behavior of the original code. No point making it more complicated and harder to read.

    Truncating is not rounding. It's just chopping off the deimcal part. If you want to round, then use the round() function. If you always want to round up, then just add 1 and then truncate using the int() function. (You might want to add a check for the case where it's already an int value.)

  • @KevinWorkman but the thing is there is not round( ) or int( ) function in p5js isn't? or I am missing something...

  • @alexdontsurf Please click the link I provided in my post, which takes you to the P5.js reference on the round() function.

    Alternatively you could just google "JavaScript round", since P5.js is JavaScript.

    Here's the link again: https://p5js.org/reference/#/p5/round

    More generally, the reference should be your first stop for questions like this.

  • I did a really bad search, thank again Kevin

  • edited August 2016 Answer ✓

    Those 2 techniques erase the fractional part completely w/ excellent performance! >:/
    Even something as 4.999999999999999 becomes 4! @-)

    For rounding numbers, there are round(), floor(), ceil().
    Other more JS specific includes parseInt() & Number.parseInt():

    1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt
    2. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseInt
  • @GoToLoop Yes, that's the definition of truncating. That's what the original code does by casting to int, and that's what the int() function does. I'm not sure what your point is?

  • I'm not sure what your point is?

    How about completeness for starters? So the OP can choose which 1 to use? :-\"

  • edited August 2016

    delete this comment

  • edited March 2019

    Hmm.... you've deleted your latest post. So it seems you've got it working already, right? >-)
    However, since I was already trying to solve it as well, gonna leave my own version posted here. :-\"
    1st 1 is the tweaked Java version (also compatible w/ Pjs), which is the basis for the p5.js version: :>

    /**
     * Noisy Char Grid (v2.3.1)
     * by  AlexDontSurf (2016-Aug-31)
     * mod GoToLoop
     *
     * Forum.Processing.org/two/discussion/18026/text-array-in-p5js#Item_12
     * p5js.SketchPad.cc/sp/pad/view/ro.CEAew8yiEGaOO8/latest
     *
     * Forum.Processing.org/two/discussion/18859/running-p5-js-in-google-sites
     * ThimbleProjects.org/gotoloop/127477/
     */
    
    static final char[] CHARS = { '+', '—', 'I', 'O', '+', 'C' };
    static final int LEN_L1 = CHARS.length - 1;
    static final int LEN_P1 = CHARS.length + 1;
    
    static final int OFFSET = 18, OFFSET3 = OFFSET*3, FPS = 60;
    static final float INC = .006;
    static final color BG = -1;
    static final boolean IS_JAVA = 1/2 != 1/2.;
    
    int xwOff, yhOff;
    float z;
    
    void setup() {
      size(500, 700, IS_JAVA? FX2D : JAVA2D);
      if (IS_JAVA)  pixelDensity(displayDensity());
    
      smooth(3);
      frameRate(FPS);
    
      noStroke();
      fill(0);
      textAlign(CENTER, CENTER);
    
      xwOff = width  - OFFSET*2;
      yhOff = height - OFFSET*2;
    }
    
    void draw() {
      background(BG);
    
      float ny = (float) OFFSET3/yhOff;
      z += INC;
    
      for (int y = OFFSET3; y < yhOff; ny = (float) (y += OFFSET)/yhOff)
        for (int x = OFFSET3; x < xwOff; x += OFFSET) {
          final float nz = noise(z, (float) x/xwOff, ny);
          final int idx = min((int) (nz*LEN_P1), LEN_L1);
          text(CHARS[idx], x, y);
        }
    }
    
  • edited March 2019

    Now the p5.js itself. It can be watched running online at the link below too: :bz
    http://p5js.SketchPad.cc/sp/pad/view/ro.G$G4q68Ayur/latest

    index.html:

    <script async src=http://p5js.org/assets/js/p5.min.js></script>
    <script defer src=NoisyCharGrid.js></script>
    

    NoisyCharGrid.js:

    /**
     * Noisy Char Grid (v2.3.1)
     * by  AlexDontSurf (2016-Aug-31)
     * mod GoToLoop
     *
     * Forum.Processing.org/two/discussion/18026/text-array-in-p5js#Item_13
     * p5js.SketchPad.cc/sp/pad/view/ro.CEAew8yiEGaOO8/latest
     *
     * Forum.Processing.org/two/discussion/18859/running-p5-js-in-google-sites
     * ThimbleProjects.org/gotoloop/127477/
     */
    
    "use strict";
    
    const CHARS = [ '+', '—', 'I', 'O', '+', 'C' ],
          LEN_L1 = CHARS.length - 1, LEN_P1 = CHARS.length + 1,
          OFFSET = 18, OFFSET3 = OFFSET*3, FPS = 60, INC = .006;
    
    let bg, xwOff, yhOff, z = 0;
    
    function setup() {
      createCanvas(500, 700);
      pixelDensity(displayDensity());
    
      frameRate(FPS).noStroke().fill(0);
      textAlign(CENTER, CENTER).textStyle(BOLD);
    
      bg = color(255), xwOff = width - OFFSET*2, yhOff = height - OFFSET*2;
    }
    
    function draw() {
      background(bg);
      z += INC;
    
      for (let y = OFFSET3, ny = y/yhOff; y < yhOff; ny = (y += OFFSET)/yhOff)
        for (let x = OFFSET3; x < xwOff; x += OFFSET) {
          const nz = noise(z, x/xwOff, ny), idx = min(nz*LEN_P1 | 0, LEN_L1);
          text(CHARS[idx], x, y);
        }
    }
    
Sign In or Register to comment.