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; } |
...