矩形どうしの引き算

# 矩形どうしの引き算をするプログラム
　対象の矩形から、ある矩形でくり抜いて、対象の矩形上にある残りの領域を返すプログラムです。
例えば、

①下の図（左）の「黒矩形」マイナス「青矩形」
⇒緑矩形が出力される。
実際の計算としては、以下となる。矩形はひとつである。

`[0,0,20,20] - [10,0,20,20] = [[0,0,10,20]]`
※[xmin, ymin, xmax, ymax]

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/7bc93128-89aa-d2dd-2df3-a04b224f4135.png)

②下の図（左）の「黒矩形」マイナス「青矩形」
⇒緑矩形が出力される。
実際の計算としては、以下となる。矩形が4つに分かれる。

`[0,0,20,20] - [5,5,15,15] = [[0,0,5,20], [15,0,20,20], [5,0,15,5], [5,15,15,20]]`
※[xmin, ymin, xmax, ymax]
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/c39b2aa2-0f4d-c635-656b-06f75942d1ad.png)


# ソースコード
```ruby:minusBox.py
def minusBox(minusedBox:list, minusBox:list):

    xmin1 = minusedBox[0]
    ymin1 = minusedBox[1]
    xmax1 = minusedBox[2]
    ymax1 = minusedBox[3]

    xmin2 = minusBox[0]
    ymin2 = minusBox[1]
    xmax2 = minusBox[2]
    ymax2 = minusBox[3]

    if xmax1 > xmin2 and xmax2 > xmin1 and ymax1 > ymin2 and ymax2 > ymin1:
        pass
    else:
        #print("boxs don't cross!")
        return None

    # search containing point
    delBox_direH, delBox_direV = None, None
    
    # search horizon
    if(xmin1 < xmin2  and xmin2 < xmax1):
        delBox_direH = "r"
    if(xmin1 < xmax2 and xmax2 < xmax1):
        delBox_direH = "l"
    if(xmin1 < xmin2 and xmax2 < xmax1):
        delBox_direH = "i"
    if(xmin2 <= xmin1 and xmax1 <= xmax2):
        delBox_direH = "c"

    # search vertical
    if(ymin1 < ymin2 and ymin2 < ymax1):
        delBox_direV = "d"
    if(ymin1 < ymax2 and ymax2 < ymax1):
        delBox_direV = "u"
    if(ymin1 < ymin2 and ymax2 < ymax1):
        delBox_direV = "i"
    if(ymin2 <= ymin1 and ymax1 <= ymax2):
        delBox_direV = "c"

    # triming boxes
    deledBoxs = []
    if(delBox_direH == "r"):
        deledBoxs.append([xmin1, ymin1, xmin2, ymax1])
        if(delBox_direV == "u"):
            deledBoxs.append([xmin2,ymax2,xmax1,ymax1])
        if(delBox_direV == "d"):
            deledBoxs.append([xmin2,ymin1,xmax1,ymin2])
        if(delBox_direV == "i"):
            deledBoxs.append([xmin2,ymin1,xmax1,ymin2])
            deledBoxs.append([xmin2,ymax2,xmax1,ymax1])
        if(delBox_direV == "c"):
            pass
        
    if(delBox_direH == "l"):
        deledBoxs.append([xmax2, ymin1, xmax1, ymax1])
        if(delBox_direV == "u"):
            deledBoxs.append([xmin1, ymax2, xmax2, ymax1])
        if(delBox_direV == "d"):
            deledBoxs.append([xmin1, ymin1, xmax2, ymin2])
        if(delBox_direV == "i"):
            deledBoxs.append([xmin1, ymin1, xmax2, ymin2])
            deledBoxs.append([xmin1, ymax2, xmax2, ymax1])
        if(delBox_direV == "c"):
            pass
            
    if(delBox_direH == "i"):
        deledBoxs.append([xmin1, ymin1, xmin2, ymax1])
        deledBoxs.append([xmax2, ymin1, xmax1, ymax1])
        if(delBox_direV == "u"):
            deledBoxs.append([xmin2, ymax2, xmax2, ymax1])
        if(delBox_direV == "d"):
            deledBoxs.append([xmin2, ymin1, xmax2, ymax1])
        if(delBox_direV == "i"):
            deledBoxs.append([xmin2, ymin1, xmax2, ymin2])
            deledBoxs.append([xmin2, ymax2, xmax2, ymax1])
        if(delBox_direV == "c"):
            pass
    
    if(delBox_direH == "c"):
        if(delBox_direV == "u"):
            deledBoxs.append([xmin1, ymax2, xmax1, ymax1])
        if(delBox_direV == "d"):
            deledBoxs.append([xmin1, ymin1, xmax1, ymin2])
        if(delBox_direV == "i"):
            deledBoxs.append([xmin1, ymin1, xmax1, ymin2])
            deledBoxs.append([xmin1, ymax2, xmax1, ymax1])
    
    return deledBoxs

# box:[xmin, ymin, xmax, ymax]
p = [0, 0, 20, 20]
n = [5, 0, 20, 20]
print(p,"-",n,"=",minusBox(p,n))

p = [0, 0, 20, 20]
n = [5, 5, 15, 15]
print(p,"-",n,"=",minusBox(p,n))

```

# 計算結果
　最初に述べた「例①と②」の結果が得られるのが分かる。

```ruby:result
[0, 0, 20, 20] - [5, 0, 20, 20] = [[0, 0, 5, 20]]
[0, 0, 20, 20] - [5, 5, 15, 15] = [[0, 0, 5, 20], [15, 0, 20, 20], [5, 0, 15, 5], [5, 15, 15, 20]]
```