Meta Mounds: p5js and three force sensitive resistor buttons.

Link to the working code, which uses x and y mouse values instead of input so that one can play with this without hooking up an Arduino. 

Large GIF (740x444).gif
Large GIF (528x442).gif
Large GIF (816x440).gif

Below is a previous attempt to create this, along with the code I used to make the animation above. 

 

Large GIF (420x468).gif

The goal of this project was to use arrays and a constructor function to generate cleaner, compartmentalized code. I am using a shape I made (a clay model of an abstract shape that has curves, sort of reminiscent of a cartoony mountain range) and recreating it's shape using arcs. The display function uses the position of x and y (which are set to random) to place the "portrait" or linear representations of the clay shape onto the canvas.  Here is the link to the code to the P5JS editor. 

Questions

1. I am not sure how to make a step repeat pattern. It must be easy but so far I have only been able to generate linear repetitions, not evenly spread out wallpaper-like repetitions. I actually prefer the randomization, but was just curious to try a more orderly step-repeat approach. 

2. I would like to superimpose this wave over the patterns so that they block the top if the screen with the sine wave motion but I cannot get the two sets of code to coexist in one file. When i try to merge the code i get the following error: 

Uncaught TypeError: Cannot read property 'length' of undefined (sketch: line 96)

This is the code

 

Next Steps

The next step of this project is to use serial connection the pressure sensors on the clay shape and manipulate the amplitude, width, and speed of the wave. 

Code (with Errors)


var xspacing = 12;    // Distance between each horizontal location
var w;                // Width of entire wave
var theta = 0;      // Start angle at 0
var amplitude = 75.0; // Height of wave
var period = 400.0;   // How many pixels before the wave repeats
var dx;               // Value for incrementing x
var yvalues;  // Using an array to store height values for the wave

var sensor1;
var sensor2;
var inData;


function setup() {
  createCanvas(710, 400);
 
  w = width+12;
  dx = (TWO_PI / period) * xspacing;
  // dx =1;
  yvalues = new Array(floor(w/xspacing)); 
  // print(dx);

}

//end of setup

function draw() {
  //background(344, 54, 23);
   background(22, 22, 243);

 calcWave();
 renderWave();
  sensor1 = map(inData, 0, width, 0, 5);
 // sensor2 = map(mouseY, 0, height, 1, 3);
}


function calcWave() {
  // Increment theta (try different values for
  // 'angular velocity' here)
  
  theta += 0.02;

  // For every x value, calculate a y value with sine function
  var x = theta;
   
  for (var i = 0; i < yvalues.length; i++) {
    yvalues[i] = sensor2*sin(x * sensor1) * amplitude ;
    x+=dx;
  }
}

// for incoming serial data

function setup() {
  createCanvas(500, 300);
  colorMode(HSB,255,255,255);
  serial = new p5.SerialPort();       // make a new instance of the serialport library
  serial.on('list', printList);  // set a callback function for the serialport list event
  serial.on('connected', serverConnected); // callback for connecting to the server
  serial.on('open', portOpen);        // callback for the port opening
  serial.on('data', serialEvent);     // callback for when new data arrives
  serial.on('error', serialError);    // callback for errors
  serial.on('close', portClose);      // callback for the port closing
 
  serial.list();                      // list the serial ports
  serial.open(portName);              // open a serial port
circlecolor = color(inData, 200, 200);
  
  
  w = width+12;
  dx = (TWO_PI / period) * xspacing;
  // dx =1;
  yvalues = new Array(floor(w/xspacing)); 
  // print(dx);

  
}

function renderWave() {
  noStroke();
  fill(255);
  // A simple way to draw the wave with an ellipse at each location
  

  for (var x = 0; x < yvalues.length; x++) {
    ellipse(x*xspacing, height/105+yvalues[x], 10, -390);
  }
}
 

CODE THAT DOES WORK (but only maps to one sensor)


var xspacing = 12;    // Distance between each horizontal location
var w;                // Width of entire wave
var theta = 0;      // Start angle at 0
var amplitude = 75.0; // Height of wave
var period = 400.0;   // How many pixels before the wave repeats
var dx;               // Value for incrementing x
var yvalues;  // Using an array to store height values for the wave

var sensor1;
var sensor2;


function setup() {
  createCanvas(710, 400);
 
  w = width+12;
  dx = (TWO_PI / period) * xspacing;
  // dx =1;
  yvalues = new Array(floor(w/xspacing)); 
  // print(dx);

}

//end of setup

function draw() {
  //background(344, 54, 23);
   background(22, 22, 243);

 calcWave();
 renderWave();
  sensor1 = map(mouseX, 0, width, 0, 5);
  sensor2 = map(mouseY, 0, height, 1, 3);
}


function calcWave() {
  // Increment theta (try different values for
  // 'angular velocity' here)
  
  theta += 0.02;

  // For every x value, calculate a y value with sine function
  var x = theta;
   
  for (var i = 0; i < yvalues.length; i++) {
    yvalues[i] = sensor2*sin(x * sensor1) * amplitude ;
    x+=dx;
  }
}

function renderWave() {
  noStroke();
  fill(255);
  // A simple way to draw the wave with an ellipse at each location
  

  for (var x = 0; x < yvalues.length; x++) {
    ellipse(x*xspacing, height/105+yvalues[x], 10, -390);
  }
}