Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to divide a rectangle in specific number of rows and columns?

I am trying to divide a rectangle with specific coordinates into 8 smaller rectangles (two columns and four rows) is this possible?

Input for example would be:

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

and result would be:

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

This is what I've tried so far:

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)

This is what I need (kind of :/):

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
                         -----------
like image 474
Selman Avatar asked Oct 08 '19 09:10

Selman


People also ask

How do you divide a rectangle into a grid?

To activate the function, select your object and choose Object > Path > Split Into Grid. With the SIG dialog box open, you can change the number of Rows, number of Columns, Gutter dimensions and Illustrator will automatically calculate the height and width of the rectangles.

Can you divide a rectangle into 4 equal parts?

Well, if we divide a shape into four equal parts, we call each part a quarter. We have to divide our rectangle into four equal parts. We could start by dividing our rectangle into two equal parts, or halves. And then, we can halve each half.


2 Answers

If you work a lot with geometric objects you might consider using Shapely library. It has some useful functionality that we could use in order to construct a grid of smaller rectangles from the given rectangle.

First, constructing a Polygon from your list of tuples:

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)

This is your polygon:
enter image description here

Next, constructing a list of lines that we will use to split that polygon:

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

Applying each line to split the polygon:

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

This is how your resulting collection of rectangles will look like:
enter image description here

If you want a list of coordinates back, you can get them like this:

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)]]
like image 61
Georgy Avatar answered Nov 14 '22 21:11

Georgy


If you use the numpy library, the problem is greatly simplified using the linspace function which generates equally-spaced points.

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)
like image 35
wgb22 Avatar answered Nov 14 '22 21:11

wgb22