# Pattern Attractors

@jakejake Take a good long look at this part of your code.

``````    // Normalize distances for later scaling
float[] distNormed = new float[distances.length];
for(int dn = 0; dn < distances.length; dn++){
distNormed[dn] = map(dn,min(distances),max(distances),0.0,1.0);
}
``````
2 Likes

Ahh Thanks!

Here is the updated code

``````int X = 25;
int Y = 25;
int n = 4;

PVector[] ellipsePositions = new PVector[X*Y];
PVector[] curvePoints = new PVector[n];
PVector[] interpolations;

void setup(){
size(400,400);
background(255);
noFill();
rectMode(CENTER);

float spaceX = 1.0*width/X;
float spaceY = 1.0*height/Y;

for(int i = 0; i < X; i++){
for(int j = 0; j < Y; j++){
ellipsePositions[(i*Y)+j] = new PVector(i*spaceX,j*spaceY);
}
}

for(int p = 0; p < n; p++){
curvePoints [p] = new PVector(1.0*p*width/float(n),random(height));
}

int resolution = 50;
interpolations = new PVector[resolution];

for(int r = 0; r < resolution; r++){
interpolations[r] = lerpVectors(curvePoints, 1.0*r/(resolution));
}

// Get distances
float[] distances = new float[ellipsePositions.length];

for(int pt = 0; pt < ellipsePositions.length; pt++){
float[] d = new float[interpolations.length];

// Get all distances to curve points
for(int j = 0; j < interpolations.length; j++){
d[j] = PVector.dist(ellipsePositions[pt],interpolations[j]);
}
// Get minimum distance (closest point to curve)
distances[pt] = min(d);
}

// Normalize distances for later scaling
float[] distNormed = new float[distances.length];
for(int dn = 0; dn < distances.length; dn++){
distNormed[dn] = map(distances[dn],min(distances),max(distances),0.0,1.0);
}
// Display curve
beginShape();
for (PVector i : interpolations){
vertex(i.x,i.y);
}
endShape();

// Display ellipses
for(int j = 0; j < ellipsePositions.length; j++){
float diameter = distNormed[j]*spaceX;
//println(distNormed[j]);
fill(0);
noStroke();
ellipse(ellipsePositions[j].x, ellipsePositions[j].y,diameter,diameter);
noFill();
stroke(0);
rect(ellipsePositions[j].x, ellipsePositions[j].y,spaceX,spaceX);
}
}

PVector cosineLerpVec(PVector v1, PVector v2, float amt){
float x = lerp(v1.x,v2.x,amt);
float y = cosineLerp(v1.y,v2.y,amt);
return new PVector(x,y);
}

float cosineLerp(float y1, float y2, float mu){
float mu2 = (1-cos(mu*PI))/2;
return y1*(1-mu2)+y2*mu2;
}

PVector lerpVectors(PVector[] vecs, float amt){ //amt is lerp position from resolution
if(vecs.length==1){
return vecs[0];
}

float spacing = 1.0/(vecs.length-1); //dist between two points
int lhs = floor(amt / spacing); //find position start?
int rhs = ceil(amt / spacing); // find position end?

try{
return cosineLerpVec(vecs[lhs], vecs[rhs], amt%spacing/spacing);
}
catch(Exception  e){
return cosineLerpVec(vecs[constrain(lhs, 0, vecs.length-2)], vecs[constrain(rhs, 1, vecs.length-1)], amt);
}
}
``````
2 Likes