Logical Operators
So far we’ve looked at different forms of the if statement using single conditions involving one relational operator (>, <=, >, >=, ==, !=). But often we need to create more complex conditions that involve more than one condition linked together somehow.
To do this, p5.js includes 3 logical operators: && (which means AND), || (which means OR), and ! (which means NOT). Let’s look at some mouse roll-over examples to demonstrate!
&& (AND)
Here is how && works: if a condition on the left of it AND a condition on the right of it are both true, then the overall Boolean expression will be true. Otherwise, the result will be false. This works exactly as you would expect in English. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function setup() { createCanvas(400, 400) } function draw() { background(220) line(0, height/2, width, height/2) line(width/2, 0, width/2, height) // If the mouse is in the top-right quadrant // then draw a red rectangle there. if (mouseX > width/2 && mouseY < height/2) { fill(255,0,0) rect(width/2, 0, width, height/2) } } |
On line 12, I am checking if the x-coordinate of the mouse is on the right half of the canvas and (&&) that the y-coordinate of the mouse is on the top half of the canvas. If both of these conditions are true, then the overall Boolean expression is true. If one or both conditions are false, then the overall result will be false.
Before using &&, the code for this would have required an if statement inside another if statement like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
function setup() { createCanvas(400, 400) } function draw() { background(220) line(0, height/2, width, height/2) line(width/2, 0, width/2, height) // If the mouse is in the top-right quadrant // then draw a red rectangle there. if (mouseX > width/2) { if (mouseY < height/2) { fill(255,0,0) rect(width/2, 0, width, height/2) } } } |
This approach works, but it requires an extra level of indentation and can start to become hard to read if the logic gets much more complex than this. Much better to use && in situations like this.
|| (OR)
The way || works is different than in English, be careful! In English, if I ask “Would you like tea or coffee?” you would understand that to mean one or the other, but not both. But in programming, if one or the other or both conditions on either side of the || operator are true, the overall Boolean expression will be true. Only if both conditions are false, will the overall result will be false.
Here’s an example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function setup() { createCanvas(400, 400) } function draw() { background(220) line(width/3, 0, width/3, height) line(2*width/3, 0, 2*width/3, height) // If the mouse is over the left OR right section // then draw 2 red rectangles. if (mouseX < width/3 || mouseX > 2*width/3) { fill(255,0,0) rect(0, 0, width/3, height) rect(2*width/3, 0, width, height) } } |
This time on line 12 I am checking if the mouse is on the right third or (||) left third of the canvas. If either of these conditions is true, the overall expression will be true. Note, in this case, both conditions would never be true at one time; that is, the mouse can’t be on the right third and left third simultaneously. Just be aware that there are other situations where both conditions might be true at the same time and || will give a true result in these cases.
! (NOT)
Lastly, let’s look at how the not (!) operator works. This time I’ll use the mouseIsPressed system variable which will have the value true if a mouse button is pressed, and false otherwise. A variable that contains either true or false is called a Boolean variable. Using the ! operator reverses a Boolean value. So, !true means false, and !false means true.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
function setup() { createCanvas(400, 400) } function draw() { background(220) // If the mouse button is NOT pressed draw rectangle // otherwise, draw an ellipse if (!mouseIsPressed) { fill(255, 0, 0) rect(100, 100, 200, 200) } else { fill(0, 0, 255) ellipse(200, 200, 200, 200) } } |
In this example, as long as mouseIsPressed is false a red square will be drawn, and otherwise a blue circle. Notice that by using the mouseIsPressed system variable like this I did not need to create a mousePressed() function to handle the event.
On line 10, I could have written:
if (mouseIsPressed == false) {
and that would have been equivalent to !mousePressed. The second way takes a little more typing, but you might find it easier to understand.
We could have easily reversed the logic as well by writing:
if (mouseIsPressed == true) {
or
if (mouseIsPressed) {
which both have the same meaning.
In terms of precedence (i.e., order of operations), if you have a combination of &&, ||, and ! together, the ! (NOT) has the highest precedence, followed by && (AND), then || (OR). You can also use ( parentheses ) to control/change the order of operations if desired.
You Try!
- Assuming x = 3 and y = 7, what would be the result of these Boolean expressions:
- (x >= 3)
- !(x > 3)
- (x == 3 && y == 6)
- (x == 6 || y == 7)
- !(x > -3 && y <= 7)
- (x > 10 && x < 2)
- Extend the && (AND) example from the lesson to handle all four quadrants. In other words, change the colour of each quadrant when the mouse enters it. Hint: you will need to add several else if parts to the logic.
- Write a program that implements a simple roll-over. Draw a black rectangle somewhere on the canvas. As long as the mouse is over the rectangle change its colour to red, otherwise, it should be black.
- Repeat Q3, but this time use a circle. How might you check if the mouse is within the bounds of the circle?
- Modify Q4. Draw two overlapping circles (you’ll need to use some transparency here), and demonstrate how the && operation works; i.e., make the background green only when the mouse is over both the left and right circle, otherwise red.
- Modify Q5, but this time show how the || operation works; i.e., the background is green as long as the mouse pointer is over one or the other or both circles, otherwise red.