Wrong language or a syntax error? (axidraw)

As an axidraw user, I was very interested in LingDong’s procedurally-generated plotter landscape. He includes the source code at the end of the page. I believe he did this in processing.

I’m using Processing v3 in python mode. I guess his code is written in Java or Javascript, neither which I’m familiar with.

When I try to run his code in Processing 3 (setting it to ‘java’ mode), I get complaint about a syntax error in an obscure location.

in
for (int j = 0; jcos(iPI/10),loc[1]-(w/2)sin(iPI/10));

it complains

expecting SEMI, found ‘,’
Syntax error, maybe a missing semicolon?

Like I said, I don’t know Java or Javascript. So I am note sure if:

  1. this is a syntax error/typo
  2. this is not javascript or java or whatever ‘java mode’ is expecting
  3. there has been a dialect change? Perhaps the original code worked in Processing 2 but not in Processing 3?

The program is interesting enough to bother to read java(script) to understand it, but I want to know where the issue is before I run off an a wrong tangent. Can anyone advise?

Regards

1 Like

Comment the line out

Because of the ; at the end it’s doing nothing anyway

Yeah, thanks, I commented that out, which seemed to leave an extraneous } in the line below. Knocked that out too.

Then I suspected immediately below vertex(loc[0]+(w/2)-(w/3)cos(iPI/10),loc[1]-(w/3)sin(iPI/10)); should be vertex(loc[0]+(w/2)-(w/3)*cos(iPI/10),loc[1]-(w/3)*sin(iPI/10)); .

But then it decayed into a game of unmatched parens and braces.

So is this ‘javascript’ or ‘java’ that I’m reading. I suspect javascript. Perhaps the best course of action it to put it into a better ide and try to clean up the formatting, etc, and go through the effort of learning javascipt syntax. Enough interesting procgen stuff written in it, and it doesn’t look that hard…

Definitely processing, java flavor

Hello,
Have you opened the brackets after your “for” line?

As in:

for (int j = 0; jcos(iPI/10),loc[1]-(w/2)sin(iPI/10)) {
// your code
}

it seems that the blog system used destroyed some of the code; especially some of the *

takes a moment to show the first image

Chrisir

running code:


class Piece {
  Piece right;
  Piece up;
  Piece down;
  Piece left;
  int w;
  int h;
  float l;
  int typ;
  int[] dat;

  int row;
  int col;

  public Piece(int typ) {

    this.typ = typ;    
    this.l = random(1.0);
    if (typ == 0) {
      this.w = 50; 
      this.h = 20;
    } else if (typ == 1) {
      this.w = 15; 
      this.h = 120;

      this.l = ceil(random(2.0));
      if (this.l == 1) {
        this.l = 1;
      } else {
        this.l = random(1.0);
      }
    } else if (typ == 2) {
      this.w = 50; 
      this.h = 30;
    } else if (typ == 3) {
      this.w = 60; 
      this.h = 30;
    } else if (typ == 4) {
      this.w = 50; 
      this.h = 120;
    }
    //grow();
  }

  public int[] locPiece() {
    if (left == null && down == null) {
      return new int[] {0, 0};
    } else if (left != null) {
      return new int[] {left.locPiece()[0]+left.w, left.locPiece()[1]};
    } else {
      return new int[] {down.locPiece()[0], down.locPiece()[1]-down.h};
    }
  }
  public void gr(int n) {
    //println(col);
    if (col < random(1.0)*20) {
      right = new Piece(n);
      right.left = this;
      right.col = col + 1;
      right.row = row;
      right.grow();
    }
  }
  public void gu(int n) {
    if (row < random(1.0)*4) { 
      up = new Piece(n); 
      up.down = this; 
      up.col = col; 
      up.row = row+1; 
      up.grow();
    }
  } 
  public void grow() { 
    if (typ == 0) { 
      gr(0); 
      if (random(1.0)>0.5) {
        gu(1);
      } else {
        gu(4);
      }
    }
    if (typ == 1) {
      if (l == 1) {
        if (random(1.0)>0.1) {
          gu(2);
        } else {
          gu(3);
        }
      }
    }
    if (typ == 2) {
      if (random(1.0)>0.2) {
        gu(1);
      } else {
        gu(4);
      }
    }
  }


