now in the zoomable version i have a even bigger problem with half grid
but i see that your numbers and the function values always FIT.
could not stop without testing
SCROLLITIS functions for this show.
// SCROLLITIS ( combination of a key and mouseWheel to tune a parameter )
// use Y1 [q] [w] [e] [r] and mouseWheel,
// use Y2 [a] [s] [d] [f] and mouseWheel
// and [z] and mouseWheel for grid zoom and [p] and mouseWheel for play epsilon
// key [h] to en/dis-able formula, numbers...
// USER FUNCTION
float Q = 1.0, W = 2.0, E = 0.0, R = 0.0;
float y1(float x) {
return Q + W * x + E * x*x + R * x*x*x; // The Y1 function to plot
}
float A = 4.0, S = -1.0, D = 0.0, F = 0.0;
float y2(float x) {
return A + S * x + D * x*x + F * x*x*x; // The Y2 function to plot
}
void print_Y1() {
String formula = "Y1 = ";
if ( notnearZero(Q) ) formula += nf(Q, 1, 2)+" ";
if ( notnearZero(W) ) formula += plus(W)+nf(W, 1, 2)+"*x ";
if ( notnearZero(E) ) formula += plus(E)+nf(E, 1, 2)+"*xx ";
if ( notnearZero(R) ) formula += plus(R)+nf(R, 1, 2)+"*xxx";
formula += " use [q] [w] [e] [r] and mouseWheel ";
textSize(12);
fill(RED);
text(formula, 10, 15 );
}
void print_Y2() {
String formula = "Y2 = ";
if ( notnearZero(A) ) formula += nf(A, 1, 2)+" ";
if ( notnearZero(S) ) formula += plus(S)+nf(S, 1, 2)+"*x ";
if ( notnearZero(D) ) formula += plus(D)+nf(D, 1, 2)+"*xx ";
if ( notnearZero(F) ) formula += plus(F)+nf(F, 1, 2)+"*xxx";
formula += " use [a] [s] [d] [f] and mouseWheel ";
textSize(12);
fill(BLUE);
text(formula, 10, 45 );
formula = "and [z] for zoom and play epsilon [p] and mouseWheel";
formula += "\nuse key [h] toggle all that info";
fill(0);
text(formula, 10, 75 );
}
String plus(float val ) {
if ( val < 0 ) return "";
return "+";
}
boolean notnearZero(float val ) {
float check = 0.05;
if ( val > -check && val < check ) return false;
return true;
}
//______________________________________________________________________
void setup() {
size(500, 500);
draw_it();
}
void draw() {
}
void draw_it() {
background(255);
draw_grid();
push();
translate(gridcenter, gridcenter);
draw_functions();
pop();
if ( showhelp) print_Y1();
if ( showhelp) print_Y2();
}
// can be other TAB..
// rev 0.4 try even zoom key [z] and check grid / numbers and function plot correct
int steps = 100;
float X, Y1, Y2, Xo=0, Y1o, Y2o;
float f_start_x = -10, f_stop_x = 10; // changed in draw and mousewheel
float dx = (f_stop_x - f_start_x )/float(steps);
float epsilon = 1; // @mcintyre
boolean showhelp = true;
//consts
color RED = color(255, 0, 0);
color BLUE = color(0, 0, 255);
void draw_functions() {
strokeWeight(1);
f_start_x = -width/(2*w);
f_stop_x = width/(2*w);
dx = (f_stop_x - f_start_x )/float(steps);
for ( int i = 0; i< steps; i++) {
X = f_start_x + dx * i;
if ( i == 0 ) Xo=X; // need a dummy init for first line
Y1 = y1(X);
if ( i == 0 ) Y1o=Y1;
Y2 = y2(X);
if ( i == 0 ) Y2o=Y2;
if ( abs(Y2 - Y1) <= epsilon ) println("solution near i "+i+" X "+nf(X, 1, 2)+" Y1 "+nf(Y1, 1, 2)+" Y2 "+nf(Y2, 1, 2)+ " for epsilon "+nf(epsilon, 1, 2));
// draw it: // in processing draw y negativ! // scale to GRID by w
stroke(RED);
line(Xo*w, -Y1o*w, X*w, -Y1*w);
circle(X*w, -Y1*w, 2);
stroke(BLUE);
line(Xo*w, -Y2o*w, X*w, -Y2*w);
circle(X*w, -Y2*w, 2);
// remember for next loop draw line
Y1o = Y1;
Y2o = Y2;
Xo = X;
}
}
// grid of rectangles
int x = 0, y = x, w = 25, h = w, offset = 0;
int grid = 20, many = grid*grid;
int gridcenter = x + ( w + offset ) * grid/2;
void draw_grid() {
println("x "+x+" y "+y+" w "+w+" h "+h+" offset "+offset+" grid "+grid+" many "+many);
noFill();
stroke(0);
strokeWeight(0.5);
for (int i = 0; i < many; i++) rect(x+(i%grid)*(w+offset), y+(floor(i/grid))*(h+offset), w, h); // or any other shape/text on that position
if ( showhelp) {
// https://discourse.processing.org/t/math-and-processing/9292/7 @CHRISIR
// small lines with numbers ||||||||||| : for x axis
pushMatrix();
translate(gridcenter, gridcenter);
strokeWeight(3);
textSize(12);
textAlign(CENTER);
fill(0); // BLACK
stroke(0); // BLACK
for (int i = -grid/2; i < grid/2; i++) {
float dx = 1;
float X = dx * i;
if ( X==0 ) continue; // || X==-10 // skip those numbers
float xToDraw = getXtoDraw(X);
float yToDraw = getYtoDraw(0);
line(xToDraw, yToDraw, xToDraw, yToDraw+11);
text(i, xToDraw+3, yToDraw+24);
}//for
textAlign(LEFT);
strokeWeight(1);
popMatrix();
// small lines with numbers : for y axis
pushMatrix();
translate(gridcenter, gridcenter);
stroke(0); // BLACK
fill(0); // BLACK
textSize(12);
textAlign(CENTER);
strokeWeight(3);
for (int i = -grid/2; i < grid/2; i++) {
float dx = 1;
float Y = dx * i;
if ( Y==0 ) continue; // skip these numbers // || Y==9 || Y==-1)
float xToDraw = getXtoDraw(0);
float yToDraw = getYtoDraw(Y);
line(xToDraw, yToDraw, xToDraw+11, yToDraw);
text(i, xToDraw+15, yToDraw-3); // +24
}//for
textAlign(LEFT);
strokeWeight(1);
popMatrix();
// show arrows and texts X and Y
decoration();
fill(255);
ellipse(gridcenter, gridcenter, 5, 5); // show center point
}
}
void decoration () {
stroke(0);
strokeWeight(3);
// line |
line ( gridcenter, 0, gridcenter, gridcenter*2);
// line -
line ( 0, gridcenter, gridcenter*2, gridcenter);
// texts X and its arrow ---
fill(0);
textSize(24);
text ( "X", gridcenter*2-17, gridcenter+31);
pushMatrix();
noFill();
strokeWeight(3.0);
strokeJoin(MITER);
beginShape();
float f = 3.0;
translate(gridcenter*2-f*7, gridcenter);
vertex(3.5*f, -3.0*f);
vertex(6.5*f, 0.0*f);
vertex(3.5*f, 3.0*f);
endShape();
strokeWeight(1);
popMatrix();
// texts Y and its arrow ---
fill(0);
textSize(24);
text ( "Y", gridcenter+10, 22);
pushMatrix();
noFill();
strokeWeight(3.0);
strokeJoin(MITER);
beginShape();
translate(gridcenter, 22);
vertex( -3.0*f, -3.5*f);
vertex( 0.0*f, - 6.5 * f);
vertex( 3.0*f, - 3.5 * f);
endShape();
popMatrix();
}
// ------------------------------------------------------------ HELPER FUNCTIONS
float getXtoDraw(float xin_) {
return xin_*w;
}
float getYtoDraw(float yin_) { // in processing draw y negativ!
return -yin_*w;
}
void keyPressed() {
if ( key == 'h' ) {
showhelp = !showhelp; // [h]
draw_it();
}
}
void mouseWheel(MouseEvent event) {
float e = event.getCount();
float k=0.05; // step change parameter
if ( keyPressed && key == 'z' ) w += e; // [z] grid size
// Y1 = Q + W * x + E * x*x + R * x*x*x;
if ( keyPressed && key == 'q' ) Q += e*k; // [q]
if ( keyPressed && key == 'w' ) W += e*k; // [w]
if ( keyPressed && key == 'e' ) E += e*k; // [e]
if ( keyPressed && key == 'r' ) R += e*k; // [r]
// Y2 = A + S * x + D * x*x + F * x*x*x;
if ( keyPressed && key == 'a' ) A += e*k; // [a]
if ( keyPressed && key == 's' ) S += e*k; // [s]
if ( keyPressed && key == 'd' ) D += e*k; // [d]
if ( keyPressed && key == 'f' ) F += e*k; // [f]
if ( keyPressed && key == 'p' ) epsilon += e*k; // [p]
auto_scale();
draw_it();
}
void auto_scale() { // autoscale grid on changing w
grid = floor((width-2*x)/(w + offset ));
many = grid*grid;
gridcenter = x + ( w + offset ) * grid/2;
h = w;
}