Linedrawing Processing webcam video keypressed reset problem

I am a student studying processing.
Currently, I am implementing a real-time line drawing code using a webcam and I am currently facing a problem.
In the current code, I want to press q to start the video, press s to stop, and press r to initialize the screen, resulting in a new line drawing.
Currently, q and s keyboard functions are implemented, but r functions are not implemented, so we ask for your help. Thank you

import cc.arduino.;
import org.firmata.
;
import processing.serial.;
import processing.video.
;
Serial port;
int Sensor;
PImage myImage;
int numSteps = 300, counter = 0;
Canvas myCanvas;
float zFactor = 0;
Capture cam;
boolean showNow=false;
void setup(){
size(640,480);
frameRate(60);
frameRate(60);
myCanvas = new Canvas(new PVector(0, 0));
noFill();
String cameras = Capture.list();
cam = new Capture(this, cameras[1]);
cam.start();
background(255);
println(Serial.list());
port = new Serial(this, Serial.list()[2], 115200); // make sure Arduino is talking serial at this baud rate
port.clear(); // flush buffer
port.bufferUntil(‘\n’);
noLoop();
}
void draw()
{
if (cam.available() == true && showNow == false )
{
cam.read();
//image(cam, 0, 0);
showNow = true;
int cam_width = 640;
int cam_height = 480;
myImage = createImage(640, 480, RGB);
myImage.copy(cam, 0, 0, cam.width, cam.height, 0, 0, myImage.width, myImage.height);
myImage.loadPixels();
}
if ( showNow == true)
{
for(int i = 0; i < numSteps; i++){
myCanvas.update();
myCanvas.show();
zFactor += 0.01;
}
println(Sensor);
}
}
void keyPressed() {
if ( key == ‘s’ ) noLoop();
if ( key == ‘q’ ) loop();
}

class Canvas{
PVector previousPos, currentPos, velocity = new PVector(0, 0), force = new PVector(0, 0);
float maxSpeed = 3, surroundMatrix = 3, noiseMultiplier = 1.0;
int drawAlpha = 30, drawWeight = 1, maxCounters= 70;
color drawColor = color(1, 0, 0, drawAlpha);
Canvas(PVector pos){
previousPos = pos.copy();
currentPos = pos.copy();
}
void update(){
previousPos = currentPos.copy();
force.mult(0);
PVector target = new PVector(0, 0);
counter = 0;
for(float i = -floor(surroundMatrix / 2); i < surroundMatrix / 2; i++){
for(float j = -floor(surroundMatrix / 2); j < surroundMatrix / 2; j++){
if (i == 0 && j == 0){
continue;
}
int x = floor(currentPos.x + i);
int y = floor(currentPos.y + j);
if(((myImage.width - 1 - x) | (x - 0) | (myImage.height - 1 - y) | (y - 0)) >= 0) {
// color c = color(red(getColor(x, y)), green(getColor(x, y)), blue(getColor(x, y)), alpha(getColor(x, y)));
color c = color(red(getColor(x, y)), green(getColor(x, y)), blue(getColor(x, y)), alpha(getColor(x, y)));
drawColor = c;
b = 1 - b / 20.0;
PVector pos = new PVector(i, j);
target.add(pos.div(pos.mag()).copy().mult(b));
counter++;
}
}
}
if(counter != 0){
force.add(target.div(counter));
}
float n = noise(currentPos.x, currentPos.y, zFactor);
n = map(n, 0, 1, 0, 5 * TWO_PI);
PVector p = PVector.fromAngle(n);
if(force.mag() < 0.01){
force.add(p.mult(noiseMultiplier * 5));
}
else{
force.add(p.mult(noiseMultiplier));
}
velocity.add(force);
if (velocity.mag() > maxSpeed) {
velocity.normalize().mult(maxSpeed);
}
currentPos.add(velocity);
if (!((floor(width - currentPos.x) | floor(currentPos.x - 0) | floor(height - currentPos.y) | floor(currentPos.y - 0)) >= 0)) {
reset();
}
}
void reset(){
myImage.updatePixels();
myImage.loadPixels();
counter = 0;
boolean hasFound = false;
while(!hasFound){
currentPos.x = random(1) * width;
currentPos.y = random(1) * height;
color c = color(red(getColor(floor(currentPos.x), floor(currentPos.y))), green(getColor(floor(currentPos.x), floor(currentPos.y))),
blue(getColor(floor(currentPos.x), floor(currentPos.y))), alpha(getColor(floor(currentPos.x), floor(currentPos.y))));
float b = brightness(c);
if(b < 255){
hasFound = true;
}
}
drawColor = color(red(getColor(floor(currentPos.x), floor(currentPos.y))), green(getColor(floor(currentPos.x), floor(currentPos.y))),
blue(getColor(floor(currentPos.x), floor(currentPos.y))), drawAlpha);
previousPos = currentPos.copy();
velocity.mult(0);
}
void show(){
counter++;
if(counter > maxCounters){
reset();
}
stroke(drawColor);
drawColor = color(red(getColor(floor(currentPos.x), floor(currentPos.y))), green(getColor(floor(currentPos.x), floor(currentPos.y))),
blue(getColor(floor(currentPos.x), floor(currentPos.y))), drawAlpha);
strokeWeight(drawWeight);
line(previousPos.x, previousPos.y, currentPos.x, currentPos.y);
fadeLineFromImg(previousPos.x, previousPos.y, currentPos.x, currentPos.y);
}
}
void fadeLineFromImg(float x1, float y1, float x2, float y2){
int xOffset = floor(abs(x1 - x2));
int yOffset = floor(abs(y1 - y2));
int step = xOffset < yOffset ? yOffset : xOffset;
for (int i = 0 ; i < step ; i++) {
int x = floor(x1 + (x2 - x1) * i / step);
int y = floor(y1 + (y2 - y1) * i / step);
color originColor = color(red(getColor(x, y)), green(getColor(x, y)), blue(getColor(x, y)), alpha(getColor(x, y)));
float r = red(originColor);
float g = green(originColor);
float b = blue(originColor);
originColor = color(r + 50 > 255 ? 255 : (r + 50), g + 50 > 255 ? 255 : (g + 50), b + 50 > 255 ? 255 : (b + 50));
setColor(x, y, originColor);
}
}
color getColor(int i, int j) {
int index = j * myImage.width + i;
return color(red(myImage.pixels[index]), green(myImage.pixels[index]), blue(myImage.pixels[index]), alpha(myImage.pixels[index]));
}
void setColor(int i, int j, color c) {
int index = j * myImage.width + i;
myImage.pixels[index] = color(red(c), green(c), blue(c), alpha(c));
}

void serialEvent(Serial port){
String inData = port.readStringUntil(‘\n’);
inData = trim(inData);
if (inData.charAt(0) == ‘S’){
inData = inData.substring(1);
Sensor = int(inData);
}
}

After that, we plan to link the line thickness with the Arduino heart rate sensor, so we even attach a serial communication code.

Hi @jinjin I can see this is the same project as the other post. It’s better to keep the two conversations separate. So in this one we’ll only talk about the specific question you’ve asked.

(Please make it easier by editing you post, select the whole code, and press </> .)

The general answer to your question is:

  • see all your code in setup, separate it into two sections
    • a) things that are only done at sketch start.
    • b) things that have to be repeated when you want to reset the display.
  • put all the b) things in another function e.g. 'void reset(){ code here }
boolean doReset = true;

void draw() {
  if (doReset) {
    reset();
    doReset = false
}

// Where you detect 'r' is pressed
doReset = true;

Please try that and say how you get on.