# Pattern Attractors

**URL:** <https://discourse.processing.org/t/pattern-attractors/2535>\
**Category:** Project Guidance\
**Created:** [August 10, 2018, 4:13pm UTC](https://discourse.processing.org/t/pattern-attractors/2535 "2018-08-10T16:13:02Z")\
**Posts on this page:** 2\
**Page:** 2

<div class="post-metadata">

**Author:** ![tony](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tony/32/949_2.png) [@tony](https://discourse.processing.org/u/tony)\
**Post date:** [August 16, 2018, 8:50pm UTC](https://discourse.processing.org/t/pattern-attractors/2535/21 "2018-08-16T20:50:57Z")

</div>

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

```auto
    // 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);
    }

```

---

<div class="post-metadata">

**Author:** ![jakejake](https://avatars.discourse-cdn.com/v4/letter/j/e495f1/32.png) [@jakejake](https://discourse.processing.org/u/jakejake)\
**Post date:** [August 16, 2018, 8:54pm UTC](https://discourse.processing.org/t/pattern-attractors/2535/22 "2018-08-16T20:54:30Z")

</div>

Ahh Thanks!

Here is the updated code

```auto
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);
    }
}

```

[Previous page](https://discourse.processing.org/t/pattern-attractors/2535.md?page=1)
