 # Python Help! Stuck with one rectangle...trying to create offsets

Hi everyone,

Not getting any errors but I’ve tried both + and * and still not getting the nesting square effect.

Essentially I am trying to recreate this artwork. https://thomafoundation.org/artwork/transformations/

Can someone tell me what’s missing? Is it just my line 31?

Much appreciated!

If rect is a list, you need to “append” any rectangle to it at line 31.

I attempted practically exactly the same thing about a year ago in Python. My goal was then to animate Vera Molnár’s artwork.

Here’s my script, if you’re interested:

``````import Rhino.Geometry as rg
from ghpythonlib import treehelpers
import random
import math

def construct_square_grid(plane, size, extendx, extendy, padding=0):
"""Creates a two-dimensional grid of square cells.

Args:
plane (Rhino.Geometry.Plane): Base plane for the grid
size (int|float): Size of the grid cells
extendx (int): Number of grid cells in the base plane x-direction
extendy (int): Number of grid cells in the base plane y-direction
by default 0, which means no padding

Returns:
A list of grid cells as polylines.
"""
xform = rg.Transform.PlaneToPlane(rg.Plane.WorldXY, plane)
grid = []
for y in range(extendy):
for x in range(extendx):
pt1 = rg.Point3d(
x * size + padding * x,
y * size + padding * y,
0
)
pt2 = rg.Point3d(
(x + 1) * size + padding * x,
(y + 1) * size + padding * y,
0
)
rectangle = rg.Rectangle3d(rg.Plane.WorldXY, pt1, pt2)
rectangle.Transform(xform)
grid.append(rectangle.ToPolyline())
return grid

def random_vector2d(plane=rg.Plane.WorldXY, scale=1.0):
"""Returns a random, two-dimensional vector that can optionally
be scaled to a desired magnitude. If no scale is provided
a unit vector of magnitude 1.0 is returned."""
theta = random.uniform(0, 2 * math.pi)
x = math.cos(theta)
y = math.sin(theta)
vec = rg.Vector3d(x, y, 0)
vec.Unitize()
if scale != 1.0:
vec *= scale
xform = rg.Transform.PlaneToPlane(rg.Plane.WorldXY, plane)
vec.Transform(xform)
return vec

def distort(polyline_crv, dmin=0, dmax=1):
"""Randomly distorts a polyline curve.

Args:
plane:
polyline_crv (Rhino.Geometry.PolylineCurve): Polyline Curve to distort
dmin (int|float): Optional minimum distortion radius, by default 0.0
dmax (int|float): Optional maximum distortion radius, by default 1.0

Returns:
The distorted polyline curve on success, otherwise the initial curve.
"""
if not isinstance(polyline_crv, rg.PolylineCurve):
return polyline_crv

rc, plane = polyline_crv.TryGetPlane()
if not rc:
return polyline_crv

pline = polyline_crv.ToPolyline()
if pline is None:
return polyline_crv

for i in range(pline.Count-1):
rscale = random.uniform(dmin, dmax)
pline[i] += random_vector2d(plane, rscale)

if polyline_crv.IsClosed:
pline[pline.Count-1] = pline

return pline.ToPolylineCurve()

# ------------------------------------------------------------------------------

if __name__ == "__main__":
if Seed is not None:
random.seed(Seed)

grid = construct_square_grid(Plane, Size, ExtendX, ExtendY, Padding)

transformations = []

for cell in grid:
prev_crv = cell.ToPolylineCurve()
sub_cells = [prev_crv]

for i in range(Count-1):
offset_crv = prev_crv.Offset(Plane, -Padding, 0.01, 0)
if offset_crv is not None:
offset_crv = offset_crv
if not isinstance(offset_crv, rg.PolylineCurve):
break
if not offset_crv.IsClosed or offset_crv.PointCount != 5:
break

prev_crv = offset_crv

if i == Index:

sub_cells.append(offset_crv)

transformations.append(sub_cells)

# Outputs
Curves = treehelpers.list_to_tree(transformations)
``````

transformations_2019.gh (11.2 KB)

1 Like

Thanks for your response! While I have figured it out it’s always nice to see the different approaches! Really appreciate you sharing this! Cheers Noted! Thank you Tom