made with proce55ing


// SIN_PATTERN_SLIDERS
//
// pattern generator based on the sum of combined sin waves
// play with the sliders to adjust each of the 3 frequencies
// and phases on x and y.
//
// Seb Chevrel | www.seb.cc
// ———————————————————————————————————————————————————————————————

int WIDTH=400;
int HEIGHT=400;
int NUMF=3;

float[] freqV=new float[NUMF];
float[] freqH=new float[NUMF];
float[] phaseV=new float[NUMF];
float[] phaseH=new float[NUMF];
HScrollbar[] freqVScroll=new HScrollbar[NUMF];
HScrollbar[] freqHScroll=new HScrollbar[NUMF];
HScrollbar[] phaseVScroll=new HScrollbar[NUMF];
HScrollbar[] phaseHScroll=new HScrollbar[NUMF];
float sum=0;
int col;

void setup() {
  size(WIDTH,HEIGHT+NUMF*20+10);
  noBackground();
  for(int i=0; i<NUMF; i++) {
    freqVScroll[i]=new HScrollbar (5, HEIGHT+i*20+15, 120, 16, 1);
    freqHScroll[i]=new HScrollbar (WIDTH/2+5, HEIGHT+i*20+15, 120, 16, 1);
    freqV[i]=(random(200)+10)/(1<<i);
    freqH[i]=(random(200)+10)/(1<<i);
    freqVScroll[i].setPos((float)freqV[i]/210);
    freqHScroll[i].setPos((float)freqH[i]/210);
    phaseV[i]=random(PI);
    phaseH[i]=random(PI);
    phaseVScroll[i]=new HScrollbar (135, HEIGHT+i*20+15, 60, 16, 1);
    phaseHScroll[i]=new HScrollbar (WIDTH/2+135, HEIGHT+i*20+15, 60, 16, 1);
    phaseHScroll[i].setPos(phaseH[i]/PI);
    phaseVScroll[i].setPos(phaseV[i]/PI);
  }
  render();
}

void loop() {
  // init
  for(int i=0; i<NUMF; i++) {
    freqVScroll[i].update();
    freqV[i]=freqVScroll[i].getPos()*200+10;
    freqVScroll[i].draw();

    phaseVScroll[i].update();
    phaseV[i]=phaseVScroll[i].getPos()*PI;
    phaseVScroll[i].draw();

    freqHScroll[i].update();
    freqH[i]=freqHScroll[i].getPos()*200+10;
    freqHScroll[i].draw();

    phaseHScroll[i].update();
    phaseH[i]=phaseHScroll[i].getPos()*PI;
    phaseHScroll[i].draw();

  }
  if(HScrollbar.inuse) render();

}

void render() {
  for(int i=0;i<WIDTH;i++) {
    for(int j=0;j<HEIGHT;j++) {
      sum=0;
      for(int k=0;k<NUMF;k++) {
        sum+= sin(j/freqV[k]+phaseV[k]) * sin(i/freqH[k]+phaseH[k]) ;
      }
      col=int(sum*255/NUMF);
      if (col<0) col=-col;
      pixels[i+j*WIDTH]=(col<<16)+(col<<8)+col;
    }
  }
}

class HScrollbar
{
  static boolean inuse;
  int swidth, sheight;    // width and height of bar
  int xpos, ypos;         // x and y position of bar
  float spos, newspos;    // x position of slider
  int sposMin, sposMax;   // max and min values of slider
  int loose;              // how loose/heavy
  boolean over;           // is the mouse over the slider?
  boolean locked;
  float ratio;
  

  HScrollbar (int xp, int yp, int sw, int sh, int l) {
    swidth = sw;
    sheight = sh;
    int widthtoheight = sw - sh;
    ratio = (float)sw / (float)widthtoheight;
    xpos = xp;
    ypos = yp-sheight/2;
    spos = xpos + swidth/2 - sheight/2;
    newspos = spos;
    sposMin = xpos;
    sposMax = xpos + swidth - sheight;
    loose = 1;
  }

  void update() {
    if(over() && !inuse) {
      over = true;
    } else {
      over = false;
    }
    if(mousePressed && over) {
      if (! inuse) {
        locked = true;
        inuse=true;
      }
    }
    if(!mousePressed) {
      locked = false;
      inuse=false;
    }
    if(locked) {
      newspos = constrain(mouseX-sheight/2, sposMin, sposMax);
    }
    if(abs(newspos - spos) > 1) {
      spos = spos + (newspos-spos)/loose;
    }
  }

  int constrain(int val, int minv, int maxv) {
    return min(max(val, minv), maxv);
  }

  boolean over() {
    if(mouseX > xpos && mouseX < xpos+swidth &&
    mouseY > ypos && mouseY < ypos+sheight) {
      return true;
    } else {
      return false;
    }
  }

  void draw() {
    fill(0);
    rect(xpos, ypos, swidth, sheight);
    if(over || locked) {
      fill(255, 102, 0);
    } else {
      fill(255, 255, 255);
    }
    rect(spos, ypos, sheight, sheight);
  }

  void setPos(float v) {
    newspos=spos=xpos+v/ratio*(swidth-sheight);
  }

  float getPos() {
    // convert spos to be values between
    // 0 and the total width of the scrollbar
    return (spos-xpos)/(swidth-sheight);
  }
}