Reputation: 5640
I'm working with Java and I am trying to detect the intersection of an ovale with a rectangle.
I tough at first using Intersect would be sufficient :
Shape rect = new Rectangle2D.Double(ant.getPosX(), ant.getPosY(), 5, 5);
for (Shape obstacle : obstaclesShape) {
if(obstacle.intersects(rect.getBounds())){
System.out.println("Boom");
}
}
obstaclesShape is an ArrayList of oval shape.
Shape oval = new Ellipse2D.Double(getRandomX(), getRandomY(), obstacle.getRandomWidth(), obstacle.
this.obstaclesShape.add(oval);
But using this method is not reliable enough. The event seems to be triggered almost randomly.
So I was asking myself wouldn't it be better to use mathematic and determine the position of the border of my ellipsis? Something which would be determine by the angle and height / width I guess.
The thing is how to determine it precisely? What is the formula for it? Or is there a better way?
Upvotes: 1
Views: 570
Reputation: 80187
Yes, it is worth to apply some math and find whether your ellipse intersects rectangle.
Let rectangle has corners (x0,y0) and (x1,y1) and ellipse has center (cx, cy), horizontal semi-axis a
, vertical sem-axis b
.
At first we can make affine transformation to simplify calculations - we transform ellipse into origin-centered circle with radius 1. Rectangle will transform too, and intersection fact does not change.
With such transform we apply shift by (-cx,-cy), scaling by `1/a` in OX direction and scaling by `1/b` in 0Y direction. After that rectangle will have coordinates
xxx0 = (x0-cx) / a
yyy0 = (y0-cy) / b
xxx1 = (x1-cx) / a
yyy1 = (y1-cy) / b
Now we can apply described here approach to find a distance between origin (circle center) and rectangle. If it less than 1, objects do intersect.
Slightly modified function (Delphi)
function RectDistanceToZeroLessThan1(RR: TRect): Boolean;
var
wh, hh, dx, dy, t, SquaredDist: Double;
begin
SquaredDist := 0;
//width and height
wh := RR.Right - RR.Left;
hh := RR.Bottom - RR.Top;
//doubled rectangle center coordinates
dx := - (RR.Left + RR.Right);
dy := - (RR.Top + RR.Bottom);
//rectangle sides divide plane to 9 parts,
t := dx + wh;
if t < 0 then
SquaredDist := t * t
else begin
t := dx - wh;
if t > 0 then
SquaredDist := t * t
end;
t := dy + hh;
if t < 0 then
SquaredDist := SquaredDist + t * t
else begin
t := dy - hh;
if t > 0 then
SquaredDist := SquaredDist + t * t
end;
Result = SquaredDist <= 4 // due to removed 0.5 coefficients
end;
Upvotes: 1