C# 在两个简单矩形之间进行边缘检测的最快算法。
给定两个简单的矩形:C# 在两个简单矩形之间进行边缘检测的最快算法。,c#,math,collision,C#,Math,Collision,给定两个简单的矩形: class Rectangle { int x; int y; int width; int height; } Rectangle a; Rectangle b; 以及以下列举: [Flags] enum Edges { None, Top, Bottom, Left, Right, Inside, } 检测矩形a上被矩形b碰撞的边的最快方法是什么 Edges e = EdgeDetec
class Rectangle
{
int x;
int y;
int width;
int height;
}
Rectangle a;
Rectangle b;
以及以下列举:
[Flags]
enum Edges
{
None,
Top,
Bottom,
Left,
Right,
Inside,
}
检测矩形a上被矩形b碰撞的边的最快方法是什么
Edges e = EdgeDetect(a, b);
首先,您必须明确定义枚举的值,以使标志正常工作。在您的情况下,
Left==Top+Bottom+None
。以下是一个可能的声明:
[Flags]
public enum Edges
{
None = 0,
Top = 1,
Bottom = 2,
Left = 4,
Right = 8,
Identical = Top + Bottom + Left + Right,
Inside = 16,
Covers = 32
}
接下来,介绍边缘碰撞检测的可能实现。注意,我使用内置的System.Drawing.Rectangle
,而不是重写类。直接的优点是Intersect
方法的可用性:
public static Edges DetectEdgesCollision(Rectangle a, Rectangle b)
{
var result = Edges.None;
if (a == b) return Edges.Identical;
b.Intersect(a);
if (b.IsEmpty) return Edges.None;
if (a == b) return Edges.Covers;
if (a.Top == b.Top && (a.Right >= b.Right && a.Left<=b.Left ))
result |= Edges.Top;
if (a.Bottom == b.Bottom && (a.Right >= b.Right && a.Left<=b.Left ))
result |= Edges.Bottom;
if (a.Left == b.Left && (a.Bottom >= b.Bottom && a.Top <= b.Top))
result |= Edges.Left;
if (a.Right == b.Right && (a.Bottom >= b.Bottom && a.Top <= b.Top))
result |= Edges.Right;
return result == Edges.None ? Edges.Inside : result;
}
检测到公共静态边碰撞(矩形a、矩形b)
{
var结果=边。无;
如果(a==b)返回边。相同;
b、 交集(a);
如果(b.IsEmpty)返回边。无;
如果(a==b)返回边缘。覆盖;
如果(a.Top==b.Top&&(a.Right>=b.Right&&a.Left=b.Right&&a.Left=b.Bottom&&a.Top=b.Bottom&&a.Top首先,您必须明确定义枚举的值,以使标记正常工作。在您的情况下,Left==Top+Bottom+None
。下面是一个可能的声明:
[Flags]
public enum Edges
{
None = 0,
Top = 1,
Bottom = 2,
Left = 4,
Right = 8,
Identical = Top + Bottom + Left + Right,
Inside = 16,
Covers = 32
}
接下来是边缘碰撞检测的可能实现。请注意,我使用内置的System.Drawing.Rectangle
而不是重写类。直接的优势是Intersect
方法的可用性:
public static Edges DetectEdgesCollision(Rectangle a, Rectangle b)
{
var result = Edges.None;
if (a == b) return Edges.Identical;
b.Intersect(a);
if (b.IsEmpty) return Edges.None;
if (a == b) return Edges.Covers;
if (a.Top == b.Top && (a.Right >= b.Right && a.Left<=b.Left ))
result |= Edges.Top;
if (a.Bottom == b.Bottom && (a.Right >= b.Right && a.Left<=b.Left ))
result |= Edges.Bottom;
if (a.Left == b.Left && (a.Bottom >= b.Bottom && a.Top <= b.Top))
result |= Edges.Left;
if (a.Right == b.Right && (a.Bottom >= b.Bottom && a.Top <= b.Top))
result |= Edges.Right;
return result == Edges.None ? Edges.Inside : result;
}
检测到公共静态边碰撞(矩形a、矩形b)
{
var结果=边。无;
如果(a==b)返回边。相同;
b、 交集(a);
如果(b.IsEmpty)返回边。无;
如果(a==b)返回边缘。覆盖;
如果(a.Top==b.Top&&(a.Right>=b.Right&&a.Left=b.Right&&a.Left=b.Bottom&&a.Top=b.Bottom&&a.Top快速=小代码,或者,快速=快速?还有:x,y是一个角点还是中点?内部的边是什么,因此,如果我投票否决这个问题,我仍在苦苦挣扎。但是,如果你向我们提供你自己的实现,社区会很高兴地查看你的代码并提出一些改进建议。@Doc:我怀疑这意味着b
完全被a
包围(没有任何边直接相交)@Doc,而是数字(也称为声誉)hooingquick=little code,或者,quick=fast?还有:x,y是一个角还是一个中点?里面的边是什么?@Rob:那么“租码员”不是吗,因此,如果我投票否决这个问题,我仍在苦苦挣扎。但是,如果你向我们提供你自己的实现,社区会很高兴地查看你的代码并提出一些改进建议。@Doc:我怀疑这意味着b
完全被a
包围(没有任何边直接相交).@Doc,改为数字(也称声誉)Hooing您的代码只检测一条边相交。您不应该返回一条边,而应该在每个if中按位或按位返回。我假设,他需要另一条rectA从外部碰撞到rectB。根据Suggested修改代码您的代码只检测一条边相交。您不应该返回一条边,而应该在每个if中按位或按位返回。我假设,他需要另一条er rectA从外部碰撞到rectB。根据Suggested奇妙响应修改了代码Steve:)-这非常有效。唯一的小问题是,如果矩形B大于矩形A并完全覆盖它,则返回相同。可能它应该是“覆盖”或“吞没”而不是“相同”?谢谢。你说得对,我更新了代码。定义了新的枚举值Covered
,而DetectEdge
方法是轻微的ly更改为先检测相同,然后检测覆盖,然后检测每个边缘。还添加了一个新的测试。奇妙的响应史蒂夫:)-这非常有效。唯一的小问题是,如果矩形B大于矩形A并完全覆盖它,则返回相同。可能它应该是“覆盖”或“吞没”而不是“相同”?谢谢。你说得对,我更新了代码。定义了新的枚举值Covered
,而DetectEdge
方法是轻微的ly更改为先检测相同,然后检测覆盖,然后检测每条边。还添加了一个新的测试。