Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This example uses a curve as the reactor object. The curve is subdivided into several points, and those points used in the similar way as the previous reactor examples.

...

Code Block
intvar NDIVS = 100; // # of subdivisions, higher is more accurate, but slower, and vice versa
var cps PVector= [] cps; // curve controll points
intvar gridWidth = 30; 
intvar gridHeight = 30; 
floatvar shapeWidth = 19; 
floatvar shapeHeight = 19; 
floatvar reactorScaler = 0.006;

voidfunction setup() {
  sizecreateCanvas(500,500);
  smooth();


 cps
= new PVector[4];
  for (intvar i=0; i<4; i++) {
    cps[i] = new PVector(createVector(0,0);
  }
  cps[0].x = width+300;
  cps[0].y = -500;
  cps[1].x= 50;
  cps[1].y= 50;
  cps[2].x= width-50;
  cps[2].y= height-50;
  cps[3].x= -500;
  cps[3].y= height+300;
}
 
voidfunction draw() {
  background(255);
  drawGeometry();
}
 
voidfunction drawGeometry() {
  stroke(255,0,0);
  noFill();
  curve(cps[0].x,cps[0].y, cps[1].x,cps[1].y, cps[2].x,cps[2].y, cps[3].x,cps[3].y);
  
  
  // uncomment if you want to manipulate curve (BUT BE CAREFUL, it's heavy!)
  /*
  for (let pt of cps) {
  	ellipse(pt.x, pt.y, 20, 20);
  }
  
  if (mouseIsPressed) {
    for (let pt of cps) {
      if (dist(mouseX, mouseY, pt.x, pt.y) < 20) {
        pt.x = mouseX;
        pt.y = mouseY;
        break;
      }
    }
  }
  */
  
  fill(0);
  noStroke();
for(intvar i = 0; i<gridWidth; i++ ) {
      for(intvar j = 0; j<gridHeight; j++ ) {
         
                    PVector var myPos = new PVectorcreateVector(i*shapeWidth, j*shapeHeight);
          PVectorvar cpt = ClosestPointOnCatmullRom(cps,myPos,NDIVS);
          floatlet reactorDistance = dist(cpt.x, cpt.y, myPos.x, myPos.y);
          floatlet scaler = reactorDistance*reactorScaler;
          //translate(posX, posY);
 
   
          ellipse(myPos.x, myPos.y, shapeWidth*scaler, shapeHeight*scaler);
      };
  };

}
 

 // see http://davebollinger.org/category/code/
/**
 * Returns the closest point on a catmull-rom curve relative to a search location.
 * This is only an approximation, by subdividing the curve a given number of times.
 * More subdivisions gives a better approximation but takes longer, and vice versa.
 * No concern is given to handling multiple equidistant points on the curve - the
 *   first encountered equidistant point on the subdivided curve is returned.
 *
 * @param cps    array of four PVectors that define the control points of the curve
 * @param pt     the search-from location
 * @param ndivs  how many segments to subdivide the curve into
 * @returns      PVector containing closest subdivided point on curve
 */
PVectorfunction ClosestPointOnCatmullRom(PVector [] cps, PVector pt, int steps) {
  PVectorvar result = new PVector(createVector(0,0);
  floatvar bestDistanceSquared = 0;
  floatvar bestT = 0;
  for (intvar i=0; i<=steps; i++) {
    floatlet t = (float)(i) / (float)(steps);
    floatlet x = curvePoint(cps[0].x,cps[1].x,cps[2].x,cps[3].x,t);
    floatlet y = curvePoint(cps[0].y,cps[1].y,cps[2].y,cps[3].y,t);
    floatlet dissq = dist(pt.x, pt.y, x, y);
    if (i==0 || dissq < bestDistanceSquared) {
      bestDistanceSquared = dissq;
      bestT = t;
      result.set(x,y,0);
    }
  }
  return result;
}

...