Packing objects on tiling patterns

calendar_today

02.11.2023

label

Modeling

mouse

Houdini 19.5

1 Description

A packing procedure for placing and individually rotating packed objects onto a partitioned floor pattern to avoid intersections. Parameters for scaling and offsetting the pattern, cell padding and the maximum rotation angle.

2 Code discussion

The pattern code is taken from this example: https://procegen.konstantinmagnus.de/non-overlapping-tiles
The pcfind-function is used to select objects that match the individual tile sizes: pcfind(1, 'shape', size, 10.0, 10);

// PARAMETER
float pad = chf('padding');
float angle_max = chf('max_angle');

// SIZE
vector size = getbbox_size(0, itoa(i@primnum));
size -= set(pad, 0.0, pad);

// ANGLE
float angle = (rand(i@primnum, 123) - 0.5) * angle_max * 2.0;
float theta = radians(angle);
float cos_theta = abs(cos(theta));
float sin_theta = abs(sin(theta));

// ROTATED SIZE
float x = size.x * cos_theta + size.z * sin_theta;
float z = size.x * sin_theta + size.z * cos_theta;
vector size_rot = set(x, 0.0, z);
float s = min(size.x / size_rot.x, size.z / size_rot.z);
size *= s;

// FIND SIMILAR SIZES
int num = npoints(1);
int pts[] = pcfind(1, 'shape', size, 10.0, 10);

// FIND BEST MATCH
int pt_near = -1;
foreach(int pt; pts){
    vector shape_pt = point(1, 'shape', pt);
    if(shape_pt.x < size.x && shape_pt.z < size.z){
        
        // NAME
        string name = itoa(pt);
        int pt_add = addpoint(0, v@P);
        setpointattrib(0, 'name', pt_add, name, 'set');
        
        // ORIENTATION
        matrix3 m = ident();
        rotate(m, theta, {0,1,0});
        vector4 orient = quaternion(m);
        setpointattrib(0, 'orient', pt_add, orient, 'set');
        
        // GROUP
        setpointgroup(0, 'pivots', pt_add, 1, 'set');

        break;
    }
}
download

downloads