new version
looks better, still not perfect
you can DRAG the focal points now
PVector[] listPV = {
new PVector (0, 0),
new PVector (0, 200),
new PVector (550, 400),
new PVector (50, 500),
new PVector (600-24, 800-24)
};
color[] listColor = {
color (100, 255, 255),
color (255, 0, 0),
color (255, 200, 200),
color (255, 0, 255),
color (255, 0, 0)
};
// mouse dragging
boolean hold=false;
int hold_i=-1;
// -------------------------------------------------------------------------------------------
void setup() {
size(600, 800);
}
void draw() {
background(255);
noFill();
color c1;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
c1 = getCol (x, y); // color(200, 255, 255);
stroke(c1);
point(x, y);
}
}
// optional: show all focal points
showFocalPoints();
// mouse dragging
if (hold&&hold_i!=-1) {
listPV[hold_i].x=mouseX;
listPV[hold_i].y=mouseY;
}
//noLoop();
}
void mousePressed() {
// mouse dragging
hold=true;
int i2=0;
for (PVector pv : listPV) {
if (dist(mouseX, mouseY, pv.x, pv.y)<21) {
hold_i=i2;
return;
}
i2++;
}//for
}
void mouseReleased() {
// mouse dragging
hold=false; // reset
hold_i=-1;
}
// ------------------------------------------------------------------------------------------------------
color getCol(float x1, float y1) {
color c1=0;
float red=0, green=0, blue=0;
int i2a=0;
c1=color(random(256));
// c1=0;
///for (PVector pv : listPV) {
for ( int i2=0; i2<listPV.length-1; i2++ ) {
// we look at one focal point and the next
PVector pv1 = listPV[i2];
c1 = listColor[i2];
float distMy1 = dist(pv1.x, pv1.y, x1, y1);
PVector pv2 = listPV[i2+1];
color c2 = listColor[i2+1];
float distMy2 = dist(pv2.x, pv2.y, x1, y1);
// 0.5
// println(distMy1 / distMy2);
/// exit();
float amt = distMy1 / distMy2 ;
amt=map(amt, 0, 3, 0, 1);
color c3 = lerpColor (c1, c2, amt);
// ----
// sum it
red += red(c3);
green += green(c3);
blue += blue(c3);
i2a=i2;
}//for
// take average
//red /= (float)i2a;
//green /= (float)i2a;
//blue /= (float)i2a;
// println(red, green, blue);
// OR just map the sums to 0..256
float maxRange1 = 1220;
red = map(red, 0, maxRange1, 0, 256);
green = map(green, 0, maxRange1, 0, 256);
blue = map(blue, 0, maxRange1, 0, 256);
return color(red, green, blue);
}
// -------------------------------------------------------------------------------------------
// NOT IN USE
color getColOld(float x1, float y1) {
color c1=0;
float red=0, green=0, blue=0;
int i2=0;
c1=color(random(256));
// c1=0;
for (PVector pv : listPV) {
float distMy;
// distMy = pv.dist(new PVector(x1, y1));
distMy = dist(pv.x, pv.y, x1, y1);
float amt = map(distMy, 0, 444, 255, 0) ;
// c1 = lerpColor ( c1, listColor[i2], amt) ;
c1=listColor[i2];
red += red(c1)*amt;
green += green(c1)*amt;
blue += blue(c1)*amt;
i2++;
}//for
// i2--;
// take average
red/=(float)i2;
green/=(float)i2;
blue/=(float)i2;
// println(red, green, blue);
return color(red, green, blue);
// return c1;
}
void showFocalPoints() {
int i2=0;
for (PVector pv : listPV) {
fill(listColor[i2]);
stroke(0);
rect(pv.x, pv.y, 6, 6);
noFill();
rect(pv.x, pv.y, 6, 16);
rect(pv.x, pv.y, 26, 26);
i2++;
}
}
Remarks
- of course you can / should join the 2 parallel ArrayLists by creating a
class FocalPoint
and say
ArrayList<FocalPoint> listFocalPoints = new ArrayList();
the function getCol I have problems with; it’s the core question, how can I
- for each pixel A in the canvas
- calc the lerpColor between (in this approach) 2 focal points B1 and B2 (with colors c1 and c2)
- with an amt that is between 0 and 1 and calculated so that it reflects the distances between A-B1 and A-B2.
So when A-B1 is 600 and A-B2 is 300,
- A is closer to B2,
- the amt value between colors c1 and c2 should be around 0.6 I guess (making the color c2 belonging to B2 dominant over c1).
- But what is the exact formula?
And when I have a couple of pairs B1/B2, B2/B3…calculated, how can I calc the average color?