Advancing loop one frame at a time then save frame as a PDF -- doesn’t always save frame seen on screen

This is a piece of a larger sketch I have reduced down to basic elements for the question.

  • It is currently set up to redraw one frame at a time when keyPressed.
  • And with mousePressed to record a PDF of the frame shown on screen.

The recording is inconsistent however. Sometimes records the frame as seen on screen, but more often records following frame (or next?).

Since beginRecord is at the outset of draw() I would expect the program flow to capture the image as it is currently displayed on screen.

Basically I want to be able to manually control the loop and record a PDF of the frame if desired.
I’ve also tried running with a very slow frameRate (.5), and but still the recording is not always of the frame shown when mousePressed…

Any suggestions most appreciated!
Thank you!
:nerd_face:

// MAIN ------------------------------------
import processing.pdf.*;

boolean record;

HalfmoonRect hlfMn_R;
HalfmoonArc hlfMn_A;

void setup() {
  size(200, 200);
  noLoop();

  hlfMn_R = new HalfmoonRect (0, 0, 200);
  hlfMn_A = new HalfmoonArc (0, -100, 200);

  //frameRate(1);
}

void draw() {
  
  if (record) {
    beginRecord (PDF, nf(month())+nf(day(),2)+nf(hour(),2)+nf(minute(),2)+nf(second(),2)+" .pdf");
  }

  background (255);

  hlfMn_R.display();
  hlfMn_A.display();
  
  if (record) {
    endRecord();
    record = false;
  }
}
void keyPressed() {
  hlfMn_R.display();
  hlfMn_A.display();
  redraw();
}

void mousePressed(){
  record = true;
}
// CLASS SUPER ----------------------------------------------

class Halfmoon {

  color c1 = #FFFFFF, 
    c2 = #BEBEBE, 
    c3 = #7F7F7F, 
    c4 = #3F3F3F, 
    c5 = #000000;
  color[] grays = {c1, c2, c3, c4, c5};  

  float deg, rad;
  float x, y, sz;

  Halfmoon(float tempX, float tempY, float tempSz) {    
    x = tempX;
    y = tempY;
    sz = tempSz;
    
    deg = radians(90);
  }

  void arcPlusColor (color arcColor) {
    fill (arcColor);
    arc (x, y, sz, sz, 0, PI);
  }

  void rectPlusColor (color rectColor) {
    fill (rectColor);
    rectMode (CENTER);
    rect (0, 0, 200, 200);
  }
}
// SUB1
class HalfmoonArc extends Halfmoon {
  HalfmoonArc(float x, float y, float sz) {
    super(x, y, sz);
  }

  void display() {
    noStroke();
    float r = random(1);
    println (r);

    if (r < 0.40) {
      rotate (deg);
    } else if (r > 0.40 && r < 0.50) {
      rotate (deg*3);
    } else if (r > 0.50 && r < 0.65) {
      rotate (deg*2);
    } else {
      rotate (deg*4);
    }

    arcPlusColor(grays[int(random(grays.length))]);
  }
}
// SUB2

class HalfmoonRect extends Halfmoon {

  HalfmoonRect(float x, float y, float sz) {
    super(x, y, sz);
  }

  void display() {
    noStroke();
    translate (100, 100);
    rectPlusColor(grays[int(random(grays.length))]);
  }
}
1 Like

Hi @debxyz,

This suggestion won’t solve the problem, but I’m hoping it will help you diagnose the problem: split the logic which displays the arc off from the logic which chooses its rotation and which chooses its color.

void setup() {
}

class Foo {
  color[] grays = {
    #FFFFFF, /* white */
    #BEBEBE, /* 75% gray */
    #7F7F7F, /* 50% gray */
    #3F3F3F, /* 25% gray */
    #000000 /* black */
  };

  float x;
  float y;
  float sz;
  float rotation;
  color fillColor;

  void display() {
    noStroke();
    rotate(rotation);
    fill(fillColor);
    arc (x, y, sz, sz, 0, PI);
  }

  void chooseRotationRnd() {
    float r = random(1.0);
    if (r < 0.40) {
      /* 90 deg, HALF_PI rad */
      rotation = radians(90);
    } else if (r > 0.40 && r < 0.50) {
      /* 90 * 3 = 270 deg, PI + HALF_PI rad */
      rotation = radians(90 * 3);
    } else if (r > 0.50 && r < 0.65) {
      /* 90 * 2 = 180 deg, PI rad */
      rotation = radians(90 * 2);
    } else {
      /* 90 * 4 = 360 deg, TAU rad */
      rotation = radians(90 * 4);
    }
  }

  void chooseColorRnd() {
    fillColor = grays[int(random(grays.length))];
  }
}

These functions can now be tested independently.

You can think of this as adopting and following an annoyingly long function name rule: every function name describes all that the function does. If you rename display to chooseRotationRandomlyAndChooseColorRandomlyAndDisplay, and it’s annoying to type all that in, then you need to narrow down what the function does.

Best,
Jeremy

1 Like

Hello @behreajj and thank you for your suggestion!! :slightly_smiling_face:

So I guess the mousePressed delays when the the beginRecord is actually initiated… (?).

After dropping the mousePressed and trying a different beginRecord sequence from the PDF Libraries reference – “Single Frame (With Screen Display)” the displayed frame records as desired.
:nerd_face:

1 Like