From 2893c65165594be24be8f3924d82abc70e2884a6 Mon Sep 17 00:00:00 2001 From: aryan02420 Date: Mon, 15 Mar 2021 18:45:30 +0530 Subject: [PATCH 1/2] fixed Line/Rect correctly identifies collision when line is completely inside rect --- CodeExamples/LineRect/LineRect.pde | 20 +++++++++++++ CodeExamples/LineRect/web-export/LineRect.pde | 29 +++++++++++++++---- Website/line-rect.php | 11 +++++-- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/CodeExamples/LineRect/LineRect.pde b/CodeExamples/LineRect/LineRect.pde index d4d2f1b..0cfbf5a 100644 --- a/CodeExamples/LineRect/LineRect.pde +++ b/CodeExamples/LineRect/LineRect.pde @@ -46,6 +46,12 @@ void draw() { // LINE/RECTANGLE boolean lineRect(float x1, float y1, float x2, float y2, float rx, float ry, float rw, float rh) { + + // is either end INSIDE the rectangle? + // if so, return true immediately + boolean inside1 = pointRect(x1,y1, rx,ry,rw,rh); + boolean inside2 = pointRect(x2,y2, rx,ry,rw,rh); + if (inside1 || inside2) return true; // check if the line has hit any of the rectangle's sides // uses the Line/Line function below @@ -62,6 +68,20 @@ boolean lineRect(float x1, float y1, float x2, float y2, float rx, float ry, flo } +// POINT/RECTANGLE +boolean pointRect(float px, float py, float rx, float ry, float rw, float rh) { + + // is the point inside the rectangle's bounds? + if (px >= rx && // right of the left edge AND + px <= rx + rw && // left of the right edge AND + py >= ry && // below the top AND + py <= ry + rh) { // above the bottom + return true; + } + return false; +} + + // LINE/LINE boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) { diff --git a/CodeExamples/LineRect/web-export/LineRect.pde b/CodeExamples/LineRect/web-export/LineRect.pde index 2df7cd4..0cfbf5a 100644 --- a/CodeExamples/LineRect/web-export/LineRect.pde +++ b/CodeExamples/LineRect/web-export/LineRect.pde @@ -10,18 +10,16 @@ float y1 = 0; float x2 = 20; // static point float y2 = 20; -float sx, sy; // square position +float sx = 200; // square position +float sy = 100; float sw = 200; // and size float sh = 200; void setup() { - size($("#wrapper").width(), 400); + size(600, 400); strokeWeight(5); // make the line easier to see - - sx = width/2-sw/2; - sy = height/2-sh/2; } @@ -48,6 +46,12 @@ void draw() { // LINE/RECTANGLE boolean lineRect(float x1, float y1, float x2, float y2, float rx, float ry, float rw, float rh) { + + // is either end INSIDE the rectangle? + // if so, return true immediately + boolean inside1 = pointRect(x1,y1, rx,ry,rw,rh); + boolean inside2 = pointRect(x2,y2, rx,ry,rw,rh); + if (inside1 || inside2) return true; // check if the line has hit any of the rectangle's sides // uses the Line/Line function below @@ -64,6 +68,20 @@ boolean lineRect(float x1, float y1, float x2, float y2, float rx, float ry, flo } +// POINT/RECTANGLE +boolean pointRect(float px, float py, float rx, float ry, float rw, float rh) { + + // is the point inside the rectangle's bounds? + if (px >= rx && // right of the left edge AND + px <= rx + rw && // left of the right edge AND + py >= ry && // below the top AND + py <= ry + rh) { // above the bottom + return true; + } + return false; +} + + // LINE/LINE boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) { @@ -87,4 +105,3 @@ boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, flo } - diff --git a/Website/line-rect.php b/Website/line-rect.php index b6929b8..1edec7e 100644 --- a/Website/line-rect.php +++ b/Website/line-rect.php @@ -2,9 +2,16 @@

LINE/RECTANGLE

-

We've actually already covered how to check if a line has hit a rectangle: it's really just four Line/Line collisions, one for each side!

+

We've actually already covered how to check if a line has hit a rectangle: it's really just two Point/Rect and four Line/Line collisions, one for each side!

-

For example, the left edge of the square starts at (rx,ry) and extends down to ry+rh. We can treat that as a line, using the algorithm we made in the last section:

+

First, let's test if either of the ends of the line are inside the rectangle. This is likely to happen if the line is much smaller than the rectangle. To do this, we can use Point/Rect from the beginning of the book. If either end is inside, return true immediately and skip the rest.

+ +
boolean inside1 = pointRect(x1,y1, rx,ry,rw,rh);
+boolean inside2 = pointRect(x2,y2, rx,ry,rw,rh);
+if (inside1 || inside2) return true;
+
+ +

Next, we check for collision between the line and any edge of the square. For example, the left edge of the square starts at (rx,ry) and extends down to ry+rh. We can treat that as a line, using the algorithm we made in the last section:

boolean left =   lineLine(x1,y1,x2,y2, rx,ry, rx,ry+rh);
 
From 320b956f648b3e79a3eaf59ea5427563b6914444 Mon Sep 17 00:00:00 2001 From: aryan02420 Date: Mon, 15 Mar 2021 18:50:57 +0530 Subject: [PATCH 2/2] minor fixes --- CodeExamples/LineRect/web-export/LineRect.pde | 8 +++++--- Website/line-rect.php | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CodeExamples/LineRect/web-export/LineRect.pde b/CodeExamples/LineRect/web-export/LineRect.pde index 0cfbf5a..3a1af51 100644 --- a/CodeExamples/LineRect/web-export/LineRect.pde +++ b/CodeExamples/LineRect/web-export/LineRect.pde @@ -10,16 +10,18 @@ float y1 = 0; float x2 = 20; // static point float y2 = 20; -float sx = 200; // square position -float sy = 100; +float sx, sy; // square position float sw = 200; // and size float sh = 200; void setup() { - size(600, 400); + size($("#wrapper").width(), 400); strokeWeight(5); // make the line easier to see + + sx = width/2-sw/2; + sy = height/2-sh/2; } diff --git a/Website/line-rect.php b/Website/line-rect.php index 1edec7e..3e22dc6 100644 --- a/Website/line-rect.php +++ b/Website/line-rect.php @@ -4,7 +4,7 @@

We've actually already covered how to check if a line has hit a rectangle: it's really just two Point/Rect and four Line/Line collisions, one for each side!

-

First, let's test if either of the ends of the line are inside the rectangle. This is likely to happen if the line is much smaller than the rectangle. To do this, we can use Point/Rect from the beginning of the book. If either end is inside, return true immediately and skip the rest.

+

First, let's test if either of the ends of the line are inside the square. This is likely to happen if the line is much smaller than the square. To do this, we can use Point/Rect from the beginning of the book. If either end is inside, return true immediately and skip the rest.

boolean inside1 = pointRect(x1,y1, rx,ry,rw,rh);
 boolean inside2 = pointRect(x2,y2, rx,ry,rw,rh);