# Question about TexttoPoint()

**URL:** https://discourse.processing.org/t/question-about-texttopoint/27627
**Category:** Beginners
**Created:** [February 6, 2021, 11:56am UTC](https://discourse.processing.org/t/question-about-texttopoint/27627 "2021-02-06T11:56:27Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![kmn063836](https://avatars.discourse-cdn.com/v4/letter/k/dc4da7/32.png) [@kmn063836](https://discourse.processing.org/u/kmn063836)
#### Post date: [February 6, 2021, 11:56am UTC](https://discourse.processing.org/t/question-about-texttopoint/27627/1 "2021-02-06T11:56:27Z")

</div>

Hi, I have a question about TexttoPoint() in p5.js.

Is there a way to set/limit the number of points that draw the letter?

For example, I’d like to draw both letters ‘A’ and ‘B’ only with 10 points but not sure how… (Using the option sampleFactor creates points based on path-length so ‘A’ and ‘B’ would different number of points). Or would there be a way to do this using something other than TexttoPoint()?

I’d really appreciate any help!

---

<div class="post-metadata">

### Author: ![CodeMasterX](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/codemasterx/32/2942_2.png) [@CodeMasterX](https://discourse.processing.org/u/CodeMasterX)
#### Post date: [February 6, 2021, 12:18pm UTC](https://discourse.processing.org/t/question-about-texttopoint/27627/2 "2021-02-06T12:18:07Z")

</div>

[https://p5js.org/reference/#/p5.Font/textToPoints](https://p5js.org/reference/#/p5.Font/textToPoints)

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/d/d7e2338dd243d5b7e91988894fd389ac5eaf8673.png)

---

<div class="post-metadata">

### Author: ![kmn063836](https://avatars.discourse-cdn.com/v4/letter/k/dc4da7/32.png) [@kmn063836](https://discourse.processing.org/u/kmn063836)
#### Post date: [February 6, 2021, 1:01pm UTC](https://discourse.processing.org/t/question-about-texttopoint/27627/3 "2021-02-06T13:01:49Z")

</div>

Hi, thanks for the reply but these options don’t achieve what I asked, or am I not understanding correctly? I’m new to programming so I’d appreciate if you could clarify?

---

<div class="post-metadata">

### Author: ![CodeMasterX](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/codemasterx/32/2942_2.png) [@CodeMasterX](https://discourse.processing.org/u/CodeMasterX)
#### Post date: [February 6, 2021, 1:15pm UTC](https://discourse.processing.org/t/question-about-texttopoint/27627/4 "2021-02-06T13:15:59Z")

</div>

```auto
pts = caslon.textToPoints('NYTimes', 0, 0, 120,{
    sampleFactor: 0.1, //the higher the number, the more detail
    simplifyThreshold: 0
  });

```

code reference (unmodified code)  
[https://editor.p5js.org/aferriss/sketches/B1BOfBdZX](https://editor.p5js.org/aferriss/sketches/B1BOfBdZX)

---

<div class="post-metadata">

### Author: ![kmn063836](https://avatars.discourse-cdn.com/v4/letter/k/dc4da7/32.png) [@kmn063836](https://discourse.processing.org/u/kmn063836)
#### Post date: [February 6, 2021, 1:30pm UTC](https://discourse.processing.org/t/question-about-texttopoint/27627/5 "2021-02-06T13:30:55Z")

</div>

Yes, I get that but ‘N’ and ‘Y’ from ‘NYTimes’ will still have different number of points, because sampleFactor changes the distance between the points rather than the number of points.

For example, I have ‘0’ and ‘4’ but they are drawn with different number of ellipses. How can I make sure both have the same number of ellipses? Please let me know if my question is unclear…

 ![Screen Shot 2021-02-06 at 9.28.42 PM](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/a/a65ce8d3ee5e3b47c751bf4efd32cd77ea7fc818.jpeg)

---

<div class="post-metadata">

### Author: ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)
#### Post date: [February 6, 2021, 10:27pm UTC](https://discourse.processing.org/t/question-about-texttopoint/27627/6 "2021-02-06T22:27:57Z")

</div>

Hi,

You have two possible solutions :

- Take an arbitrary large number for the `sampleFactor` parameter like `100` for both letters and take the quantity you want out of those arrays :

- Otherwise look at the [source code](https://github.com/processing/p5.js/blob/eb9b15a46dd2bd3c0e1396ec58c0cfdab6c52d93/src/typography/p5.Font.js#L233) and try to implement your own function 😉 :

```auto
p5.Font.prototype.textToPoints = function(txt, x, y, fontSize, options) {
  let xoff = 0;
  const result = [];
  const glyphs = this._getGlyphs(txt);

  function isSpace(i) {
    return (
      (glyphs[i].name && glyphs[i].name === 'space') ||
      (txt.length === glyphs.length && txt[i] === ' ') ||
      (glyphs[i].index && glyphs[i].index === 3)
    );
  }

  fontSize = fontSize || this.parent._renderer._textSize;

  for (let i = 0; i < glyphs.length; i++) {
    if (!isSpace(i)) {
      // fix to #1817, #2069

      const gpath = glyphs[i].getPath(x, y, fontSize),
        paths = splitPaths(gpath.commands);

      for (let j = 0; j < paths.length; j++) {
        const pts = pathToPoints(paths[j], options);

        for (let k = 0; k < pts.length; k++) {
          pts[k].x += xoff;
          result.push(pts[k]);
        }
      }
    }

    xoff += glyphs[i].advanceWidth * this._scale(fontSize);
  }

  return result;
};

```

---

<div class="post-metadata">

### Author: ![kmn063836](https://avatars.discourse-cdn.com/v4/letter/k/dc4da7/32.png) [@kmn063836](https://discourse.processing.org/u/kmn063836)
#### Post date: [February 7, 2021, 6:39am UTC](https://discourse.processing.org/t/question-about-texttopoint/27627/7 "2021-02-07T06:39:14Z")

</div>

Hi, Thank you for the reply! I tried the first code but nothing was showing up. Could it be that I have integrated it incorrectly to my code?

```auto
let grotesk;
let fontSize = 400;

let zeroArray;
let fourArray;

function preload() {
  grotesk = loadFont('grotesk.otf');
}

function setup() {
  createCanvas(windowWidth,windowHeight);
  textFont(grotesk);
	
	const options = {
  	sampleFactor: 100,
  	simplifyThreshold: 0
	}
	const nPoints = 20;
	
	zeroArray = grotesk.textToPoints("0",100,300,options).slice(0, nPoints);
	fourArray = grotesk.textToPoints("4",500,300,options).slice(0, nPoints);
}

function draw() {
	background(220);
  textSize (fontSize);
	noStroke();
	
	zero();
	
}

function zero() {
	
	for (let i = 0; i < zeroArray.length; i++){
		fill (random(255));
		ellipse(zeroArray[i].x,zeroArray[i].y,5,5);		
		}
	
	for (let i = 0; i < fourArray.length; i++){
		ellipse(fourArray[i].x,fourArray[i].y,5,5);
		fill (random(20));
		}

}

```

---

<div class="post-metadata">

### Author: ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)
#### Post date: [February 7, 2021, 4:47pm UTC](https://discourse.processing.org/t/question-about-texttopoint/27627/8 "2021-02-07T16:47:48Z")

</div>

Ok my bad, this is not the right solution but few things first :

- Be careful, you forgot the `fontSize` parameter in `textToPoints(txt, x, y, fontSize, [options])` so it wouldn’t work anyway.

- Calling `textSize(fontSize);` in the `draw()` function doesn’t affect the locations of the points generated by the `textToPoints` functions since we pass the font size in the parameters.

- If you intent is to draw points rather than circles or ellipses, I prefer using the `point()` function since it’s more clear and faster if you don’t need stroke.

So the code might go like this :

```auto
let grotesk;
const fontSize = 200;
const nPoints = 20;

let zeroArray;
let fourArray;

function preload() {
  grotesk = loadFont('grotesk.otf');
}

function setup() {
  createCanvas(windowWidth, windowHeight);

  textFont(grotesk);

  const options = {
    sampleFactor: 20,
    simplifyThreshold: 0
  }

  zeroArray = grotesk.textToPoints("0", 100, 300, fontSize, options);
  fourArray = grotesk.textToPoints("4", 500, 300, fontSize, options);

  console.log(zeroArray.length);
  console.log(fourArray.length);

  zeroArray = zeroArray.slice(0, nPoints);
  fourArray = fourArray.slice(0, nPoints);
}

function draw() {
  background(220);

  zero();

  noLoop();
}

function zero() {
  strokeWeight(5);

  for (let i = 0; i < zeroArray.length; i++) {
    const pt = zeroArray[i];

    stroke(random(255));
    point(pt.x, pt.y);
  }

  for (let i = 0; i < fourArray.length; i++) {
    const pt = fourArray[i];

    stroke(random(20));
    point(pt.x, pt.y);
  }
}

```

As you can see, I printed the number of points generated by the `textToPoints` function. With a fontSize of `40` this is the result :

```auto
zeroArray.length = 2953
fourArray.length = 3402

```

This is quite large! (`100` is too high for the detail)  
And the output on the screen only shows two points at the same location.

But my solution is not right because if you take the first `20` points of an array of `2953`, you only get the beginning of the contour of the letter. Because the number of points is large, we only get a tiny portion of the first points.

So the way to go is to take 20 points at equal interval in the array of points :

```auto
/**
 * Take nElements from array at constant interval
 */
function sampleFromArray(array, nElements) {
  const result = [];
  const increment = Math.ceil(array.length / nElements);

  for (let i = 0; i < array.length; i += increment) {
    result.push(array[i]);
  }

  return result;
}

```

So we are an array and a number of elements to sample and we first compute the increment between each elements in the array, for example :

```auto
array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; // length 10
nElements = 3;

increment = Math.ceil(10 / 3) = Math.ceil(3.333333...) = 4

// So we take
array[0], array[4], array[8]

```

We use `Math.ceil()` because it takes the lowest integer superior or equal to a certain number. But we could also use `Math.floor()` or `Math.round()`.

Note that the function is not really exact since if we wanted to take `7` elements from that array, the increment would be `Math.ceil(10 / 7) = 2` so the result wouldbe an array of `8` elements.

It doesn’t matter since we are dealing with large arrays anyway…

So now you can call :

```auto
zeroArray = sampleFromArray(zeroArray, nPoints);
fourArray = sampleFromArray(fourArray, nPoints);

```