  public void drawPiece() {
    int[] loc = locPiece();
    //println(loc);
    if (typ == 0) {
      fill(200, 210);//floor(random(2.0))*180+20);
      stroke(0);
      rect(loc[0]-5, loc[1]-h, w+10, h);
    } else if (typ == 1) {
      int mseg = 5;

      int seg = ceil(l*mseg);
      pushMatrix();
      translate(10, 0);
      for (int i = 0; i< seg; i++) {
        noStroke();
        fill(220);
        rect(loc[0], loc[1]-(i+1)*h/mseg, w, h/mseg);
        //for (int j = 0; jcos(iPI/10), loc[1]-(w/2)sin(iPI/10)) {
      }
      for (int i = 0; i < 11; i++) {
        vertex(
          loc[0]+(w/2)-(w/3)*cos(i*PI/10), 
          loc[1]-(w/3)*sin(i*PI/10)
          );
      }     //rect(loc[0],loc[1]-h,w,h);
      endShape(CLOSE);
      strokeWeight(1);

      popMatrix();
    } else if (typ == 4) {
      fill(30);

      //rect(loc[0]-4,loc[1]-h,w+8,h);

      for (int i = 0; i < w; i++) {
        float nz = noise(0.005*(loc[0]+i), loc[1]);
        //stroke(20);//+ noise(0.1(loc[0]+i))20);
        noStroke();
        fill(20, 120);
        rect(loc[0]+i, loc[1]-h*nz, 2, h*nz);
        fill(0);
        rect(loc[0]+i, loc[1]-h*nz-2, 2, 2);
      }
    }
    if (right != null) {
      right.drawPiece();
    }
    if (up != null) {
      up.drawPiece();
    }
  }
}// class ? 


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



void setGradient(int x, int y, float w, float h, color c1, color c2, int axis ) {
  int Y_AXIS = 1;
  int X_AXIS = 2;
  //noFill();
  noStroke();
  if (axis == Y_AXIS) {  // Top to bottom gradient
    for (int i = y; i <= y+h; i++) {
      float inter = map(i, y, y+h, 0, 1);
      color c = lerpColor(c1, c2, inter);
      fill(c);
      rect(x, y, w, 1);
    }
  } else if (axis == X_AXIS) {  // Left to right gradient
    for (int i = x; i <= x+w; i++) {
      float inter = map(i, x, x+w, 0, 1);
      color c = lerpColor(c1, c2, inter);
      fill(c);
      rect(i, y, 1, h);
    }
  }
}

ArrayList Lines=new ArrayList();
int[] Epts;
PImage img;
int[][][] Vmap;

void tree(float x, float y, float a, float o, float l, int depth) {
  if (depth > 0) {
    float x1 = x + l*cos(a-o);
    float y1 = y + l*sin(a-o);
    float x2 = x + l*cos(a+o);
    float y2 = y + l*sin(a+o);
    strokeWeight(1);
    stroke(random(1.0)*255);
    line(x, y, x1, y1);
    line(x, y, x2, y2);
    tree(x1, y1, a-o, o, l*0.6, depth-1);
    tree(x2, y2, a+o, o, l*0.6, depth-1);
  }
}

void tree2(float x, float y, float l, int depth) {
  if (depth > 0) {
    float x1 = x;
    float y1 = y-l;
    strokeWeight(1);
    stroke(0, 0, 0);
    tree(x1, y1, -PI, PI/16, l, 2);
    tree(x1, y1, 0, PI/16, l, 2);
    line(x, y, x1, y1);
    tree2(x1, y1, l*0.8, depth-1);
  }
}

void noisefill(int[][][] vm) {
  for (int i = 0; i < vm.length; i++) {
    for (int j = 0; j < vm[i].length; j++) {
      vm[i][j][0] = parseInt(noise(0.01*i, 0.004*j)*255);
    }
  }
}

void scanimg(int[][][] vm) {
  //image(img,0,0);
  for (int i = 0; i < vm.length; i++) {
    for (int j = 0; j < vm[i].length; j++) {

      vm[i][j][0] = parseInt((red(get(j+dx, i+dy))+green(get(j+dx, i+dy))+blue(get(j+dx, i+dy)))/3);
    }
  }
}

