Math and processing

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

1 Like