in shadows/framework/src/main/java/org/robolectric/shadows/RoundRectangle.java [195:258]
public boolean intersects(double x, double y, double w, double h) {
if (isEmpty() || w <= 0 || h <= 0) {
return false;
}
double x0 = getX();
double y0 = getY();
double x1 = x0 + getWidth();
double y1 = y0 + getHeight();
// Check for trivial rejection - bounding rectangles do not intersect
if (x + w <= x0 || x >= x1 || y + h <= y0 || y >= y1) {
return false;
}
double maxLeftCornerWidth = Math.max(ulWidth, llWidth) / 2d;
double maxRightCornerWidth = Math.max(urWidth, lrWidth) / 2d;
double maxUpperCornerHeight = Math.max(ulHeight, urHeight) / 2d;
double maxLowerCornerHeight = Math.max(llHeight, lrHeight) / 2d;
Zone x0class = classify(x, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
Zone x1class = classify(x + w, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
Zone y0class = classify(y, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
Zone y1class = classify(y + h, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
// Trivially accept if any point is inside inner rectangle
if (x0class == Zone.MIDDLE
|| x1class == Zone.MIDDLE
|| y0class == Zone.MIDDLE
|| y1class == Zone.MIDDLE) {
return true;
}
// Trivially accept if either edge spans inner rectangle
if ((close.contains(x0class) && far.contains(x1class))
|| (close.contains(y0class) && far.contains(y1class))) {
return true;
}
// Since neither edge spans the center, then one of the corners
// must be in one of the rounded edges. We detect this case if
// a [xy]0class is 3 or a [xy]1class is 1. One of those two cases
// must be true for each direction.
// We now find a "nearest point" to test for being inside a rounded
// corner.
if (x1class == Zone.CLOSE_INSIDE && y1class == Zone.CLOSE_INSIDE) {
// Potentially in upper-left corner
x = x + w - x0 - ulWidth / 2d;
y = y + h - y0 - ulHeight / 2d;
return x > 0 || y > 0 || isInsideCorner(x, y, ulWidth / 2d, ulHeight / 2d);
}
if (x1class == Zone.CLOSE_INSIDE) {
// Potentially in lower-left corner
x = x + w - x0 - llWidth / 2d;
y = y - y1 + llHeight / 2d;
return x > 0 || y < 0 || isInsideCorner(x, y, llWidth / 2d, llHeight / 2d);
}
if (y1class == Zone.CLOSE_INSIDE) {
// Potentially in the upper-right corner
x = x - x1 + urWidth / 2d;
y = y + h - y0 - urHeight / 2d;
return x < 0 || y > 0 || isInsideCorner(x, y, urWidth / 2d, urHeight / 2d);
}
// Potentially in the lower-right corner
x = x - x1 + lrWidth / 2d;
y = y - y1 + lrHeight / 2d;
return x < 0 || y < 0 || isInsideCorner(x, y, lrWidth / 2d, lrHeight / 2d);
}