void genterr(int[][][] vm) {
  for (int i = 450; i < vm.length*2; i+=50) {
    float hl = 0;
    for (int j = 0; j < vm[0].length; j++) {
      float nz0 = noise(0.005*i, 0.001*j);
      float nz1 = noise(0.1*i, 0.005*j);
      float nz2 = noise(0.1*i, 0.05*j, 200);
      //stroke(map(i,0,vm.length,0,255));
      //line(j,i,j,i-nz*100);
      float h;
      if (i < vm.length*0.9) {
        h = nz0*500+nz1*200+nz2*20;
      } else if (i < vm.length*0.95) {
        h = 0;
      } else {
        h = 200+nz0*200+nz1*40+nz2*4;
      }
      for (int k = 0; k < h; k++) { 
        float nz3 = noise(0.1*i, 0.1*j, 0.1*k); 
        if (k > 2.0*h*noise(0.005*i, 0.001*(j+1000))) {
          if (i < vm.length*0.9) {
            fill(constrain(parseInt(map(k, h/2, h, 0, 300) * (0.9+0.1*((1-k/h)+(k/h)*nz3))*i/vm.length), 0, 255));
          } else {
            fill(constrain(
              parseInt(map(k, h/2, h, 0, 250)*(0.8+0.2*((1-k/h)+(k/h)*nz3))*i/vm.length), 0, 255
              ));
            //fill(0,0);
          }
        } else {
          if (i < vm.length*0.9) { 
            fill(constrain(parseInt(map(k, h/2, h, 0, 80)*(0.1+0.9*((1-k/h)+(k/h)*nz3))*i/vm.length), 0, 255));
          } else { 
            fill(constrain(parseInt(map(k, h/2, h, 0, 120)*(0.1+0.9*((1-k/h)+(k/h)*nz3))*i/vm.length), 0, 255));
            //fill(0,0);
          }
        } 
        noStroke(); 
        rect(j, i-k, 1, 1); 
        if (random(1) > 0.99 && k < h*0.7 && k > h*0.5 && i < vm.length*0.8) { 
          tree2(j, i-k, 5+5*random(1.0), 5);
        }
      } 
      fill(200); 
      if (random(1) > 0.5) {
        rect(j, i-h, 1, 1);
      }
      if (random(1) > 0.9) {
        //tree2(j,i-h0.9,5+5random(1.0),5);
      }


      hl = h;
    }
    for (int j = 0; j < vm[0].length; j++) { 
      float h = 400; 
      if (random(1) > 0.9995 && i > vm.length*1.0 && i < vm.length*1.2) {
        Piece p = new Piece(0);
        p.grow();
        pushMatrix();
        translate(j, i-h*random(0.7, 0.9));
        scale(0.0+3*(i-vm.length*0.9)/(vm.length*1.1));

        p.drawPiece();
        popMatrix();
      }
    }
  }
}

void levelfygrc(int[][][] vm) {
  for (int i = 0; i < vm.length; i++) {
    for (int j = 0; j < vm[i].length; j++) {
      vm[i][j][1] = max(parseInt(map(vm[i][j][0], 0, 255, 1, 20))*2, 1);
      //println(vm[i][j][1]);
      //vm[i][j][1] = 2*parseInt(255/max(1,vm[i][j][0]));
    }
  }
}

int[] getedgepts(int[][][] vm) {
  int[] epts = new int[width*height*2];
  epts[0] = 1;
  for (int i = 0; i < vm.length; i++) {
    for (int j = 0; j < vm[i].length; j++) {
      if (j==0 || vm[i][j-1][1] != vm[i][j][1]) {
        epts[epts[0]] = i;
        epts[epts[0]+1] = j;
        epts[0] += 2;
      }
    }
  }  
  return epts;
}

