我试图做一个循环,它返回一个矩形是否碰撞,然后向哪个和弦移动该矩形。
我这样称呼我的职能:
rectangles2[i].rect = rectangleupdated(i, rectangles2);
这就是我的功能:
private Rectangle rectangleupdated(int i, List<rectList> rectangles2)
{
//fills rectangles with rectangles to check intersect with
BOTTOM = rectangles2[i].rect;
BOTTOM_LEFT = rectangles2[i].rect;
BOTTOM_RIGHT = rectangles2[i].rect;
//bool to be set to false if intersects returns true
bBOTTOM = true;
bBOTTOM_LEFT = true;
bBOTTOM_RIGHT = true;
//move the intersect rectangles
BOTTOM.Y++;
BOTTOM_LEFT.Y++;
BOTTOM_LEFT.X--;
BOTTOM_RIGHT.Y++;
BOTTOM_RIGHT.X++;
foreach (rectList rects in rectangles2)
{
if (!rects.type.Contains("bg"))
{
if (rectangles2[i].rect.Y < 500)
{
if (BOTTOM.IntersectsWith(rects.rect))
{
bBOTTOM = false;
}
else if (BOTTOM_LEFT.IntersectsWith(rects.rect))
{
bBOTTOM_LEFT = false;
}
else if (BOTTOM_RIGHT.IntersectsWith(rects.rect))
{
bBOTTOM_RIGHT = false;
}
}
else
{
return rectangles2[i].rect;
}
}
}
if (bBOTTOM == true) return BOTTOM;
else if (bBOTTOM_RIGHT == true) return BOTTOM_RIGHT;
else if (bBOTTOM_LEFT == true) return BOTTOM_LEFT;
return rectangles2[i].rect;
}
我想我知道为什么它会这么慢,但我不知道如何修复它/使这段代码更有用。
发布于 2014-05-13 12:39:51
你确定你真的应该在这里使用else if
吗?我认为你只需要使用if
。因为另一个rect可以同时与左下角和右下角同时碰撞。
if (BOTTOM.IntersectsWith(rects.rect))
{
bBOTTOM = false;
}
else if (BOTTOM_LEFT.IntersectsWith(rects.rect))
{
bBOTTOM_LEFT = false;
}
else if (BOTTOM_RIGHT.IntersectsWith(rects.rect))
{
bBOTTOM_RIGHT = false;
}
现在,我相信有一个更有效的方法来做到这一点。我想称之为..。
不要使用代码和测试冲突,而是使用Rectangle
对象上可用的更多数学和方法,并使用它们进行计算。
我相信你能做到这一点。我没有时间用C#计算出确切的代码(部分原因是我不是C#专家)。我不知道它会有多高的效率,我也不完全确定它是否会起作用,但我认为它应该是正确的,而且是有效的:
这里的想法是计算所有矩形交叉口的总和,你将通过移动得到。
MovingRect = the rectangle you want to move
MovingRect.y++
intersection = empty rectangle
for each (`rect` in all other rectangles) {
if (rect intersects with MovingRect) {
thisIntersection = calculate how much / where it intersects: See link below
intersection = union of intersection with thisIntersection: See link below
if the width of the intersection is two or more, then you can't move at all.
}
}
check the size and position of the `intersection` rectangle:
if it's size is nonexistent (i.e. empty rectangle), then you are free to move down one step
else if it's width is 2 or more, then you are unable to move at all
else if it's position is in the lower-left area of your rectangle, move right one step
else if it's position is in the lower-right area of your rectangle, move left one step
else throw an AssertionError because something is apparently wrong with this logic.
链接:
用于计算交叉口面积
对于矩形的合并
发布于 2014-05-12 20:27:52
我建议的唯一更改是,在不知道您试图完成什么任务的情况下,将一个条件添加到foreach循环的末尾(E:实际上,最好在条件符中的if之后添加一个条件,因为布尔值只有在代码执行、更新以反映这一点时才会有所不同):
if (rectangles2[i].rect.Y < 500)
{
...
if (!bBOTTOM && !bBOTTOM_RIGHT && !bBOTTOM_LEFT)
{ return rectangles2[i].rect; }
}
避免在矩形中循环,即使我们已经知道它没有空间。
至于剩下的事情,如果你不知道你想要完成什么,那就很难了。如果上面、左边或右侧的一个点完全打开,则算法只将矩形移动到一个新的空间中。这就是你需要的行为吗?还有其他算法可以工作,您可以使用这些算法简单地将所有矩形彼此移开,但不一定会在每次运行时进入一个空空间。会发生这样的事情:
foreach (rectList rects in rectangles2)
{
if (!rects.type.Contains("bg"))
{
if (rectangles2[i].rect.Y < 500)
{
if (rectangles2[i].rect.IntersectsWith(rects.rect))
{
Rectangle returnRect = rectangles2[i].rect;
if (rects.rect.X < rectangles2[i].rect.X)
{ returnRect.X++; }
else if (rects.rect.X > rectangles2[i].rect.X)
{ returnRect.X--; }
if (rects.rect.Y < rectangles2[i].rect.Y)
{ returnRect.Y++; }
else if (returnRect.Y > rectangles2[i].rect.Y)
{ returnRect.Y--; }
return returnRect;
}
}
}
}
return rectangles2[i].rect;
这将返回一个从与其相交的第一个矩形移开的矩形。这个调的东西可能比你使用的更快,这取决于它是否适合你的需要。
我还建议像rects这样的对象的公共属性(它似乎是'rectList‘类型的,但只有一个矩形与它关联?)在PascalCase中命名,要容易得多。
https://codereview.stackexchange.com/questions/49563
复制相似问题