1

I have a sketch in P5.js that is close to working as intended, except that I can't figure out how to control the period or wavelength. As you'll see if you run the code, the animation creates long sweeping waves, but I'd like to be able to set the wavelength based on a parameter. This is just a coding exercise - any help would be appreciated!

Note, the code isn't running directly on S.O. but can be run here, https://editor.p5js.org/knectar/sketches/ONxJGvmJH

var arr = []; //array that holds rectangles
var rectNum; //number of rectangles drawn
var xPos; // horizontal position of rectangle
var yPos; // vertical position of rectangle
var w = 5; // rectangle width
var h; // rectangle height
var rPadding = 4; //space between bars
var amplitude = 40;
var frequency = 2;

function setup() {
  createCanvas(1000, 400);
  angleMode(DEGREES); //slows the animation down (maybe an issue?)

 rectNum = floor(width/(w+rPadding)); //limit array size to width of canvas
  yPos = height*.6; // positions objects in vertical center

  for (var i = 0; i < rectNum+1; i++){
    var bar = new Bar(i*(w+rPadding), yPos, w, -h); //builds out the objects
    arr.push(bar); //loads objects into array
  }
}

function draw() {
  background(1);

  for (var i = 0; i < arr.length; i++){
    arr[i].make();
    arr[i].move(i);
    }
}

function Bar(xPos, yPos, w, h){
  this.xPos = xPos;
  this.yPos = yPos;
  this.width = w;
  this.height = h;

  this.move = function(i){
      this.height = sin(frameCount*frequency+i)*amplitude+(amplitude*2); // sine function to control rectange height
  }

  this.make = function(){
      strokeWeight(0);
      stroke(51);
      fill(160, 0, 124);
      rect(this.xPos, this.yPos, this.width, -this.height); // negative height sets wave to point up
  }
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Chris Amato
  • 135
  • 1
  • 7
  • Your code already has variables that control the amplitude and frequency. Changing those works fine. I'm confused about what you're asking? – Kevin Workman Jan 26 '19 at 21:15
  • @KevinWorkman No the formula is not complete. At least `i` has to be multiplied by a wave frequency or divide by a wavelength. – Rabbid76 Jan 26 '19 at 21:26

1 Answers1

3

In processing the parameter for the sin function has to be set in degrees.

If you distribute 360 degrees on all the Bar objects (distribute on arr.length), then you'll generate 1 complete sine curve:

this.move = function(i){

    var alpha = 360.0*i/arr.length;

    this.height = sin(alpha) * amplitude + (amplitude*2);
}

The wave frequency is 1.0 / wavelength. This means the angle has to be divided by the wavelength.

e.g. 4 completes sine curves can be generated by wavelength = 0.25.

var wavelength = 0.25;

this.move = function(i){

    var alpha = 360.0*i/arr.length;

    this.height = sin(frameCount*frequency + alpha/wavelength) * amplitude + (amplitude*2);
}

var arr = []; //array that holds rectangles
var rectNum; //number of rectangles drawn
var xPos; // horizontal position of rectangle
var yPos; // vertical position of rectangle
var w = 5; // rectangle width
var h; // rectangle height
var rPadding = 4; //space between bars
var amplitude = 40;
var frequency = 2;

function setup() {
  createCanvas(600, 300);
  angleMode(DEGREES); //slows the animation down (maybe an issue?)

 rectNum = floor(width/(w+rPadding)); //limit array size to width of canvas
  yPos = height*.6; // positions objects in vertical center

  for (var i = 0; i < rectNum+1; i++){
    var bar = new Bar(i*(w+rPadding), yPos, w, -h); //builds out the objects
    arr.push(bar); //loads objects into array
  }
}

function draw() {
  background(1);

  for (var i = 0; i < arr.length; i++){
    arr[i].make();
    arr[i].move(i);
    }
}

function Bar(xPos, yPos, w, h){
  this.xPos = xPos;
  this.yPos = yPos;
  this.width = w;
  this.height = h;

  frequency = arr.length / (2.0 * Math.PI);

var wavelength = 0.25;

this.move = function(i){
    var alpha = 360.0*i/arr.length;
    this.height = sin(frameCount*frequency + alpha/wavelength) * amplitude + (amplitude*2);
}

  this.make = function(){
      strokeWeight(0);
      stroke(51);
      fill(160, 0, 124);
      rect(this.xPos, this.yPos, this.width, -this.height); // negative height sets wave to point up
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.js"></script>
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thank you (yet again), this works great. I knew the formula was incomplete, and your explanation on the math, and code corrections clarify perfectly. – Chris Amato Jan 27 '19 at 20:14