负尺寸的矩形如何相交?

11

有人能解释一下为什么负大小的Rectangle会以这种方式相交吗?

var r  = new Rectangle(0, 0,  3,  3);
var r0 = new Rectangle(0, 0, -1, -1);
var r1 = new Rectangle(1, 1, -1, -1);
var r2 = new Rectangle(2, 2, -1, -1);
var r3 = new Rectangle(3, 3, -1, -1);

System.Console.WriteLine(r.IntersectsWith(r0)); // False
System.Console.WriteLine(r.IntersectsWith(r1)); // False
System.Console.WriteLine(r.IntersectsWith(r2)); // True
System.Console.WriteLine(r.IntersectsWith(r3)); // False

我认为r1r2应该总是与r相交,即使它们没有相交。如果考虑它们的负大小,r3应该相交。如果不考虑负大小,r0应该相交。

为什么会出现这种情况?在使用Rectangle结构时,还需要注意哪些陷阱呢?


我不知道... 我猜IntersectsWith对于负数大小的矩形是未定义的,尽管在API中没有这样记录...我建议你将这个问题发布到MSDN作为"社区内容"? 这是一个非常好的问题。有人怀疑,对于所有空间操作,负大小的矩形的行为都未被定义...它们甚至被渲染成你期望的吗? - corlettk
1
@corlettk:“社区内容”并不适合发布问题。这就是 MSDN 论坛的作用。 - Cody Gray
谢谢Cody。我从未使用过MSDN的论坛;-) - corlettk
2个回答

8
如果你创建一个宽度为负数的矩形,则会绘制一个从原始坐标(x,y)开始向左而不是向右绘制的矩形。
如果你创建一个高度为负数的矩形,则会绘制一个从原始坐标(x,y)开始向上而不是向下绘制的矩形。
因此,如果你创建一个宽度为-1,高度为-2的矩形,例如new Rectangle(5,4,-1,-2);,则会得到以下点的矩形:(5,4)、(4,4)、(5,2)、(4,2)。
运行以下代码以获取示例:
    Rectangle negWidthHeightRect = new Rectangle(5, 4, -1, -2);
    Console.WriteLine(negWidthHeightRect.Left);
    Console.WriteLine(negWidthHeightRect.Right);
    Console.WriteLine(negWidthHeightRect.Bottom);
    Console.WriteLine(negWidthHeightRect.Top);
    Console.WriteLine(negWidthHeightRect.Width);
    Console.WriteLine(negWidthHeightRect.Height);
    Console.ReadLine();

输出结果如下:
5
4
2
4
-1
-2

考虑到微软对其他类似矩形控件(除了System.Drawing.Rectangle)的评论,这种行为有些意料之中。请参阅MSDM 此处

现在,为什么矩形的IntersectsWith方法会产生如此奇怪的结果呢?这是因为它使用以下代码实现IntersectsWith方法:

public bool IntersectsWith(Rectangle rect)
{
    return ((((rect.X < (this.X + this.Width)) && (this.X < (rect.X + rect.Width))) && (rect.Y < (this.Y + this.Height))) && (this.Y < (rect.Y + rect.Height)));
}

如果你按照逻辑自己理解,你会明白为什么会得到你所得到的答案。微软应该采取以下措施之一:
1) 当遇到负宽度/高度时,将宽度/高度变为正数并调整左侧/顶部。
2) 或者在IntersectsWith逻辑中,在执行逻辑时进行一些Min(x,x+width)和Min(y,y+width)计算。
比我聪明的其他人可能会有更聪明的方法来处理这个问题。

0

请查看 此问题 答案的第一个评论。它似乎在说负高度和宽度表示在当前坐标点上方和左侧的象限中绘制的矩形。


这意味着 Rectangle(0, 0, -x, -x)Rectangle(-x, -x, x, x) 是相同的。 - Dan D.
@Dan D. 看起来这是真的。我完全惊讶于它甚至是有效的输入。他们在答案中谈论了ScreenToClientClientToScreen(我个人没有太多经验),这让我相信它是他们内部操作的一部分。 - jonsca
@Dan D. 这是否意味着 Rectangle(1, 1, -1, -1)Rectangle(0, 0, 1, 1) 是相同的?如果是,它仍然应该与 r 相交。 - dlras2
@Daniel Rasmussen Rectangle(-1,-1,-1,-1)Rectangle(0,0,1,1) 是相同的。 - jonsca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接