我写了一个名为Shape的对象,它有一个代表topLeftCorner的点和一个代表其宽度和高度的维度。要获得右上角,我可以简单地将宽度添加到topLeftPoint.x。我习惯于围绕它们的中心旋转一定程度。旋转后的问题是,我的intersects(Shape)
方法失败了,因为它不支持形状的旋转。每个形状的旋转将是相同的。我当前的实现在我的形状对象中如下所示:
public boolean intersects(Shape s){
// functions returning a Point of shape s
return intersects(s.topLeft())
|| intersects(s.topRight())
|| intersects(s.bottomLeft())
|| intersects(s.bottomRight())
|| intersects(s.leftCenter())
|| intersects(s.rightCenter())
|| intersects(s.center());
}
public boolean intersects(Point p){
return p.x >= leftX()
&& p.x <= rightX()
&& p.y >= topY()
&& p.y <= bottomY();
}
基本上我需要像rotatedLeftX()
或rotatedTopRight()
这样的功能才能正常工作。同样对于该计算,我认为在 ie 90 旋转之前的左上点何时变成右上角并不重要......
我已经在这里阅读了这个问题和这个问题,但并不完全理解。
我修改了Stackoverflow中的算法,以执行您为我编写的战舰游戏使用矩形指示的操作。 这是代码:
private boolean overlaid(int [][][] shps, int curr)
{
for (int i = curr-1; i>=0; --i)
{
// From: http://stackoverflow.com/questions/306316/determine-if-two-rectangles-overlap-each-other/306332#306332
// if (RectA.X1 < RectB.X2 && RectA.X2 > RectB.X1 &&
// RectA.Y1 < RectB.Y2 && RectA.Y2 > RectB.Y1)
if (shps[curr][0][1] <= shps[i][1][1] &&
shps[curr][1][1] >= shps[i][0][1] &&
shps[curr][0][0] <= shps[i][1][0] &&
shps[curr][1][0] >= shps[i][0][0])
return true;
}
return false;
}
private int [][][] shps = { {{-1,-1},{-1,-1}},
{{-1,-1},{-1,-1}},
{{-1,-1},{-1,-1}} };
shps
参数只是一个矩阵,使用 {x0,y0}, {x1,y1} 指示每个矩形的左上角和右下角的位置。 例如,shps[curr][0][1]
== 当前shp
的 y0。 出于我的目的,我不得不使用 <= 和>=。 此外,如果您使用屏幕坐标与笛卡尔坐标,则必须注意 y 的反面。 还有德摩根定律,如果你想使用不叠加。
我有一个解决方案:
假设我想计算形状的旋转(90 度),其中 x =1、y=1(左上点)、宽度为 4、高度为 6 围绕其中心 (3, 4) == (x1, y2)
rotatedX = x1 + cos(q) * (x - x1) - sin(q) * (y - y1)
rotatedY = y1 + sin(q) * (x - x1) + cos(q) * (y - y1)
在这种情况下:
rotatedX = 3 + cos(90) * (1 - 3) - sin(90) * (1 - 4)
rotatedY = 4 + sin(90) * (1 - 3) + cos(90) * (1 - 4)
这是针对笛卡尔平面上的旋转(其中正旋转值表示逆时针旋转)
因此,如果您想顺时针旋转 90 度,您只需将旋转乘以 -1;