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更改为先检测相同,然后检测覆盖,然后检测每条边。还添加了一个新的测试。