Geomerative text question

Hi everyone !

I have a question about Geomerative library.

When I am drawing my shape with curveVertex, I can’t control my fill function.

Can anyone help me ?

My code is :point_down:

import geomerative.*;
RFont f;
RShape grp;
RPoint[] pts;
RPoint[][] pointPaths;

void setup() {
  size(900, 900);
  RG.init(this);

  grp = RG.getText("Belli", "aktif.ttf", 200, CENTER);
}

void draw() {
  background(255);
  strokeWeight(2);
  RG.setPolygonizer(RG.UNIFORMLENGTH);
  pts = grp.getPoints();
  pointPaths = grp.getPointsInPaths();

  translate(300, 160);
  fill(0, 0, 0);
  noStroke();
  for (int i = 0; i< pts.length; i++) {
    fill(0);
    ellipse(pts[i].x, pts[i].y, 2, 2);
  }

  translate(0, 200);
  beginShape(POINTS);
  stroke(0);
  for (int i = 0; i< pts.length; i++) {
    vertex(pts[i].x + sin(frameCount*0.05 + pts[i].y*0.1)*5, pts[i].y);
  }
  endShape();

  translate(0, 200);

  for (int i = pointPaths.length-1; i >= 0; i--) {
    if (pointPaths[i] != null) {
      beginShape();
      for (int j = pointPaths[i].length-1; j >= 0; j --) {
        curveVertex(pointPaths[i][j].x + sin(frameCount*0.05 + pointPaths[i][j].y*0.1)*5, pointPaths[i][j].y);
      }
      endShape(CLOSE);
    }
  }


  translate(0, 200);
  for (int i =0; i< pts.length; i++) {
    line(pts[i].x, pts[i].y, pts[i].x + random(-15, 15), pts[i].y + random(-15, 15));
  }
}

and my result is :point_down:


I appreciate any help, thanks !

I also failed when trying this. When you set frameRate(.1); and observe it with a loop, you’ll notice that the shape doesn’t close actually. I guess the workaround will be placing a regular filled shape behind it.

Thanks for your reply !
So, it is not possible to control fill() function ?
Can’t I get normal letters with transparent holes ?

Yeah, something like this.

Edit: I now saw you wrote ‘curveVertex’, that would be the third one.
I modified the code, but nr 3 isn’t of course what you want.

import geomerative.*;
RFont f;
RShape grp;
RShape grp2;
RPoint[] pts;
RPoint[][] pointPaths;

void setup() {
  size(900, 900);
  RG.init(this);
  grp2 = RG.getText("Belli", "FreeSans.ttf", 200, CENTER);
  grp = RG.getText("Belli", "FreeSans.ttf", 200, CENTER);
}

void draw() {
  background(255);
  strokeWeight(2);
  RG.setPolygonizer(RG.UNIFORMLENGTH);
  pts = grp.getPoints();
  pointPaths = grp.getPointsInPaths();
  translate(300, 160);
  fill(0, 0, 0);
  noStroke();
  for (int i = 0; i< pts.length; i++) {
    fill(0);
    ellipse(pts[i].x, pts[i].y, 2, 2);
  }
  translate(0, 200);
  beginShape(POINTS);
  stroke(0);
  for (int i = 0; i< pts.length; i++) {
    vertex(pts[i].x + sin(frameCount*0.05 + pts[i].y*0.1)*5, pts[i].y);
  }
  endShape();
  translate(0, 200);
  noStroke(); 
  fill(255, 0, 0);
  grp.draw();
  noFill();
  stroke(0);
  for (int i = pointPaths.length-1; i >= 0; i--) {
    if (pointPaths[i] != null) {
      beginShape();
      for (int j = pointPaths[i].length-1; j >= 0; j --) {
        curveVertex(pointPaths[i][j].x + sin(frameCount*0.05 + pointPaths[i][j].y*0.1)*5, pointPaths[i][j].y);
      }
      endShape(CLOSE);
    }
  }
  translate(0, 200);
  noStroke();
  fill(255, 0, 0);
  grp.draw();
  stroke(0);
  for (int i =0; i< pts.length; i++) {
    line(pts[i].x, pts[i].y, pts[i].x + random(-15, 15), pts[i].y + random(-15, 15));
  }
}

Far-fetched workaround for No. 3.but …

import geomerative.*;
import java.awt.Point;
import java.util.Queue;
import java.util.LinkedList;

