Skip to content

Commit

Permalink
Merge pull request #103 from RAIRLab/98-ellipse-collision-not-detecting
Browse files Browse the repository at this point in the history
Ellipse collision detection bug
  • Loading branch information
James-Oswald authored Oct 9, 2023
2 parents 71eff51 + 6cd835f commit d2e1cdb
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 46 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"Anusha",
"Huda",
"jamesoswald",
"mosueout",
"peaceiris",
"peircemyheart",
"radx",
Expand Down
17 changes: 10 additions & 7 deletions src/AEG/Ellipse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,18 @@ export class Ellipse {
return false;
} else {
//check if the rectangular bounding boxes of the ellipse overlap
if (this.boundingBox.overlaps((otherShape as Ellipse).boundingBox)) {
if (
this.boundingBox.overlaps((otherShape as Ellipse).boundingBox) ||
//this.boundingBox.containsShape((otherShape as Ellipse).boundingBox) ||
(otherShape as Ellipse).boundingBox.containsShape(this.boundingBox)
) {
//return true;
//if there is an overlap, check if points along the ellipse curve overlap
//this can be done by checking if points along the curve of the other ellipse
//are within this ellipse

const otherPoints: Point[] = otherShape.getEllipsePoints();
for (let i = 0; i < otherPoints.length; i++) {
if (this.containsPoint(otherPoints[i])) {
//this can be done by checking if points along the curve of this ellipse
//are within the other ellipse
const points: Point[] = this.getEllipsePoints();
for (let i = 0; i < points.length; i++) {
if (otherShape.containsPoint(points[i])) {
return true;
}
}
Expand Down
174 changes: 135 additions & 39 deletions src/AEG/Rectangle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,65 +76,161 @@ export class Rectangle {
* Method that checks whether there is an overlap between this rectangle and another shape.
* @param otherShape The other shape that might be overlapping this rectangle.
* @returns True, if there is an overlap. Else, false.
* @todo This method is wrong, the ellipse overlap portion functions as a contains or overlaps
* it should be replaced to just handle overlaps and not return true on contains. -James
* @todo this is basically the exact same method that needs to be implemented for
* Ellipse.overlaps, the implementations should be merged into a single helper function,
* which is called by both methods. -James
*/
public overlaps(otherShape: Rectangle | Ellipse): boolean {
if (otherShape instanceof Rectangle) {
if (
this.checkHorizontalEdgeOverlap(otherShape) &&
otherShape.checkVerticalEdgeOverlap(this)
) {
return true;
} else if (
this.checkVerticalEdgeOverlap(otherShape) &&
otherShape.checkHorizontalEdgeOverlap(this)
) {
return true;
}

return false;
} else {
return this.edgesOverlap(otherShape);
} else if (otherShape instanceof Ellipse) {
for (let i = 0; i < 4; i++) {
if ((otherShape as Ellipse).containsPoint(this.getCorners()[i])) {
if (otherShape.containsPoint(this.getCorners()[i])) {
return true;
}
}
return false;
} else {
throw Error("Invalid Shape passed to overlaps, must be a Rectangle | Ellipse");
}
}

/**
* Checks if any of the horizontal edges of the other rectangle lie within the horizontal
* boundaries of this rectangle
* @param otherRect The other rectangle
* @returns True, if the other edges lie within this boundary. Else, false
* Method that checks if any edges of this rectangle overlap with the other rectangle.
* @param otherRect The other rectangle to be checked.
* @returns True, if edges overlap. Else, false.
* @todo This algo can and should be simplified to be less than 10 lines of code. -James-Oswald
*/
private checkHorizontalEdgeOverlap(otherRect: Rectangle): boolean {
private edgesOverlap(otherRect: Rectangle): boolean {
const thisCorners = this.getCorners();
const otherCorners = otherRect.getCorners();

if (thisCorners[0].y <= otherCorners[0].y && thisCorners[2].y >= otherCorners[0].y) {
return true;
} else if (thisCorners[0].y <= otherCorners[2].y && thisCorners[2].y >= otherCorners[2].y) {
return true;
}
//The top edge of the other rectangle is within the horizontal boundaries
//of this rectangle
if (thisCorners[0].x <= otherCorners[0].x && thisCorners[1].x >= otherCorners[0].x) {
//The left edge of the other rectangle is within the vertical boundaries
//of this rectangle
return true;
} else if (
//The left edge of this rectangle is within the vertical boundaries
//of the other rectangle
otherCorners[0].x <= thisCorners[0].x &&
otherCorners[1].x >= thisCorners[0].x
) {
return true;
} else if (
//The right edge of the other rectangle is within the vertical boundaries
//of this rectangle
thisCorners[0].x <= otherCorners[1].x &&
thisCorners[1].x >= otherCorners[1].x
) {
return true;
} else if (
//The right edge of this rectangle is within the vertical boundaries
//of the other rectangle
otherCorners[0].x <= thisCorners[1].x &&
otherCorners[1].x >= thisCorners[1].x
) {
return true;
}

return false;
}
return false;
} else if (otherCorners[0].y <= thisCorners[0].y && otherCorners[2].y >= thisCorners[0].y) {
//The top edge of this rectangle is within the horizontal boundaries
//of the other rectangle
if (thisCorners[0].x <= otherCorners[0].x && thisCorners[1].x >= otherCorners[0].x) {
//The left edge of the other rectangle is within the vertical boundaries
//of this rectangle
return true;
} else if (
//The left edge of this rectangle is within the vertical boundaries
//of the other rectangle
otherCorners[0].x <= thisCorners[0].x &&
otherCorners[1].x >= thisCorners[0].x
) {
return true;
} else if (
//The right edge of the other rectangle is within the vertical boundaries
//of this rectangle
thisCorners[0].x <= otherCorners[1].x &&
thisCorners[1].x >= otherCorners[1].x
) {
return true;
} else if (
//The right edge of this rectangle is within the vertical boundaries
//of the other rectangle
otherCorners[0].x <= thisCorners[1].x &&
otherCorners[1].x >= thisCorners[1].x
) {
return true;
}

/**
* Checks if any of the vertical edges of the other rectangle lie within the vertical
* boundaries of this rectangle
* @param otherRect The other rectangle
* @returns True, if the other edges lie within this boundary. Else, false
*/
private checkVerticalEdgeOverlap(otherRect: Rectangle): boolean {
const thisCorners = this.getCorners();
const otherCorners = otherRect.getCorners();
return false;
} else if (thisCorners[0].y <= otherCorners[2].y && thisCorners[2].y >= otherCorners[2].y) {
//The bottom edge of the other rectangle is within the horizontal boundaries
//of this rectangle
if (thisCorners[0].x <= otherCorners[0].x && thisCorners[1].x >= otherCorners[0].x) {
//The left edge of the other rectangle is within the vertical boundaries
//of this rectangle
return true;
} else if (
//The left edge of this rectangle is within the vertical boundaries
//of the other rectangle
otherCorners[0].x <= thisCorners[0].x &&
otherCorners[1].x >= thisCorners[0].x
) {
return true;
} else if (
//The right edge of the other rectangle is within the vertical boundaries
//of this rectangle
thisCorners[0].x <= otherCorners[1].x &&
thisCorners[1].x >= otherCorners[1].x
) {
return true;
} else if (
//The right edge of this rectangle is within the vertical boundaries
//of the other rectangle
otherCorners[0].x <= thisCorners[1].x &&
otherCorners[1].x >= thisCorners[1].x
) {
return true;
}

if (thisCorners[0].x <= otherCorners[0].x && thisCorners[1].x >= otherCorners[0].x) {
return true;
} else if (thisCorners[0].x <= otherCorners[1].x && thisCorners[1].x >= otherCorners[1].x) {
return true;
return false;
} else if (otherCorners[0].y <= thisCorners[2].y && otherCorners[2].y >= thisCorners[2].y) {
//The bottom edge of this rectangle is within the horizontal boundaries
//of the other rectangle
if (thisCorners[0].x <= otherCorners[0].x && thisCorners[1].x >= otherCorners[0].x) {
//The left edge of the other rectangle is within the vertical boundaries
//of this rectangle
return true;
} else if (
//The left edge of this rectangle is within the vertical boundaries
//of the other rectangle
otherCorners[0].x <= thisCorners[0].x &&
otherCorners[1].x >= thisCorners[0].x
) {
return true;
} else if (
//The right edge of the other rectangle is within the vertical boundaries
//of this rectangle
thisCorners[0].x <= otherCorners[1].x &&
thisCorners[1].x >= otherCorners[1].x
) {
return true;
} else if (
//The right edge of this rectangle is within the vertical boundaries
//of the other rectangle
otherCorners[0].x <= thisCorners[1].x &&
otherCorners[1].x >= thisCorners[1].x
) {
return true;
}

return false;
}

return false;
Expand Down

0 comments on commit d2e1cdb

Please sign in to comment.