# Reducing a box while keeping its center?

So I have to draw a second box inside the original box but reduced by a factor. I have the first coordinates of the box and I have to calculate the new coordinates that would draw the new box.

``````def getCenter(coords):
coord1 = coords[0]
coord2 = coords[1]

x0 = coord1[0]
y0 = coord1[1]

x1 = coord2[0]
y1 = coord2[1]

middleX = (x0 + x1) / 2
middleY = (y0 + y1) / 2

return (middleX,  middleY)

def drawBox(t, coords):
coord1 = coords[0]
coord2 = coords[1]

x0 = coord1[0]
y0 = coord1[1]

x1 = coord2[0]
y1 = coord2[1]

t.up()
t.width(1)
t.goto(coord1)
t.down()
t.goto(x1, y0)
t.right(90)
t.goto(coord2)
t.right(90)
t.goto(x0, y1)
t.right(90)
t.goto(coord1)

def reduceSize(coords):
middle = getCenter(coords)
middleX = middle[0]
middleY = middle[1]
print(middle)

coord1 = coords[0]
coord2 = coords[1]

x0 = coord1[0]
y0 = coord1[1]

x1 = coord2[0]
y1 = coord2[1]

newX0 = x0 - (middleX * FACTOR)
newY0 = y0 - (middleY * FACTOR)
newX1 = x1 + (middleX * FACTOR)
newY1 = y1 + (middleY * FACTOR)

return ((newX0, newY0), (newX1, newY1))

FACTOR = 0.10
``````

So far I have this but it doesn't work for the 4 quadrants of a plot.

Edit: With the currend implementation it works with the coords((-150, 150), (0, 0)) and a factor of 0.90 but if I give it coords in other quadrant the center of the second box changes

• Please edit your question and define what you mean by "but it doesn't work". Do you get an error (if so include the full exception as code formatted text)? Do you get an incorrect or unexpected result (if so please describe exactly what does happen or provide a screenshot)? – user2856 Feb 15 '20 at 21:42

That's not the way to scale from the center.

You need to scale the difference between the corner and the middle point, and move that scaled difference to the middle:

``````    newX0 = (x0 - middleX) * FACTOR + middleX
newY0 = (y0 - middleY) * FACTOR + middleY
newX1 = (x1 - middleX) * FACTOR + middleX
newY1 = (y1 - middleY) * FACTOR + middleY
``````

I would recommend a different approach. Consider the following workflow:

1. Create a square buffer around a point
2. Create a second square buffer around a point with a scale factor applied

``````import pandas as pd
import geopandas as gpd
import geoplot as gplt

# The scale factor and buffer distance
BUFFER_DISTANCE = 3
FACTOR = 0.9

# Make up some data (https://geopandas.org/gallery/create_geopandas_from_pandas.html)
df = pd.DataFrame(
{'City': ['Buenos Aires', 'Brasilia', 'Santiago', 'Bogota', 'Caracas'],
'Country': ['Argentina', 'Brazil', 'Chile', 'Colombia', 'Venezuela'],
'Latitude': [-34.58, -15.78, -33.45, 4.60, 10.48],
'Longitude': [-58.66, -47.91, -70.66, -74.08, -66.86]})

# Convert pandas dataframe to geopandas geodataframe
gdf = gpd.GeoDataFrame(df, geometry = gpd.points_from_xy(df.Longitude, df.Latitude))

# Buffer the points n distance (note cap_style = 3 refers to square buffer)
buffers = gdf.buffer(BUFFER_DISTANCE, cap_style=3)

# Buffer the points by n distance and apply scale factor
buffers2 = gdf.buffer(BUFFER_DISTANCE * FACTOR, cap_style=3)

# Plot the results
ax = gplt.polyplot(buffers2, figsize=(10, 10))
gplt.polyplot(buffers, ax=ax)
``````