Rectangle packing Python script

So I have tried to rewrite houdini vex script for rectangle packing found here http://www.natelapinski.com/2019/05/08/box-packing/

But my script does not work as shown in vex example. All rectangles travel away from center, even though there are no collisions. Any advice would be appreciated
Rectangle packing.gh (16.4 KB)
.
Rectangle packer

import Rhino.Geometry as rg  # Import Rhino geometry library
import random  # Import random module

def pack_squares(points, dimensions, iterations):
    pp = points[:]  # Copy the input points

    for q in range(iterations):  # Loop through the specified number of iterations    
        newP = rg.Point3d(0, 0, 0)  # Initialize a new point
    
        for i in range(len(points)):  # Loop through each point
            for j in range(len(points)):  # Loop through each point again (nested loop for pair-wise comparisons)
                p1 = pp[i]  # Current point
                dimen1 = dimensions[i]  # Dimensions of the current point (rectangle)

                p2 = pp[j]  # Another point for comparison
                dimen2 = dimensions[j]  # Dimensions of the other point (rectangle)

                min1 = p1 - dimen1  # Minimum point of the bounding box of the current point
                max1 = p1 + dimen1  # Maximum point of the bounding box of the current point

                min2 = p2 - dimen2  # Minimum point of the bounding box of the other point
                max2 = p2 + dimen2  # Maximum point of the bounding box of the other point
#                print(max2)

                x1min, x1max = min1.X, max1.X  # X min and max coordinates of the current point's bounding box
                z1min, z1max = min1.Z, max1.Z  # Z min and max coordinates of the current point's bounding box

                x2min, x2max = min2.X, max2.X  # X min and max coordinates of the other point's bounding box
                z2min, z2max = min2.Z, max2.Z  # Z min and max coordinates of the other point's bounding box
                #print(x1min, z1min, x2min, z2min)
                

                
                in_square = x1min <= x2max and x2min <= x1max and z1min <= z2max and z2min <= z1max  # Check if the rectangles intersect
                
                if in_square:
                    direction = rg.Vector3d(p1 - p2)  # Calculate the direction vector between the points
                    direction.Unitize()  # Normalize the direction vector
                    newP = p1 + direction * 0.1  # Move the current point away from the other point

                    # Move the point only if it does not collide with another square
#                    for k in range(len(points)):
#                        if k != i and rg.Point3d.DistanceTo(newP, pp[k]) < dimen1.Length + dimensions[k].Length:
#                            newP = p1  # Revert to the original position if collision detected
#                            print(dimen1.Length)
#                            break

                    pp[i] = newP  # Update the current point's position

    return pp  # Return the modified list of points




result = pack_squares(pts, dims, iters)  # Pack squares

Well … IF your goal is something like this:

and IF you want a result with some sort of real-life/pragmatic meaning (spot the colossal waste % that renders the whole approach useless) I would strongly advise to try to write code for something like this:

Using 500 rnd Rectangles:

Then packing’m in real-life “stripes” on some container available to market (like plywood, sheet metal, glass … etc etc):

Spot the waste %.

1 Like

Hmm, maybe I will look into this more. Currently I am mostly learning (the art of pointless) and thought it was interesting approach (in the vex script) to define rectangle position and size as vectors.

Anyway … real-life packing (i.e targeting minimum waste AND rational pieces production) is a big thing (in 1/2/3D). Thus I doupt that you can find high-perf solutions - for more than obvious reasons (but hope dies last).

Moral: the art of pointless (or not).