slothfulwave612
slothfulwave612

Reputation: 1409

Dividing a rectangle into NxM rectangle and numbering them in Python

So I have a rectangle of size 104x68 and I have divided the rectangle into 36 equal parts. The numbers in the image represent the coordinate location for each small rectangles.

enter image description here

Now I want to number each rectangle, something like the below image:

enter image description here

i.e.

For coordinate location x = [0, 17.3] and y = [0, 11.3] will be number 1 box
For coordinate location x = (17.3, 34.6] and y = [0, 11.3] will be number 2 box
....
For coordinate location x = (86.6, 104] and y = (56.6, 68] will be number 36 box

After numbering each of the boxes, I want that: given a value say (54,35) the program will yield the box number for that particular value, for the given value (54, 35) box number will be 22.

What is the optimized way of solving this problem in Python? Can somebody help?

Upvotes: 0

Views: 937

Answers (2)

OmG
OmG

Reputation: 18838

In the following, you can get the rectangle number by inputting the required parameters. weight and height show the dimensions of the rectangle (in your example, width = 104, height = 68). xpartition and ypartition parameters show the number of divisions in each dimension (in your example, 36 equally division means xpartition = 6, ypartition = 6). xinput and yinput are dimensions of the queried point which is desired to know its rectanlge number in the specified division (in your example, xinput = 54, yinput = 35).

import math
def get_rect_num(width, height, xpartition, ypartition, xinput, yinput):
    x_step = width / xpartition
    y_step = height / ypartition
    x = math.ceil((xinput if xinput > 0 else 0.5) / x_step) # handle border cases as well
    y = math.ceil((yinput if yinput > 0 else 0.5) / y_step)  # handle border cases as well
    return (y-1) * xpartition + x

get_rect_num(104, 68, 6, 6, 54, 35)

#> 22

The time complexity of the above computation is in Theta(1) based on the four primary operations.

Upvotes: 3

kd88
kd88

Reputation: 1204

Not the most optimised way (you could use itertools), but a fairly compact way to do this is just with numpy.arange. Assuming that this is your actual task, I can't see why the method would need to be more optimal than this.

import numpy as np 
SMALL_NUM = 1e-5 
def range_pairs(max_value, divisions): 
    division_length = max_value/divisions 
    range_values = list(np.arange(0, max_value+SMALL_NUM, division_length)) 
    return [(range_values[i], range_values[i+1]) for i in range(divisions)] 
 
i = 0 
for y in range_pairs(68, 6): 
    for x in range_pairs(104, 6): 
        i += 1 
        print(f"For coordinate location x = {x} and y = {y} will be number {i} box")

For larger tasks, consider itertools, and also consider pre-calculating the range_pairs below, or putting an lru_cache on the the range_pairs function.

Upvotes: 2

Related Questions