简体   繁体   中英

Find minimal overlapping shared surface in 2D

Consider a single square centered at (0.5, 0.5) with known size ( 0.2 ). I generate N squares more of identical sizes, by randomly shifting the original one a small quantity in x and in y.

What I need is to find the minimal overlapping region between all these squares. This is, I need its center coordinates (referenced to the reference square), and its height and width.

在此处输入图片说明

I've been playing with this for a while and I've found no easy way to do it. Any help will be much appreciated.


import numpy as np
from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle
from itertools import cycle

xc, yc = 0.4, 0.4
plt.figure()
currentAxis = plt.gca(aspect='equal')
currentAxis.add_patch(Rectangle((xc, yc), 0.2, 0.2, fill=None, alpha=1, lw=2.))
plt.scatter(0.5, 0.5)
print("Reference square centered at (0.5, 0.5)")

cols = ['r', 'b', 'g', 'm', 'c']
col_cyc = cycle(cols)
for _ in range(4):
    xs, ys = np.random.uniform(-0.1, 0.1, 2)
    print("Square {} shifted by: {:.3f}, {:.3f}".format(_, xs, ys))
    currentAxis.add_patch(
        Rectangle((xc + xs, yc + ys), 0.2, 0.2, fill=None, alpha=1,
                  color=next(col_cyc)))
plt.xlim(0.2, 0.8)
plt.ylim(0.2, 0.8)
plt.show()

If I understood it, what you want is the intersecting region of all the squares you generate.

In this case, the intercting region is the rectangle with position (max(xs), max(ys)) and size (0.2 - (max(xs)-min(xs)), 0.2 - (max(xs)-min(xs)).

In your code:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle
from itertools import cycle

xc, yc = 0.4, 0.4
plt.figure()
currentAxis = plt.gca(aspect='equal')
currentAxis.add_patch(Rectangle((xc, yc), 0.2, 0.2, fill=None, alpha=1, lw=2.))
plt.scatter(0.5, 0.5)
print("Reference square centered at (0.5, 0.5)")

xs_list = []
ys_list = []

cols = ['r', 'b', 'g', 'm', 'c']
col_cyc = cycle(cols)
for _ in range(4):
    xs, ys = np.random.uniform(-0.1, 0.1, 2)
    xs_list.append(xs)
    ys_list.append(ys)
    print("Square {} shifted by: {:.3f}, {:.3f}".format(_, xs, ys))
    currentAxis.add_patch(
        Rectangle((xc + xs, yc + ys), 0.2, 0.2, fill=None, alpha=1,
                  color=next(col_cyc)))

# This is the actual intersecting region
currentAxis.add_patch(
        Rectangle((max(xs_list)+xc, max(ys_list)+yc), 0.2 - (max(xs_list)-min(xs_list)), 
                    0.2 - (max(ys_list)-min(ys_list)), fill=True, alpha=1,
                      color=next(col_cyc)))

plt.xlim(0.2, 0.8)
plt.ylim(0.2, 0.8)
plt.show()

There you go

import numpy as np
#size of squares
size=0.2

#centers of all squares [x,y]
centers=[[0.5,0.5],
        [0.45,0.45],
        [0.6,0.6]]

centers=np.asarray(centers) #convert to numpy array

left_overlap=centers[::,0].max()-size #left border
right_overlap=centers[::,0].min()+size #right border
bottom_overlap=centers[::,1].max()-size #bottom border
top_overlap=centers[::,1].min()+size #top border

if left_overlap>right_overlap or bottom_overlap>top_overlap:
    print "No overlap"
else:
    x_center_overlap=(left_overlap+right_overlap)/2. #center x
    y_center_overlap=(bottom_overlap+top_overlap)/2. #center y

    print "Center of overlapping area is %s,%s"%(x_center_overlap,y_center_overlap)

Your maximum shifted square to the right gives your left coordinate, maximum shift to the top gives your bottom coordinate, etc.

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle
from itertools import cycle

xc, yc = 0.4, 0.4
plt.figure()
currentAxis = plt.gca(aspect='equal')
currentAxis.add_patch(Rectangle((xc, yc), 0.2, 0.2, fill=None, alpha=1, lw=2.))
plt.scatter(0.5, 0.5)
print("Reference square centered at (0.5, 0.5)")

cols = ['r', 'b', 'g', 'm', 'c']
col_cyc = cycle(cols)

x_crds=[]
y_crds=[]

for _ in range(4):
    xs, ys = np.random.uniform(-0.1, 0.1, 2)
    x_crds.append(xs)
    y_crds.append(ys)
    print("Square {} shifted by: {:.3f}, {:.3f}".format(_, xs, ys))
    currentAxis.add_patch(
        Rectangle((xc + xs, yc + ys), 0.2, 0.2, fill=None, alpha=1,
                  color=next(col_cyc)))
left  =np.max(x_crds)+xc
bottom=np.max(y_crds)+yc
right =np.min(x_crds)+xc+.2
top   =np.min(y_crds)+yc+.2

currentAxis.add_patch(
    Rectangle((left, bottom), right-left, top-bottom, fill=1, alpha=.5,
              color=next(col_cyc)))
plt.xlim(0.2, 0.8)
plt.ylim(0.2, 0.8)
plt.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM