DOBON.NET DOBON.NETプログラミング掲示板過去ログ

隣接する四角のIntersectsWithの戻り値

環境/言語:[C# .NET2.0]
分類:[.NET]

2つの四角形の重なりをIntersectsWithメソッドで判断していますが、
四角形が隣接する場合の戻り値はどうなるのでしょうか。
次の2つのケースではtrueとfalseを返します。

RectangleF rect1 = new RectangleF(142.9F, 113.0F, 25.0F, 2.0F);
RectangleF rect2 = new RectangleF(117.9F, 113.0F, 25.0F, 2.0F);
bool isIntersect = rect1.IntersectsWith(rect2); // true

RectangleF rect3 = new RectangleF(142.0F, 113.0F, 25.0F, 2.0F);
RectangleF rect4 = new RectangleF(117.0F, 113.0F, 25.0F, 2.0F);
bool isIntersect2 = rect3.IntersectsWith(rect4); // false

隣接する四角形にはIntersectsWithは使えないのでしょうか。
宜しくお願いします。
■No32159に返信(きしべいさんの記事)
> 2つの四角形の重なりをIntersectsWithメソッドで判断していますが、
> 四角形が隣接する場合の戻り値はどうなるのでしょうか。

Windows の整数の矩形は x = 100, width = 100 の場合、100 〜 199 が有効座標で 200 は範囲外です。このため、整数の矩形では x1 = 100, width1 = 100 / x2 = 200, width2 = 100 は重なりません。
これが基本的な考えだと思われます。


> 次の2つのケースではtrueとfalseを返します。

これは浮動小数が絡んでややこしいことになっているのではないかと予想されます。
Rectangle も RectangleF も手元のソースコードでは同じようです。
浮動小数による演算誤差の影響の可能性が高いと考えています。


以上のことから、隣接する矩形の判定に、IntersectsWith は使えないとお考えいただいた方がよいと思います。
■No32160に返信(Azuleanさんの記事)
> ■No32159に返信(きしべいさんの記事)

> 以上のことから、隣接する矩形の判定に、IntersectsWith は使えないとお考えいただいた方がよいと思います。

Azuleanさん有難う御座います。
RectangleFではIntersectsWithは使わないほうがいいようですね。
代わりに
if (rect1.Left < rect2.Right && rect2.Left < rect1.Right &&
rect1.Top < rect2.Bottom && rect2.Top < rect1.Bottom)
{
}
で判断することにしました。この場合は問題ないようです。
解決済み!
2014/02/16(Sun) 11:23:17 編集(投稿者)

「交差する矩形を判定したい」、そして「IntersectWith の不安定さを排除したい」ということが目的だったと考えてよいでしょうか?

ちなみに、その if 文を x86/Release で JIT 最適化有効状態では 142.9F のケースで True と判定されました。
(if ブロック内で return true;、ブロックの外で return false; するようなメソッドを作成した場合)

JIT 最適化を有効にするためには、Release 構成かつ、「デバッガで起動しないこと」か「デバッグオプションの JIT 最適化を抑制する設定を OFF にすること」のいずれかが必要です。
(「デバッガで起動しないこと」とは、Ctrl+F5、デバッグ - デバッグなしで起動、exe を直接起動といった方法のことです)

このように、浮動小数で頑張ろうとすると境界値付近で無理が出ます。
その性質を理解した上で利用してください。


(参考)
Ctrl+F5 で実験すると、x86/Debug, x64/Debug, x64/Release では false、x86/Release では true でした。
F5(デバッグ開始)では、x86/x64, Debug/Release の 4 つの組み合わせすべてで false でした。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板