Starting ellipse w/ Perlin Noise in Canvas Center on mousePressed()

Hi everyone

First time posting here! I hope somebody is able to help.

My goal is to start animating on function mousePressed an ellipse with perlin noise. The ellipse needs to be centered on the canvas and start from there.

Everything works fine, but the starting point after the mouse has been pressed is always different. I think I understand why: because this.xPos = map(this.xSpeed, 0, 1, 0, width); always sets a new x Position for the ellipse. So as soon as I add this.xPos = this.xPos + map(this.xSpeed, 0, 1, 0, width); it sort of works, but the whole perlin noise effect is gone.

Anyone has an idea how to start in the center while also maintaining the perlin noise effect?

See the sketch here:
Sketch in P5Editor

Thanks for your help!

Hello, @refchef, and welcome to the Processing Forum!

When the mouse is first pressed, you need to save the degree to which the initial position of the ellipse differs from the center of the canvas. Thereafter, subtract that difference from the mapping, each time the ellipse is to be drawn. This is to avoid the abrupt jump of the ellipse away from the center of the canvas as the animation begins.

See the code below. It still needs additional adjustments. For example, the single stray ellipse that is drawn at the outset of the animation needs to be eliminated.

class Seed {
  constructor() {
    this.growingSeed = false;
    this.xoff1 = 0;
    this.xoff2 = 10000;
    this.xoff3 = 0;
    this.xPos = width / 2;
    this.yPos = height / 2;
    this.r = 10;
    this.hu = random(1, 360);
    this.dx = 0;
    this.dy = 0;
  }

  show() {
    noStroke();
    this.hu += 1;
    this.hu = this.hu%360;
    fill(this.hu, 80, 100);
    ellipse(this.xPos - this.dx, this.yPos - this.dy, this.r);
  }

  move() {
    this.xSpeed = noise(this.xoff1);
    this.xPos = map(this.xSpeed, 0, 1, 0, width);

    this.ySpeed = noise(this.xoff2);
    this.yPos = map(this.ySpeed, 0, 1, 0, height);

    this.xoff1 += 0.005;
    this.xoff2 += 0.005;

  }

  clicked(px, py) {
    this.d = dist(px, py, this.xPos, this.yPos);
    if (this.d < this.r) {
      this.xSpeed = noise(this.xoff1);
      this.dx = map(this.xSpeed, 0, 1, 0, width) - width / 2;

      this.ySpeed = noise(this.xoff2);
      this.dy = map(this.ySpeed, 0, 1, 0, height) - height / 2;
      this.growingSeed = true;
    }
  }
}

EDIT (May 27, 2021):

The above revision to your code does leave other issues unresolved. For instance, consider whether the mapping from Perlin space to canvas coordinates needs to be adjusted in order make the 0.0 to 1.0 range of the Perlin values map neatly to the full width and height ranges of the canvas coordinates.

EDIT (May 28, 2021):

The above, regarding adjustment of the mapping, may seem a bit abstract. The image below illustrates the issue. Note that shifting the drawing so that the initial point is in the center moved the ellipses into a corner, with many of them entirely off the canvas.

Screen Shot 2021-05-27 at 4.12.08 PM

The following sketch, which maps noise values in a different manner, may also offer some additional insight. The x positions of the lines represent noise values. The top half is without shifting, while the bottom half is with shifting of the same noise values, so that the initial value is in the center. The blue lines mark the initial noise value.

Note that the left edge of the top pattern is shifted off the canvas in the bottom pattern.

The code:

let px = 0; // noise position
let x_init; // result from first noise position
let x_diff; // difference between first noise position and center
function setup() {
  createCanvas(400, 60);
  background(255, 255, 128);
  strokeCap(SQUARE);
  x_init = map(noise(px), 0, 1, 0, width);
  x_diff = x_init - width / 2;
}

function draw() {
  let x_affixed = map(noise(px), 0, 1, 0, width);          // in place
  let x_shifted = map(noise(px), 0, 1, 0, width) - x_diff; // shifted
  
  // initial val markers
  strokeWeight(8);
  stroke(0, 0, 255);
  // initial val marker blue affixed
  line(x_init, 0, x_init, height / 2); 
  // initial val marker blue shifted
  line(x_init - x_diff, height / 2, x_init - x_diff, height); 
  
  strokeWeight(4);
  stroke(255, 0, 0);
  line(width / 2, 0, width / 2, height / 2); // center marker red
  
  // center marker in red
  strokeWeight(4);
  stroke(255, 0, 0);
  line(width / 2, 0, width / 2, height); 

  // display lines based on noise value
  strokeWeight(1);
  stroke(0, 15);
  line(x_affixed, 0, x_affixed, height / 2);      // affixed
  line(x_shifted, height / 2, x_shifted, height); // shifted
  
  // next noise position
  px += 0.005;
}

How to address the issue remains an enigma, but there it is.