This week we’re learning about vectors. I decided to take my array of constrained random walkers from last week (Genuary day 29) and convert the positions into vectors. I was unable to convert it 1:1, but along the way I found some really interesting surprises - this time the emergent patterns were even more apparent compared to last week. Here are my findings…
So I started out by replacing my x, y initialisations in the Walker class with createVector(x, y)
.
//previous code
class Walker {
constructor(x, y, size) {
this.x = x
this.y = y
this.startX = x
this.startY = y
this.size = size
}
//new vector code
class Walker {
constructor(x, y, size) {
this.position = createVector(x, y)
this.startPosition = createVector(x, y)
this.size = size
}
Neat!
The update()
method came next -
I decided to make an array of [-stepSize, 0, stepSize]
and use it to create a stepVector
//previous code
update() {
let stepX = random([-stepSize, 0, stepSize])
let stepY = random([-stepSize, 0, stepSize])
this.x = constrain(this.x + stepX, this.startX - this.size, this.startX + this.size)
this.y = constrain(this.y + stepY, this.startY - this.size, this.startY + this.size)
//new vector code
update() {
let stepArray = [-stepSize, 0, stepSize];
this.step = createVector(random(stepArray), random(stepArray));
this.position.add(this.step);
Once again, neat!
But next comes the implementation of the constrain, which is where things get interesting. I initially implemented the constrain so that the movement of the squares are limited to be within a margin, giving a nice framing for the piece. To do this, I applied the constrain separately to x, y.
From the textbook, I noticed vectors have a limit()
function which constrains the magnitude of the vector. Although this only takes one input, whereas constrain()
takes start and end limits.
So just to start out, I ignored my start limit and applied the simple limit() function to my position vector. The result was unexpected.
//old constrain()
this.x = constrain(this.x + stepX, this.startX - this.size, this.startX + this.size)
this.y = constrain(this.y + stepY, this.startY - this.size, this.startY + this.size)
//new limit()
this.position.limit(this.startPosition.x + this.size);
This gave me an unexpected start position of my squares, because I was expecting a grid. After I let it play out for a while, it started to make more sense as the squares were arranging themselves in a concentric circular pattern. The limit()
function was limiting the magnitude, regardless of the direction. Which shape has an equal magnitude in all directions? A circle!
This is where I pivoted from replicating the original grid sketch towards exploring this new pattern I’m seeing. I adjusted translate()
in my draw loop to center my circles. I also adjusted the acceleration for my stepSize increment in draw loop to see the pattern quicker.
I still wanted a margin around my sketch, so I tried to simplify and replace the limit()
parameter with my current margin (set to width/4
).
//simplified limit
this.position.limit(margin);
It gave me my margin, but if I let it play out, I started to see some more intricate patterns show up.