6. Overlapping Shapes
6.1. Determining If A Point Is Inside A Given Shape
1. Circles
Determining if a point lies inside a circle is simple. We just check the distance of the point from the centre of the circle. If it is greater than the radius of the circle, then the point lies outside the circle. This simple sketch demonstrates this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | let circ = {
x: 150,
y: 150,
r: 100
};
function setup() {
createCanvas(400, 400);
background(200);
}
function draw() {
background(200);
if(dist(circ.x, circ.y, mouseX, mouseY) <= circ.r)
fill(255, 0, 0);
else
fill(255);
circle(circ.x, circ.y, 2*circ.r);
}
|
2. Rectangles and Squares
Determining if a point lies inside a rectangle (or a square) is also fairly straightforward. If the X and Y coordinates of the point lie between the X and Y coordinates for two opposite corners of the rectangle, then the point lies inside the rectangle. The following sketch demonstrates this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | let rec = {
x1: 150,
y1: 100,
x2: 300,
y2: 350,
};
function setup() {
createCanvas(400, 400);
background(200);
}
function draw() {
background(200);
if(rec.x1 < mouseX && mouseX < rec.x2 && rec.y1 < mouseY && mouseY < rec.y2)
fill(255, 0, 0);
else
fill(255);
rect(rec.x1, rec.y1, rec.x2-rec.x1, rec.y2-rec.y1);
}
|
3. Any General Shape
To check if a point lies within any general shape, you draw a line from the point towards the right till the edge of the canvas, and if this line intersects an even number of edges, then the point is outside the shape, otherwise it is inside the shape. The following code demonstrates this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 | function setup() {
createCanvas(400, 400);
background(200);
}
function pentagon(x, y, edge) {
let radius = sin(radians(54))/sin(radians(72))*edge;
let vertices = [];
beginShape();
for(i = 0; i < 5; ++i) {
vertex(x + radius*cos(2*PI*i/5), y + radius*sin(2*PI*i/5));
vertices.push({x: x + radius*cos(2*PI*i/5), y: y + radius*sin(2*PI*i/5)});
}
endShape(CLOSE);
return vertices;
}
function draw() {
background(200);
let vertices = pentagon(100, 100, 50);
let outside = true;
let n = vertices.length;
for(let i = 0; i < n; ++i) {
let interX = (mouseY-vertices[i].y)*(vertices[i].x-vertices[(i+1)%n].x)/(vertices[i].y-vertices[(i+1)%n].y) + vertices[i].x;
let minX = Math.min(vertices[i].x, vertices[(i+1)%n].x);
let maxX = Math.max(vertices[i].x, vertices[(i+1)%n].x);
let minY = Math.min(vertices[i].y, vertices[(i+1)%n].y);
let maxY = Math.max(vertices[i].y, vertices[(i+1)%n].y);
if(mouseX <= interX && minX <= interX && interX <= maxX && minY <= mouseY && mouseY <= maxY)
outside = !outside;
}
if(outside)
fill(255);
else
fill(255, 0, 0);
}
|
6.2. Determining If Two Shapes Overlap
1. Circles
Determining if two circles overlap is simple. If the distance between their centres is less than the sum of their radii then they overlap.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | let circ = {
x: 150,
y: 150,
r: 100
};
let r2 = 50;
function setup() {
createCanvas(400, 400);
background(200);
}
function draw() {
background(200);
if(dist(circ.x, circ.y, mouseX, mouseY) <= circ.r+r2)
fill(255, 0, 0);
else
fill(255);
circle(circ.x, circ.y, 2*circ.r);
circle(mouseX, mouseY, 2*r2);
}
|
2. Rectangles
Determining if two rectangles overlap is also fairly simple. If the manhattan distance between their centres is less than half the sum of their length and widths.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | let rec = {
x: 150,
y: 100,
w: 100,
h: 50,
};
let rec2 = {
w: 50,
h: 100,
};
function setup() {
createCanvas(400, 400);
background(200);
}
function mdist(x1, y1, x2, y2) {
return Math.abs(x2-x1) + Math.abs(y2-y1);
}
function draw() {
background(200);
if(Math.abs(mouseX-rec.x) < (rec.w+rec2.w)/2 && Math.abs(mouseY-rec.y) < (rec.h+rec2.h)/2)
fill(255, 0, 0);
else
fill(255);
rect(rec.x-rec.w/2, rec.y-rec.h/2, rec.w, rec.h);
rect(mouseX-rec2.w/2, mouseY-rec2.h/2, rec2.w, rec2.h);
}
|