Estoy tratando de dividir un rectángulo con coordenadas específicas en 8 rectángulos más pequeños (dos columnas y cuatro filas) ¿es esto posible?

La entrada, por ejemplo, sería:

rec = [(0, 0), (0, 330), (200, 330), (200, 0)]

Y el resultado sería:

res = [[(0, 0), (0, 82), (100, 82), (100, 0)], [(0, 82), (0, 164), (100, 164), (100, 82)],.......]

Esto es lo que he intentado hasta ahora:

h = 330
w = 200

offsets = [(0, 0), (400, 0), (0, 500), (400, 500)]

blisters = []

for offset in offsets:
    pol = [(offset), (offset[0], offset[1] + h), (offset[0] + w, offset[1] + h), (offset[0] + w, offset[1])]
    blisters.append(pol)

pits = []

for offset in offsets:
    pit = [(offset), (offset[0], int(offset[1] + a)), (int(offset[0] + b), int(offset[1] + a)), (int(offset[0] + b), offset[1]), ]
    pits.append(pit)

Esto es lo que necesito (tipo de: /):

starting point in upper left corner (eg.(0,0)) 
                         ___________
                         I    I    I
                         I    I    I
                         -----------
                         I    I    I
                         I    I    I
                         -----------
                         I    I    I
                         I    I    I
                         -----------
                         I    I    I
                         I    I    I
                         -----------
5
Selman 8 oct. 2019 a las 12:31

3 respuestas

La mejor respuesta

Si trabaja mucho con objetos geométricos, puede considerar usar la Shapely biblioteca. Tiene alguna funcionalidad útil que podríamos usar para construir una cuadrícula de rectángulos más pequeños a partir del rectángulo dado.

Primero, construyendo un Polygon de su lista de tuplas :

from shapely.geometry import LineString, MultiPolygon, Polygon
from shapely.ops import split

rec = [(0, 0), (0, 330), (200, 330), (200, 0)]
nx, ny = 2, 4  # number of columns and rows

polygon = Polygon(rec)

Este es tu polígono:
ingrese la descripción de la imagen aquí

Luego, construyendo una lista de líneas que usaremos para split que polígono:

minx, miny, maxx, maxy = polygon.bounds
dx = (maxx - minx) / nx  # width of a small part
dy = (maxy - miny) / ny  # height of a small part
horizontal_splitters = [LineString([(minx, miny + i*dy), (maxx, miny + i*dy)]) for i in range(ny)]
vertical_splitters = [LineString([(minx + i*dx, miny), (minx + i*dx, maxy)]) for i in range(nx)]
splitters = horizontal_splitters + vertical_splitters

Aplicando cada línea para dividir el polígono:

result = polygon
for splitter in splitters:
    result = MultiPolygon(split(result, splitter))

Así es como se verá su colección resultante de rectángulos:
ingrese la descripción de la imagen aquí

Si desea una lista de coordenadas, puede obtenerlas así:

parts = [list(part.exterior.coords) for part in result.geoms]
print(parts)
# [[(0.0, 0.0), (0.0, 82.5), (100.0, 82.5), (100.0, 0.0), (0.0, 0.0)],
#  [(100.0, 82.5), (200.0, 82.5), (200.0, 0.0), (100.0, 0.0), (100.0, 82.5)],
#  [(0.0, 82.5), (0.0, 165.0), (100.0, 165.0), (100.0, 82.5), (0.0, 82.5)],
#  [(100.0, 165.0), (200.0, 165.0), (200.0, 82.5), (100.0, 82.5), (100.0, 165.0)],
#  [(0.0, 165.0), (0.0, 247.5), (100.0, 247.5), (100.0, 165.0), (0.0, 165.0)],
#  [(100.0, 247.5), (200.0, 247.5), (200.0, 165.0), (100.0, 165.0), (100.0, 247.5)],
#  [(0.0, 247.5), (0.0, 330.0), (100.0, 330.0), (100.0, 247.5), (0.0, 247.5)],
#  [(100.0, 330.0), (200.0, 330.0), (200.0, 247.5), (100.0, 247.5), (100.0, 330.0)]]
2
Georgy 8 oct. 2019 a las 10:46

¡Bienvenido a StackOverflow!

Es muy simple Simplemente divida sus límites en sus columnas y filas y luego repita sobre ellos:

cols, rows = 2, 4
width, height = 200.0, 330.0

w = width / cols
h = height / rows

result = []
for c in range(cols + 1):
    for r in range(rows + 1):
        result.append((c * w, r * h))

print result

# [(0.0, 0.0), (0.0, 82.5), (0.0, 165.0), (0.0, 247.5), (0.0, 330.0), 
# (100.0, 0.0), (100.0, 82.5), (100.0, 165.0), (100.0, 247.5), 
# (100.0, 330.0), (200.0, 0.0), (200.0, 82.5), (200.0, 165.0), 
# (200.0, 247.5), (200.0, 330.0)]
0
GV_FiQst 8 oct. 2019 a las 14:49

Si usa la biblioteca numpy, el problema se simplifica enormemente usando la función linspace que genera puntos igualmente espaciados.

import numpy as np

h = 330
n_rows = 4

w = 200
n_cols = 2

offset_x = w / n_cols
offset_y = h / n_rows

rectangles = []
for x in np.linspace(0, w, n_cols+1).tolist()[:-1]:
    for y in np.linspace(0, h, n_rows+1).tolist()[:-1]:
        x1 = int(round(x))
        x2 = int(round(x + offset_x))
        y1 = int(round(y))
        y2 = int(round(y + offset_y))
        rectangles.append([(x1, y1), (x1, y2), (x2, y2), (x2, y1)])

print(rectangles)
2
wgb22 8 oct. 2019 a las 10:20
58283684