我正在使用Java,我正在尝试检测ovale与矩形的交集。
我最初使用Intersect就足够了:
Shape rect = new Rectangle2D.Double(ant.getPosX(), ant.getPosY(), 5, 5);
for (Shape obstacle : obstaclesShape) {
if(obstacle.intersects(rect.getBounds())){
System.out.println("Boom");
}
}
barriersShape是椭圆形的ArrayList。
Shape oval = new Ellipse2D.Double(getRandomX(), getRandomY(), obstacle.getRandomWidth(), obstacle.
this.obstaclesShape.add(oval);
但使用这种方法不够可靠。事件似乎几乎是随机触发的。
所以我问自己,使用数学并确定省略号边框的位置会不会更好?我想是由角度和高度/宽度决定的东西。
问题是如何确切地确定它?它的公式是什么?或者有更好的方法吗?
答案 0 :(得分:1)
是的,值得应用一些数学并找出椭圆是否与矩形相交。
让矩形具有角(x0,y0)和(x1,y1),椭圆具有中心(cx,cy),水平半轴a
,垂直半轴b
。
首先我们可以进行仿射变换以简化计算 - 我们将椭圆变换为半径为1的以原点为中心的圆。矩形也将变换,并且交点事实不会改变。
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
现在我们可以应用described here approach来查找原点(圆心)和矩形之间的距离。如果它小于1,则对象确实相交。
略微修改的功能(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;