Midterm

Random Face

In the ‘random face’ code, I found three points that I found interesting.

  1. About noLoop() and redraw()

Throughout the code, the functions noloop and redraw are used. When I stop noloop from running, the code is unable to interact with the user, meaning it cannot switch facial expressions when the user clicks the mouse. Reason

By default, P5.js redraws 60 times per second, which affects the execution of the instructions in the subsequent draw function. The redraw within the mousePressed event, however, causes the draw code to run once more after the user clicks the mouse and performs this interactive action.

Why don’t use the array()?

Because they solve different problems. noLoop() stops draw() from running again, so nothing re-randomizes. An array stores the random results once, so draw() can keep running and still draw the same picture every frame. The array version is more flexible because I can change one eye later without re-rolling everything.

If use the array(), while the code will become:

let L = 5, H = 6, G = 100;
let eyes = [];   // eyes[col][row] 

function setup() {
  createCanvas(500, 600);
  makeEyes();                       // just one time
}

function makeEyes() {
  eyes = [];
  for (let r = 0; r < H; r++) {
    eyes[r] = [];
    for (let c = 0; c < L; c++) {
      eyes[r][c] = [random() < 0.5, random() < 0.5];   // pick up and save it
    }
  }
}

function draw() {
  background(244);
  stroke(20);
  for (let r = 0; r < H; r++) {
    for (let c = 0; c < L; c++) {
      drawFace(c * G + G / 2, r * G + G / 2, eyes[r][c]);
    }
  }
}

function drawFace(cx, cy, open) {
  strokeWeight(4);
  ellipse(cx, cy, 70, 70);

  strokeWeight(5);
  for (let side = -1; side <= 1; side += 2) {
    let ex = cx + side * 15;
    if (open[(side + 1) / 2]) {          // side=-1 → 下标0,side=1 → 下标1
      ellipse(ex, cy - 8, 5, 5);         
    } else {
      arc(ex, cy - 8, 12, 8, 0, PI);
    }
  }
}

function mousePressed() {
  makeEyes();                            // remake 
  1. About side

for (let side = -1; side <= 1; side = side + 2). When I alter the line of code ‘side = side + 2’ to ‘side = side + 1’, I can observe that the eyes, which were originally positioned at either end, may occasionally appear in the middle. Reason

for (let side = -1; side <= 1; side = side + 2). The code for (let side = -1; side <= 1; side = side + 2) ensures that the coordinates remain between -1 and 1. This guarantees that, whether the eyes are closed or open, the changing position is centrally symmetrical and remains unchanged.

image.png

  1. About if (random() < 0.5)

if (random() < 0.5). When I tried changing the value in random from 0.5 to 0.8, I could see that the probability of keeping my eyes closed increased, whilst the probability of opening them decreased significantly. Reason As the default range for random is 0–1, and a probability of 0.5 represents a 50–50 chance, adjusting this probability will reduce the likelihood of the instruction being executed.

  1. Extra about why I change the point() to ellipse()

The code uses if/else, so every eye must draw either a point or an arc. My console showed 60 draw calls, so the code was running correctly. I noticed the missing eyes were always dots, never arcs, and only in the right part of the canvas.

The p5 reference says point() should draw a single point using the stroke color and stroke weight. So this looked like a bug. I replaced point() with a small ellipse(), and every eye appeared. That told me the problem was in point().

I then read the source code of my version, p5 2.3.2. It draws a point as a line that is only 0.00001 pixels long, with a round cap. My explanation is that when x is above 256, floating-point precision rounds that tiny length to zero, so the dot disappears. The x positions of my missing eyes match that threshold exactly.