void shade(int[][][] vm, int[] epts) {

  for (int i = 1; i < epts[0]; i+=2) {
    if (epts[i]%vm[epts[i]][epts[i+1]][1]==0) {
      int[] l = new int[4];
      l[1] = epts[i];
      l[0] = epts[i+1];
      for (int j = 0; j < width; j++) {
        if (epts[i+1]+j==vm[0].length-1
          //||epts[i]+j==vm.length-1
          ||vm[epts[i]][epts[i+1]+j][1] != vm[epts[i]][epts[i+1]][1]
          ) {
          l[3] = epts[i];
          l[2] = epts[i+1]+j;
          //stroke(0,255,0,200);
          //line(l[0],l[1],l[2],l[3]);
          float d = dist(l[0], l[1], l[2], l[3]);
          int[] w = wiggle(l, max(parseInt(0.1*d), 1), parseInt(vm[epts[i]][epts[i+1]][1]/2));
          for (int k = 2; k < w.length-1; k+=2) { 
            int[] nl = new int[4]; 
            nl[0] = w[k-2]; 
            nl[1] = w[k-1]; 
            nl[2] = w[k]; 
            nl[3] = w[k+1]; 
            if (random(10) > 0.0001*pow(vm[epts[i]][epts[i+1]][1], 3)) {
              Lines.add(nl);
            }
          }

          Lines.add(l);
          break;
        }
      }
    }
  }
}


int[] wiggle(int[] l, int p1, int p2) {
  //int d = parseInt(dist(l[0],l[1],l[2],l[3])/p1);
  if (p2 == width) {
    p2 = 0;
  }
  int[] ls = new int[p1*2+2];
  for (int i = 0; i < p1+1; i++) {
    ls[i*2] = l[0] + i*(l[2]-l[0])/p1;
    ls[i*2+1] = l[1] + i*(l[3]-l[1])/p1;

    ls[i*2] += parseInt(noise(0.1*ls[i*2]/p1, ls[i*2+1], 10)*p2-p2/2);
    ls[i*2+1] += parseInt(noise(0.1*ls[i*2]/p1, ls[i*2+1], 100)*p2-p2/2);
  }

  return ls;
}


int dx = 50;
int dy = 40;


import processing.pdf.*;
boolean bRecordingPDF;
int pdfOutputCount = 0; 


void setup() {
  size(1060, 820);
  background(0);


  Vmap = new int[height-100][width-100][2];
  //noisefill(Vmap);
  translate(dx, dy);
  genterr(Vmap);

  scanimg(Vmap);

  levelfygrc(Vmap);
  Epts = getedgepts(Vmap);

  shade( Vmap, Epts);
  noLoop();
}


void draw() {
  beginRecord(PDF, ""+parseInt(floor(random(1000000000)))+".pdf");

  background(255);

  translate(dx, dy);


  for (int i = 1; i < Epts[0]; i+=2) {
    stroke(0);
    strokeWeight(1);
    noFill();
    line(Epts[i+1], Epts[i], Epts[i+1], Epts[i]);
  }


  println(Lines.size());
  for (int i = 0; i < Lines.size(); i++) {

    stroke(0);
    strokeWeight(1);
    int[] c1 = (int[]) Lines.get(i);  
    line(c1[0], c1[1], 
      c1[2], c1[3]);
  }

  endRecord();
}
//
2 Likes

Oh wow cool. Maybe it was misreading it as markdown. Your version worked. I changed it to export SVG instead of PDF (so i can print on my AxiDraw) but boy, a 7.5mb SVG has Inkscape on its knees right now. There must be a tons of individual vector objects in here.

1 Like

I generated an image with this script last night, and sent it to the AxiDraw A4-sized when I went to bed. Got up this morning and my wife said, “1. you forgot to turn off the aircon in the study, 2. your plotter is plotting”. Hahaha 8 hours later, still stipling! The poor pen-up servo of my AxiDraw…

1 Like

Thanks for the pointer to LingDong, awesome!

I am doing something related, using my 3D printer as a plotter. Lifts the whole bridge&printhead to move the pen…rattle.
I’m going to some length im path optimization & double line elimination and generate gcode directly. Programm not presentable yet

Btw I recommend Ball Pentel pens, I use them since 1984 (really!), fine line, handles high speeds well, cheap, reliable, availsable, can be uncapped for days, …

Will keep you posted

would love to see a photo of this art…

This is the StuxNet picture that ultimately destroyed my pen-lift servo. Not that great of a picture in the first place plus I used a gel-ink pen, which is undependable for making stiples. It doesn’t always leave a mark.

2 Likes