なにかのまねごと

A Journey Through Imitation and Expression

四角形の重なり判定をするJavaアプレット

 昔どこかのWebで、四角形が重なっているかどうかを判定するアルゴリズムを考えよ、とかいう問題を見つけたので、自分なりに解いてみたやつ。もう4、5年前なので、ソースコード読んでも何がどうなってるのかよく分からんw
 とりあえず、非常に単純に、四角形の左下を原点としてその原点から伸びた辺が、sq1を基準にして考えるのだったらsq2の中に、sq2を基準にして考えるのだったらsq1の中に、入っているかどうかを判定してみただけみたいです。たぶんこの条件判定の部分の書き方が、java使いの方からしてみたらなんかむずがゆいはず。
 というか、よく見てみたらこれグローバル変数使いまくりで、実はとっても危ないプログラムなんじゃなかろーか…?あと、checkが関数である意味が無さげだなぁ…。

 CheckOver.javaで保存して下さい。

import java.applet.Applet;
import java.awt.*;

//<applet code="CheckOver.class" width="400" height="400"></applet>

class Square {
    Point pt = new Point(0, 0);
    Dimension size = new Dimension(0, 0);
    //int i;
    //各頂点の座標を入れた配列。
    //Point p = new Point(0,0);
    //Point[] pts = {new Point(0, 0), new Point(0,0), new Point(0,0), new Point(0,0)};
    //true なら位置をインクリメント そうでなければデクリメント
    boolean isXInc, isYInc;
    
    Square (int x, int y, int w, int h, boolean i) {
       this.pt.x = x;
       this.pt.y = y;
       this.size.width = w;
       this.size.height = h;
       this.isXInc = i;
       this.isYInc = i;
    }
}

public class CheckOver extends Applet implements Runnable {

    Square sq1 = new Square(30, 20, 70, 50, true);
    Square sq2 = new Square(50, 10, 20, 50, false);
    //true なら重なっている
    private boolean isOver = false;
    //true ならスレッドを停止
    private boolean isStop;
    
    public void check() {
        boolean checkX = false, checkY = false;
        
        if((sq1.pt.x >= sq2.pt.x) && 
        (sq2.pt.x + sq2.size.width >= sq1.pt.x))
            checkX = true;
        else if((sq2.pt.x >= sq1.pt.x) && 
        (sq1.pt.x + sq1.size.width >= sq2.pt.x))
            checkX = true;
        
        if((sq1.pt.y >= sq2.pt.y) &&
        (sq2.pt.y + sq2.size.height >= sq1.pt.y))
            checkY = true;
        else if((sq2.pt.y >= sq1.pt.y) &&
        (sq1.pt.y + sq1.size.height >= sq2.pt.y))
            checkY = true;
        
        if(checkX && checkY)
            isOver = true;
        else
            isOver = false;
    } 
    
    public void start() {
        isStop = false;
        
        Thread thread = new Thread(this);
        thread.start();
    }
    
    public void stop() {
        isStop = true;
    }
    
    public void run() { //新しいスレッドで呼び出すメソッド
        while(!isStop) {
            sq1.pt.x += sq1.isXInc ? 1 : -1;
            sq1.pt.y += sq1.isYInc ? 1 : -1;
            
            sq2.pt.x += sq2.isXInc ? 1 : -1;
            sq2.pt.y += sq2.isYInc ? 1 : -1;
            
            if (sq1.pt.x < 0)
                sq1.isXInc = true;
            else if (sq1.pt.x > getWidth() - sq1.size.width)
                sq1.isXInc = false;
            
            if (sq2.pt.x < 0)
                sq2.isXInc = true;
            else if (sq2.pt.x > getWidth() - sq2.size.width)
                sq2.isXInc = false;
            
            if (sq1.pt.y < 0)
                sq1.isYInc = true;
            else if (sq1.pt.y > getHeight() - sq1.size.height)
                sq1.isYInc = false;
                
            if (sq2.pt.y < 0)
                sq2.isYInc = true;
            else if (sq2.pt.y > getHeight() - sq2.size.height)
                sq2.isYInc = false;
            
            check();
            
            repaint();
            try {
                Thread.sleep(10);
            }
            catch(InterruptedException err) {
                System.out.println(err);
            }
        }
    }
    
    public void paint(Graphics g) {
        g.drawRect(sq1.pt.x, sq1.pt.y, sq1.size.width, sq1.size.height);
        g.drawRect(sq2.pt.x, sq2.pt.y, sq2.size.width, sq2.size.height);
        if(isOver) {
            g.drawString("good", 10, 10);
        }
    }
}

 で、実際に動かすにはこのコードをコンパイルしたのと同じディレクトリに、以下のhtmlファイルを置いて下さい。

<html>
<head>
<title>sample</title>
</head>

<body>
<div style="margin: auto; border: 1px solid #000; width: 400px; height: 400px;">
<applet code="CheckOver" width="400" height="400"></applet>
</div>
</body>
</html>