2つのRectangleが重なるか判定する - C#

2つのRectangleが重なるか判定するコードを紹介します。

概要

Rectangle同士が重なっているかを判定するには、RectangleクラスのIntersectsWith()メソッドを利用すると簡単です。

書式

[Rectangleオブジェクト].IntersectsWith([重なりを判定するRectangleオブジェクト]);
2つのRecangleに重なりがある場合は、IntersectsWith() メソッドの戻り値が true になります。 重なりがない場合は戻り値は false となります。

プログラム

UI

下図のUIを作成します。フォームにLabelを一つ配置します。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RectangleIntersection
{
  public partial class FormIntersectRect : Form
  {
    Rectangle[] rect;
    Point sp = new Point();
    int target=0;
    bool MouseDownFlag = false;
    Rectangle OldBand = new Rectangle(0,0,0,0);

    public FormIntersectRect()
    {
      InitializeComponent();
      rect = new Rectangle[2];
      for (int i=0; i<rect.Length; i++){
        rect[i] = new Rectangle();
      }
    }

    private void FormIntersectRect_Load(object sender, EventArgs e)
    {

    }

    private void FormIntersectRect_MouseDown(object sender, MouseEventArgs e)
    {
      sp.X = e.X;
      sp.Y = e.Y;
      MouseDownFlag = true;
    }

    private void FormIntersectRect_MouseMove(object sender, MouseEventArgs e)
    {
      if (MouseDownFlag == true) {
        Point ScreenP = this.PointToScreen(sp);

        ControlPaint.DrawReversibleFrame(OldBand, Color.White, FrameStyle.Dashed);

        Rectangle r = new Rectangle(ScreenP.X, ScreenP.Y, e.X - sp.X, e.Y - sp.Y);
        ControlPaint.DrawReversibleFrame(r, Color.White, FrameStyle.Dashed);
        OldBand = new Rectangle(ScreenP.X, ScreenP.Y, e.X - sp.X, e.Y - sp.Y);

      }
    }

    private void FormIntersectRect_MouseUp(object sender, MouseEventArgs e)
    {
      rect[target].X = sp.X;
      rect[target].Y = sp.Y;
      rect[target].Width = e.X - sp.X;
      rect[target].Height = e.Y - sp.Y;

      if (target == 0) {
        target = 1;
      }
      else {
        target = 0;
      }
      MouseDownFlag = false;
      OldBand = new Rectangle(0, 0, 0, 0);
      this.Invalidate();

      if (rect[0].IntersectsWith(rect[1]) == true) {
        label1.Text = "矩形は重なっています。";
      }
      else {
        label1.Text = "矩形は重なっていません。";
      }
    }

    private void FormIntersectRect_Paint(object sender, PaintEventArgs e)
    {
      e.Graphics.DrawRectangle(new Pen(Color.Blue), rect[0]);
      e.Graphics.DrawRectangle(new Pen(Color.Red), rect[1]);
    }

  }
}

解説

ドラッグするごとに、2つのRectangleを切り替えて座標を設定する動作になっています。
Rectangleの座標設定時に2つのRectangleが重なっているかを判定し上部のLabelに交差状態のメッセージを表示します。
ドラッグ時のラバーバンドはControlPaint.DrawReversibleFrame()メソッドを利用して描画します。DrawReversibleFrame()で描画した線は、再度、同じ位置に描画すると消去できるため、直前に描画した位置を記録しておき、次回の描画の際には直前の線を消去したのち、新しいバンドを描画します。
2つの矩形は、Paintイベントで描画しています。ドラッグ終了後にすぐに画面に反映されるよう、MouseUpイベントではInvalidate()メソッドを呼び出し画面の更新をしています。

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


ウィンドウ内でマウスの左ボタンを押してドラッグします。ドラッグ中は下図の点線のラバーバンドが表示されます。(注意:このプログラムでは、左上から右下方向へのドラッグ処理しか記述していません。右上方向にドラッグしないようにしてください。)


マウスのボタンを離しドラッグを終了すると、葵枠が描画されます。


同じ手順で別の場所をドラッグします。


2回目は赤い枠で描画されます。青の枠と、赤の枠が重なっていないため、上部に「矩形は重なっていません。」のメッセージが表示されます。


赤い矩形と重なるようにドラッグします。


葵枠がドラッグした位置に移動します。2つの矩形が重なっているため、「矩形は重なっています。」のメッセージに変わりました。


枠の位置を変更します。上部のメッセージが矩形の重なり状態に応じて変更されることが確認できます。


Rectangleの重なり判定ができました。

著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2014-10-27
iPentec all rights reserverd.