PImage img;
RFont f;
RShape grp;
RShape grp2;
RPoint[] pts;
RPoint[][] pointPaths;

void setup() {
  size(450, 250);
  RG.init(this);
  grp = RG.getText("Belli", "FreeSans.ttf", 200, CENTER);
}

void draw() {
  background(255);
  strokeWeight(2);
  RG.setPolygonizer(RG.UNIFORMLENGTH);
  pts = grp.getPoints();
  pointPaths = grp.getPointsInPaths(); 
  translate(200, 200);
  noFill();
  stroke(0);
  for (int i = pointPaths.length-1; i >= 0; i--) {
    if (pointPaths[i] != null) {
      beginShape();
      for (int j = pointPaths[i].length-1; j >= 0; j --) {
        curveVertex(pointPaths[i][j].x + sin(frameCount*0.05 + pointPaths[i][j].y*0.1)*5, pointPaths[i][j].y);
      }
      endShape(CLOSE);
    }
  }
  img = get();
  fillShape(50, 60);
  fillShape(200, 100);
  fillShape(291, 79);
  fillShape(336, 168);
  fillShape(381, 61);
  fillShape(381, 61);
  fillShape(381, 174);
  image(img, -200, -200, width, height);
}

void fillShape(int x, int y) { 
  img.loadPixels(); 
  Queue<Point> queue = new LinkedList<Point>();
  queue.add(new Point(x, y));
  while (!queue.isEmpty()) {
    Point p = queue.remove();
    if (check(p.x, p.y)) {     
      queue.add(new Point(p.x, p.y-1)); 
      queue.add(new Point(p.x, p.y+1)); 
      queue.add(new Point(p.x-1, p.y)); 
      queue.add(new Point(p.x+1, p.y));
    }
  }
  img.updatePixels();
}

boolean check(int x, int y) {
  if (x < 0 || y < 0 || y >= img.height || x >= img.width) return false;
  int pp = img.pixels[x+(y*img.width)];
  if (pp != color(255)) return false; 
  img.pixels[x + (y * img.width)] = color(0, 167, 230); 
  return true;
}

Image 22

Hi,

I am not sure to understand, you would like to fill (or not fill) the word you are drawing with curveVertex(), right ?

If so, just change fill(0, 0, 0) to the color of your choice or replace it by noFill()

import geomerative.*;
RFont f;
RShape grp;
RPoint[] pts;
RPoint[][] pointPaths;

void setup() {
  size(900, 900);
  strokeWeight(2);
  noFill();
  
  RG.init(this);

  grp = RG.getText("Belli", "Roboto-Black.ttf", 200, CENTER);
  RG.setPolygonizer(RG.UNIFORMLENGTH);
  pts = grp.getPoints();
  pointPaths = grp.getPointsInPaths();
  
}

void draw() {
  background(255);
  
  translate(300, 160);
  for (int i = 0; i< pts.length; i++) {
    point(pts[i].x, pts[i].y);
  }

  translate(0, 200);
  for (int i = 0; i< pts.length; i++) {
    point(pts[i].x + sin(frameCount*0.05 + pts[i].y*0.1)*5, pts[i].y);
  }

  translate(0, 200);
  for (int i = pointPaths.length-1; i >= 0; i--) {
    if (pointPaths[i] != null) {
      beginShape();
      for (int j = pointPaths[i].length-1; j >= 0; j --) {
        curveVertex(pointPaths[i][j].x + sin(frameCount*0.05 + pointPaths[i][j].y*0.1)*5, pointPaths[i][j].y);
      }
      endShape(CLOSE);
    }
  }


  translate(0, 200);
  for (int i =0; i< pts.length; i++) {
    line(pts[i].x, pts[i].y, pts[i].x + random(-15, 15), pts[i].y + random(-15, 15));
  }
}

Also, according to the dedicated reference page curveVertex() should normally begin with the first vertex being written 2 times and end with the last one specified 2 times as well.

The inner holes will also be filled, if you flll() it. That’s the problem.

1 Like

Oh I see, thank you for the clarifiaction.

I believe that is because Geomerative provides the array of points without indicating which one is at the beginning or at the end of the inner hole(s). I guess OP would have to find them manually and treat each hole individually either:

  • with beginContour()/endContour() (in combination with curveVertex())
  • by calling curveVertex() first on the outline and then for each hole inside the letter, filling them in white
1 Like