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