通过仅保留最大的圆来移除重叠的圆
Remove Overlapping Circles by Keeping Only Largest
给定一组具有随机中心和半径的圆,我希望能够修剪这组圆,这样如果圆之间发生重叠,则只保留最大的圆。这是一个与回答 的问题类似的问题,但据我了解,那里列出的问题旨在保留最大数量的非重叠圆圈。如果可能的话,我希望能够根据我的需要调整那里提供的 ILP 解决方案,尽管蛮力“搜索和删除”类型的方法也可以。后者是我迄今为止尝试过的,但未能完成。
import matplotlib.pyplot as plt
from numpy.random import rand, seed
seed(1)
N = 25 # number of circles
L = 10 # domain size
Rmin = 0.5 # min radius
Rmax = 1 # max radius
cx = rand(N)*(L-2*Rmax) + Rmax
cy = rand(N)*(L-2*Rmax) + Rmax
r = rand(N)*(Rmax-Rmin) + Rmin
# Plotting
for i in range(N):
plt.gca().add_artist(plt.Circle((cx[i], cy[i]), r[i], ec='black', fc='white'))
plt.axis('image')
plt.xlim(0,L)
plt.ylim(0,L)
plt.show()
想要的结果:
它有点乱,但这会创建您想要的输出。
import matplotlib.pyplot as plt
from numpy.random import rand, seed
import math
import numpy as np
import pandas as pd
def find_larger(df_circles_2, idx):
found_greater = False
for i,row in df_circles_2.iterrows():
if i != idx:
distance = math.sqrt( (row['x'] - df_circles_2['x'][idx])**2 + (row['y'] - df_circles_2['y'][idx])**2 )
if distance < (row['r'] + df_circles_2['r'][i]):
if row['r'] > df_circles_2['r'][idx] and (row['keep'] != "discard"):
if df_circles['keep'][i] == "keep":
return "discard"
found_greater = True
if found_greater:
return "undecided"
else:
return "keep"
seed(1)
N = 25 # number of circles
L = 10 # domain size
Rmin = 0.5 # min radius
Rmax = 1 # max radius
cx = rand(N)*(L-2*Rmax) + Rmax
cy = rand(N)*(L-2*Rmax) + Rmax
r = rand(N)*(Rmax-Rmin) + Rmin
# Plotting
for i in range(N):
plt.gca().add_artist(plt.Circle((cx[i], cy[i]), r[i], ec='black', fc='white'))
plt.gca().add_artist(plt.Text(cx[i], cy[i], text = str(i)))
plt.axis('image')
plt.xlim(0,L)
plt.ylim(0,L)
plt.show()
# Searching:
df_circles = pd.DataFrame(np.array([cx, cy, r]).T, columns = ['x', 'y', 'r'])
df_circles['keep'] = "undecided"
while(df_circles['keep'].str.contains('undecided').any()):
for i, row in df_circles.iterrows():
if row['keep'] == "undecided":
df_circles.at[i, 'keep'] = find_larger(df_circles, i)
# Plotting 2
plt.figure(2)
for i in range(N):
if df_circles['keep'][i] == "keep":
plt.gca().add_artist(plt.Circle((cx[i], cy[i]), r[i], ec='black', fc='black'))
else:
plt.gca().add_artist(plt.Circle((cx[i], cy[i]), r[i], ec='black', fc='white'))
plt.axis('image')
plt.xlim(0,L)
plt.ylim(0,L)
plt.show()
给定一组具有随机中心和半径的圆,我希望能够修剪这组圆,这样如果圆之间发生重叠,则只保留最大的圆。这是一个与回答
import matplotlib.pyplot as plt
from numpy.random import rand, seed
seed(1)
N = 25 # number of circles
L = 10 # domain size
Rmin = 0.5 # min radius
Rmax = 1 # max radius
cx = rand(N)*(L-2*Rmax) + Rmax
cy = rand(N)*(L-2*Rmax) + Rmax
r = rand(N)*(Rmax-Rmin) + Rmin
# Plotting
for i in range(N):
plt.gca().add_artist(plt.Circle((cx[i], cy[i]), r[i], ec='black', fc='white'))
plt.axis('image')
plt.xlim(0,L)
plt.ylim(0,L)
plt.show()
想要的结果:
它有点乱,但这会创建您想要的输出。
import matplotlib.pyplot as plt
from numpy.random import rand, seed
import math
import numpy as np
import pandas as pd
def find_larger(df_circles_2, idx):
found_greater = False
for i,row in df_circles_2.iterrows():
if i != idx:
distance = math.sqrt( (row['x'] - df_circles_2['x'][idx])**2 + (row['y'] - df_circles_2['y'][idx])**2 )
if distance < (row['r'] + df_circles_2['r'][i]):
if row['r'] > df_circles_2['r'][idx] and (row['keep'] != "discard"):
if df_circles['keep'][i] == "keep":
return "discard"
found_greater = True
if found_greater:
return "undecided"
else:
return "keep"
seed(1)
N = 25 # number of circles
L = 10 # domain size
Rmin = 0.5 # min radius
Rmax = 1 # max radius
cx = rand(N)*(L-2*Rmax) + Rmax
cy = rand(N)*(L-2*Rmax) + Rmax
r = rand(N)*(Rmax-Rmin) + Rmin
# Plotting
for i in range(N):
plt.gca().add_artist(plt.Circle((cx[i], cy[i]), r[i], ec='black', fc='white'))
plt.gca().add_artist(plt.Text(cx[i], cy[i], text = str(i)))
plt.axis('image')
plt.xlim(0,L)
plt.ylim(0,L)
plt.show()
# Searching:
df_circles = pd.DataFrame(np.array([cx, cy, r]).T, columns = ['x', 'y', 'r'])
df_circles['keep'] = "undecided"
while(df_circles['keep'].str.contains('undecided').any()):
for i, row in df_circles.iterrows():
if row['keep'] == "undecided":
df_circles.at[i, 'keep'] = find_larger(df_circles, i)
# Plotting 2
plt.figure(2)
for i in range(N):
if df_circles['keep'][i] == "keep":
plt.gca().add_artist(plt.Circle((cx[i], cy[i]), r[i], ec='black', fc='black'))
else:
plt.gca().add_artist(plt.Circle((cx[i], cy[i]), r[i], ec='black', fc='white'))
plt.axis('image')
plt.xlim(0,L)
plt.ylim(0,L)
plt.show()