Beginner Question: About Flow

Hello people, I’m new here and I really want some help.

I’ve a bit of a problem using P5.

My JS is quite poor and I’m using P5 to get a better understanding from the ground up. So I’m just trying to mess around with variables and I’ve this super simple code, I just want to draw an ellipse that goes around a rectangular canvas starting from the top-left and going clockwise sticking to the brders. I’ve looked around and I’ve seen plenty of possible answers dealing with setting the direction using a negative value and so on but I don’t want to do that but instead want to do it through just controlling the flow using if statements.

Now I can realize that the problem is due to multiple conditions testing for true to the same case and hence the code not running correctly. I can get it halfway through and I even stuck to just hardcoding the x and y values in hopes of figuring out what I was doing wrong or where I was messing up but alas I give up!

I want to know how to get around it by hacking away at this method. Is it possible or do I just need to get some sleep and try again?

var x = 10;
var y = 10;
function setup() {
	createCanvas(100, 100);
	background(100);
}

function draw() {
	ellipse(x, y, 10, 10);

	if(x <= 90) {
		x++;
	} else if (x >= 90) {
		x = 90;
		y++;
	} else if (y >= 90) {
		y = 90;
		x--;
	} else if (x <= 10) {
		y++;
		x = 10;
	}
}
1 Like

Here’s a Processing’s Java Mode example which can easily be converted to p5.js flavor: :coffee:
Studio.ProcessingTogether.com/sp/pad/export/ro.9DEx177ceWoBc

2 Likes

Thank you, that’s exactly the kind of thing I’m hoping to achieve

But I wanted to know what could I do to make it happen without introducing more variables, like how exactly could you do it with just if else statements, no matter how contrived it can get! I went through the code and it seems you’re using a velocity variable? I dunno as I have no clue about Java or Processing at this stage! I hope I’ll start once I get better grip on JS.

Introducing new variables can be good or bad

In my experience it’s good in most cases

My approach would be to use a variable state that is

  • 0 when we are at the upper border going right, it is
  • 1 when we are at the right side and
  • 2 when we are at the bottom going left

Now you need some ifs to know when to increase state. These 4 ifs implement each also the current state!

So

    if (state==0 && x >= .....) 
        state=1;  // state ++; 

etc.

Evaluate state

Next thing you have to do: have a different set of if clauses (for example in another function) to evaluate state and act accordingly.

The trick is to use state and separate

  • the evaluation of state where you act according to its value and
  • the checks when to increase state.

This makes things simpler because we use a new variable! Not although.

your approach

Anyway in your approach: last if clause must have y–; not ++ (my phone destroys minus minus to a long line, sorry!)

Also, the conditions overlap (first and last one); to avoid this try to say if(x<=90&&y==10) and so on

Chrisir

2 Likes

“Clockwise Pathway Circle” converted from Java Mode to p5.js flavor: :asterisk:

3 Likes

I guess you’re right!
I’m trying this way but it’s getting overtly complicated. I will wrangle with it until I’m able to get it in order.

Thank you! I guess the answer lies in the constrainToBorder() function. I’ll now get down to it to make it work in my case with my approach.

Finally figured it to make it work through 1 iteration in a very hacky way! :grin: :grin:

I know it’s absolutely terrible but it was just a case of being obsessed about doing this one particular way. I’ll refactor the entire thing into something which makes sense later. Here is what I came up with!

var x = 10;
var y = 10;

function setup() {
	createCanvas(100, 100);
	background(100);
}

function draw() {
	ellipse(x, y, 10, 10);

	var horizontal;
	var vertical;
	var horizontalReverse;
	var verticalReverse;

	if (x <= width - 10) {
		horizontal = true;
	} else {
		horizontal = false;
		vertical = true;
	}

	if (y >= height - 10) {
		vertical = false;
		horizontal = false;
		horizontalReverse = true;
	}

	if (x == 5) {
		verticalReverse = true;
		horizontal = false;

	}

	if (horizontal == true) {
		x++;
	}

	if (vertical == true) {
		y++;
	}

	if (horizontalReverse == true) {
		x--;
	}

	if (verticalReverse == true) {
		y--;
	}

}
1 Like
  • Basically the moving circle() depends on 2 variables: loc & vel.
  • Variable loc points to a p5.Vector object which keeps circle()'s current coordinates.
  • While variable vel points to a vanilla object which keeps circle()'s current velocity & p5.Color.
  • Indeed constrainToBorder() checks whether loc is still constraint within canvas’ width & height dimensions.
  • Also it takes into consideration the constants RAD (circle()'s radius) & SPD (circle()'s speed).
  • But in order to do that, it needs to check 2 state variables: vel & isClockwise.
  • Yep, vel has a double duty in this sketch: it is both the current velocity & direction state.
  • There are 4 constants which acts as both state & velocity: N, S, W & E (north up, south down, west left & east right).
  • Depending on current vel state, constrainToBorder() does a customized check.
  • And in case the check passes, it switches the vel state to 1 of the pre-customized 2 choices, which depends on isClockwise.
3 Likes

A “Clockwise Pathway Circle” Python Mode version too: :snake:

1 Like

Well my solution was incomplete, and it had been bothering me intermittently throughout the week. And so I sat down and made it again and finally got it to run continuously. Please tell me if there’s anything wrong with the approach and scope for improvement. Thanks for all the help guys!

let x = 10;
let y = 10;
let downFlag;
let rightFlag;
let upFlag;
let leftFlag;

function setup() {
  createCanvas(200, 200);
  rectMode(CENTER);
}

function draw() {
  background(220);
  rect(x, y, 10, 10);

  if (x < width - 10) {
    rightFlag = true;
  }

  if (rightFlag && !leftFlag && !upFlag && !downFlag) {
    x++;
  }

  if (x > width - 10) {
    downFlag = true;
    rightFlag = false;
  }

  if (downFlag && !leftFlag && !rightFlag && !upFlag) {
    y++;
  }

  if (y > height - 10) {
    leftFlag = true;
    downFlag = false;
    rightFlag = false;
    upFlag = false;
  }

  if (leftFlag && !rightFlag && !upFlag && !downFlag) {
    x--;
  }

  if (x < 10) {
    upFlag = true;
    leftFlag = false;
    rightFlag = false;
    downFlag = false;
  }

  if (upFlag && !rightFlag && !leftFlag && !downFlag) {
    y--;
  }

  if (y < 10) {
    rightFlag = true;
    upFlag = false;
  }

}
1 Like

here’s another way to skin the cat …

https://editor.p5js.org/slow_izzm/sketches/Va9CSvaK0

2 Likes

In these lines:

You check 4 booleans but only one can be true at a time.

my approach with int state that can have 4 different values is clearer

Chrisir