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 :
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 :
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 :
/**
* 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 :
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 :
zeroArray = sampleFromArray(zeroArray, nPoints);
fourArray = sampleFromArray(fourArray, nPoints);