I find the idea great to get the amt data for lerpColor from a function.
So I made a class where you can
- play with a bezier curve (instead of a function) and
- the bezier curve (its y-value) is fed into the color.
Core idea is in the function testlerpColor()
.
It’s a bit tricky.
But when somebody wants to know more, I can explain. I received help from the forum for this. I was mixing up curve and bezier. Bad. See reference.
This could be extended with bezierVertex() or curveVertex() I guess.
Chrisir
// Test for a new bezier Class that can do bezier and bezierpoint (2D) to set a color from bezierPoint y-value
BezierClass mybezier;
// ---------------------------------------------------------------------------------------------
void setup() {
size(1500, 900);
final int STANDARD_DISTANCE=100;
mybezier = new BezierClass (
width/2-31, 33, // coordinates for the first point / anchor
width/2-STANDARD_DISTANCE, height/2+STANDARD_DISTANCE, // control point (cp1)
width/2+STANDARD_DISTANCE, height/2+STANDARD_DISTANCE, // control point
width/2+31, 33 // coordinates for the second point / anchor
);
}
void draw() {
background(#24B41D);
fill(0);
text("Bezier\n"
+"Demo for Bezier y value to color\n"
+"You can drag the two red control points (and the anchor points) with the mouse. \n"
+"Move the mouse to move the white ball and the color on the bezier (mouseX->amt)",
14, 14);
testbezier();
}
//-------------------------------------------------------------------------------------------------------
void testbezier () {
mybezier.displaybezier(); // show entire bezier
mybezier.testbezierData(); // show circles with texts
mybezier.moveOnbezierWithMouseX(); // OR moveOnbezier()
mybezier.testlerpColor(); // lerpColor
mybezier.drag(); // for dragging with the mouse
}
//-------------------------------------------------------------------------------------------------------
void mousePressed() {
mybezier.mousePressedClass();
}
void mouseReleased() {
mybezier.mouseReleasedClass();
}
// ===============================================================================================
class BezierClass {
final int UNKNOWN = -1;
// bezier data
PVector anchor1, cp1, cp2, anchor2;
// the amt for lerp
float amt=0;
// indicates which point we drag (cp1, cp2 or anchor1 or anchor2)
int drag = -1;
// the min and max y for the current bezier
float minY, maxY;
// how strong the cp influences !!! Doesn't work good........
float factorCP = 1;
// constr - Parameters: you call the constr as you would bezier command (2D version) - see reference
BezierClass ( float f0, float f1,
float f2, float f3,
float f4, float f5,
float f6, float f7 ) {
// constr
anchor1 = new PVector (f0, f1);
cp1 = new PVector (f2, f3);
cp2 = new PVector (f4, f5);
anchor2 = new PVector (f6, f7);
setMinYAndMaxY();
} // constr
// ---
void setMinYAndMaxY () {
// init
minY = 1000000;
maxY = -100000;
// simulate bezier
for (int i = 0; i <= 100; i++) {
float y = bezierPoint(anchor1.y, factorCP * cp1.y, factorCP * cp2.y, anchor2.y,
i/100.0);
if (y<minY)
minY = y;
if (y>maxY)
maxY = y;
}//for
}
// ---
void displaybezier() {
stroke(255, 0, 0); //RED
strokeWeight(1);
noFill();
bezier (
anchor1.x, anchor1.y,
factorCP * cp1.x, factorCP * cp1.y,
factorCP * cp2.x, factorCP * cp2.y,
anchor2.x, anchor2.y
);
}
// ---
void moveOnbezier() {
// AUTO move
// resulting point
float x, y;
x = bezierPoint(anchor1.x, factorCP * cp1.x, factorCP * cp2.x, anchor2.x, amt);
y = bezierPoint( anchor1.y, factorCP * cp1.y, factorCP * cp2.y, anchor2.y, amt);
fill(255); // WHITE
noStroke();
ellipse(x, y, 5, 5);
amt+=0.01;
if (amt>=1)
amt=0.0;
}
void moveOnbezierWithMouseX() {
// mouseX move
float x, y;
// mouseX -> amt :
amt=map(mouseX, 0, width,
0, 1);
// amt ->bezier point
x = bezierPoint(anchor1.x, factorCP * cp1.x, factorCP * cp2.x, anchor2.x, amt);
y = bezierPoint( anchor1.y, factorCP * cp1.y, factorCP * cp2.y, anchor2.y, amt);
//x = bezierPoint(factorCP * cp1.x, anchor1.x, anchor2.x, factorCP * cp2.x, amt);
//y = bezierPoint(factorCP * cp1.y, anchor1.y, anchor2.y, factorCP * cp2.y, amt);
fill(255); // WHITE
noStroke();
ellipse(x, y, 5, 5);
}
// ---
void testlerpColor() {
// now it gets interesting
// mouseX to lerpColor
// mouseX -> amt :
float amt=map(mouseX, 0, width,
0, 1);
// amt -> bezierPoint Y
float y = bezierPoint( anchor1.y, factorCP * cp1.y, factorCP * cp2.y, anchor2.y, amt);
// y-value -> lerp color colorAmt
float colorAmt = map ( y, minY, maxY,
0, 1 );
// lerp color colorAmt -> color
fill( lerpColor( color(255, 0, 0), color(0, 0, 255), colorAmt ) );
rect (100, 100, 66, 66);
fill(255);
text ("min and max: " + minY+" "+maxY
+ " -> " +y
+ " \ncolor amt = "+colorAmt, 100, 180);
}
// ---
void testbezierData() {
makeCircleWithText("cp1", cp1, color (255, 0, 0)) ;
makeCircleWithText("cp2", cp2, color (255, 0, 0)) ;
makeCircleWithText("anchor1", anchor1, color (0, 0, 255)) ;
makeCircleWithText("anchor2", anchor2, color (0, 0, 255)) ;
}//method
void makeCircleWithText(String txt, PVector pv, color col) {
noStroke();
fill(col);
ellipse (pv.x, pv.y, 18, 18);
fill(255);
text(txt,
pv.x+15, pv.y-8);
}
// ---
void mousePressedClass() {
if (dist(mouseX, mouseY, cp1.x, cp1.y) < 33)
drag=0;
else if (dist(mouseX, mouseY, cp2.x, cp2.y) < 33)
drag=1;
else if (dist(mouseX, mouseY, anchor1.x, anchor1.y) < 33)
drag=2;
else if (dist(mouseX, mouseY, anchor2.x, anchor2.y) < 33)
drag=3;
}//method
void mouseReleasedClass() {
drag=UNKNOWN; // reset
setMinYAndMaxY();
}
// ---
void drag() {
if (drag==UNKNOWN)
return;
switch (drag) {
case 0:
cp1.x=mouseX;
cp1.y=mouseY;
break;
case 1:
cp2.x=mouseX;
cp2.y=mouseY;
break;
case 2:
anchor1.x=mouseX;
anchor1.y=mouseY;
break;
case 3:
anchor2.x=mouseX;
anchor2.y=mouseY;
break;
case UNKNOWN:
//ignore
break;
default:
// Error
break;
}//switch
setMinYAndMaxY();
}//method
//
}//class
//