Creating random shapes within the limits

Hi, I am trying to draw some shapes to resemble a face, I have arrays that holds the certain x, y points for each part of a human face like eyes, jaw,nose etc.

What is the best way to go about this, using arc, vertex?

The idea is drawing sorta random shapes while staying in the defined points from these arrays to resemble a face. Here is one example in image format

Here is the code sample which currently only draws a basic shape but should give you an idea.

2 Likes

Hello, @callenk, and welcome to the Processing Foundation Forum!

With randomization, would you like to vary the positions of the facial features, the forms of the facial features, or a combination of both?

EDIT (February 25, 2022):

Since each type of facial feature has its own nuances, it might be best to write a separate function for drawing each one. This would enable you to use different strategies for introducing randomness, based on those nuances. Below is an example of a function for drawing the mouth. It obviously needs refinement.

function drawMouth(color) {
  let mouth = [
    {
      _x: 387.6577683742578,
      _y: 369.0331888192228,
    },
    {
      _x: 407.00089302625776,
      _y: 365.85590373064906,
    },
    {
      _x: 434.7384985549439,
      _y: 366.171463258642,
    },
    {
      _x: 449.27931827961254,
      _y: 369.2639073617315,
    },
    {
      _x: 464.0487483311093,
      _y: 368.01369229132035,
    },
    {
      _x: 495.8288616632999,
      _y: 374.3113342729382,
    },
    {
      _x: 521.1731921017742,
      _y: 381.34289533674905,
    },
    {
      _x: 490.3371981073987,
      _y: 398.9959073598651,
    },
    {
      _x: 466.94158625804715,
      _y: 405.7705438797759,
    },
    {
      _x: 443.9603429832458,
      _y: 406.68249762387074,
    },
    {
      _x: 424.86575622764354,
      _y: 402.63111022606483,
    },
    {
      _x: 405.62077095350855,
      _y: 392.2080545568318,
    },
    {
      _x: 390.69194115753766,
      _y: 370.0178396726528,
    },
    {
      _x: 428.2131300495174,
      _y: 373.0973695790913,
    },
    {
      _x: 448.9742443594697,
      _y: 375.4678421199305,
    },
    {
      _x: 469.8304490771126,
      _y: 377.6905037503284,
    },
    {
      _x: 516.0693200903028,
      _y: 380.80110325034724,
    },
    {
      _x: 467.582837756528,
      _y: 393.76089985426137,
    },
    {
      _x: 446.66764118933406,
      _y: 394.052458612104,
    },
    {
      _x: 427.4513557777959,
      _y: 391.0020196328584,
    },
  ];
  fill(color);
  beginShape();
  for (var d of mouth) {
    // randomize vertices
    vertex(d._x + randomGaussian() * 10, d._y + randomGaussian() * 4);
  }
  endShape(CLOSE);
} // end function drawMouth

lips

Note, here, that a different degree of variability is being used for the x and y coordinates of the vertices:

    vertex(d._x + randomGaussian() * 10, d._y + randomGaussian() * 4);

You could also use different functions to implement the randomness for the different features. See the following:

2 Likes

Thanks @javagar, randomgaussian is a good idea.

I also would like to use noise() function but unsure how to do it with these arrays, like drawing similar to this within each part/array.

image

Here is an example:

function drift(x, y) {
  let mult = 50.0;
  let div = 100.0;
  let n = noise(x / div, y / div) * mult;
  n = n - mult / 2;
  print(n);
  return n;
}

function drawMouth(color) {
  let mouth = [
    {
      _x: 387.6577683742578,
      _y: 369.0331888192228,
    },
    {
      _x: 407.00089302625776,
      _y: 365.85590373064906,
    },
    {
      _x: 434.7384985549439,
      _y: 366.171463258642,
    },
    {
      _x: 449.27931827961254,
      _y: 369.2639073617315,
    },
    {
      _x: 464.0487483311093,
      _y: 368.01369229132035,
    },
    {
      _x: 495.8288616632999,
      _y: 374.3113342729382,
    },
    {
      _x: 521.1731921017742,
      _y: 381.34289533674905,
    },
    {
      _x: 490.3371981073987,
      _y: 398.9959073598651,
    },
    {
      _x: 466.94158625804715,
      _y: 405.7705438797759,
    },
    {
      _x: 443.9603429832458,
      _y: 406.68249762387074,
    },
    {
      _x: 424.86575622764354,
      _y: 402.63111022606483,
    },
    {
      _x: 405.62077095350855,
      _y: 392.2080545568318,
    },
    {
      _x: 390.69194115753766,
      _y: 370.0178396726528,
    },
    {
      _x: 428.2131300495174,
      _y: 373.0973695790913,
    },
    {
      _x: 448.9742443594697,
      _y: 375.4678421199305,
    },
    {
      _x: 469.8304490771126,
      _y: 377.6905037503284,
    },
    {
      _x: 516.0693200903028,
      _y: 380.80110325034724,
    },
    {
      _x: 467.582837756528,
      _y: 393.76089985426137,
    },
    {
      _x: 446.66764118933406,
      _y: 394.052458612104,
    },
    {
      _x: 427.4513557777959,
      _y: 391.0020196328584,
    },
  ];
  fill(color);
  beginShape();
  for (var d of mouth) {
    // randomize vertices
    vertex(d._x + drift(d._x, d._y), d._y + drift(d._x, d._y));
  }
  endShape(CLOSE);
} // end function drawMouth

Thanks this one utilises the noise function but what I meant was making that look similar to the last image I shared. As in drawing circles within circles

2 Likes

In addition to using the functions listed here for providing randomization, it might be beneficial to experiment with the following, which are listed in the p5.js Reference:

Use randomizations to vary the locations of vertices, lengths of arcs, and other parameters. If you post code and images during the process of experimentation, we can provide suggestions.

One way to proceed with experimentation might be to open the image that you shared on a canvas, and collect mouseX and mouseY coordinates in the JavaScript console that can be used to approximate that image via the functions listed above.

Here’s some starter code that might help with collecting coordinates:

let img;
function preload() {
  // image from https://discourse.processing.org/t/creating-random-shapes-within-the-limits/35438?u=javagar
  img = loadImage("photo-2022-02-25-18-06-45.jpeg");
}
function setup() {
  createCanvas(img.width, img.height);
}

function draw() {
  image(img, 0, 0);
}
function mouseReleased() {
  print(mouseX, mouseY);
}

Press and release the mouse on the canvas to collect coordinates.

Screen capture:

After writing p5.js code to approximate the image, add function calls to provide randomization.

EDIT (February 27, 2022):

… or draw an image by hand on paper, photograph it, and write code to approximate that, as a next step.