disassemble grid

tom's Avatar

tom

19 May, 2020 05:31 PM

hey,
what´s the easiest way to disassemble a grid randomly
into various squares and/or rectangles like shown in the picture?
Im trying to find a solution but it seems pretty difficult to me.

thanks in advance
tom

  1. Support Staff 1 Posted by john on 19 May, 2020 08:12 PM

    john's Avatar

    Tom,

    Your goal is indeed a bit trickier than it seems.

    It's easy to generate a list of randomly sized rectangles. Finding a list of randomly sized rectangles that fit perfectly into a larger rectangle is a harder problem.

    Most algorithms that do this require recursion. They subdivide the outer rectangle into smaller rectangles, then do the same to each of those, and so on until some limit is reached. Unfortunately NodeBox does not support recursion.

    What you are trying to do is similar to a treemap. Treemaps, essentially rectangular versions of pie charts, are used in information visualization. I do this all the time so made my own treemap custom node (included in my node library). Because the algorithm requires recursion, I had to use Python to make the custom node.

    I have attached an example NodeBox network with the treemap node included (see screenshot). I generate 12 random rectangles and fit them into an outer rectangle with the same dimensions as your example image. I color them with classic Mondrian colors to produce something similar to a Mondrian style drawing. You can change the seeds in the nodes defining the small rectangle sizes and the shuffling of the colors to try many variations.

    You will notice I said that this is similar to a Mondrian. The actual paintings Mondrian produced were not, of course, totally random. In addition to his careful balancing of color (with more white than other colors), he chose from a limited set of box sizes and was careful about the way he subdivided the grid.

    The treemap is not as careful about subdividing the grid. It does whatever it needs to do to pack all the rectangles perfectly into the assigned space. You can influence this by picking rectangle sizes more carefully. This may or may not be acceptable to you.

    If it's not, you need to think more clearly about exactly what constraints you want to place on the way you subdivide the grid. If you can describe those constraints I can help you find a way to implement them in Nodebox (even without recursion).

    Good luck and please consider sharing some of the designs you produce in our Show Your Work forum.

    John

  2. Support Staff 2 Posted by john on 19 May, 2020 08:58 PM

    john's Avatar

    Tom,

    Attached is a revised version of my Mondrian demo that comes a little closer to your example.

    I made two changes:

    • Instead of choosing 12 random sizes, I chose 12 sizes corresponding to your example.
    • I removed the automatic sorting from the treemap subnetwork so the sub-rectangles are no longer arranged from largest to smallest.

    This gets you slightly closer to what you want, but the grid is still not subdivided in a constrained way.

    John

  3. 3 Posted by tom on 20 May, 2020 01:43 AM

    tom's Avatar

    hey john,
    thank you for the fast reply!

    the mondrian approach and treemap are very interesting and i learnt a bit by exploring these nodes.
    i think it can lead me in the right direction.

    but what i am really trying to achieve is not just dissecting a single rectangle, rather a grid consisting of points into rectangles containing these points.

    these "point-groups" should be accessible in order to sort their content
    (in my case randomly sized squares on the grid)

    tom

    tom

  4. Support Staff 4 Posted by john on 20 May, 2020 08:57 AM

    john's Avatar

    Tom,

    I think a slight modification of my earlier example will do what you want.

    My solution (attached, see screenshot) starts with a grid of points, uses that to define a rectangle for my treemap node, then uses a snap node to snap the output back to the original grid.

    At the top of the network you will see five nodes that define the output:

    • rows: the number of rows in the grid (the number of vertical points)
    • columns: the number of columns in the grid (the number of horizontal points)
    • cell size: the separation between the points in the grid (this defines the minimum width and height of a box)
    • boxes: the number of rectangles that the gird will be divided into
    • seed: a random seed (change to try different sizes and arrangements)

    To clarify that the output really does produce the point groups you want within the original grid, I show both a Mondrian coloring of the boxes and an outline of the boxes superimposed over the dots of the grid.

    The ungrouped output of the snap grid is N rectangles. If you want the "point group" corresponding to each rectangle you can just attach each rectangle to a point node to get its four corner points. There are several ways to get the interior points if you want those as well - let me know if you have any trouble deriving them.

    The snap grid is a tad finicky. I used an align node set to left bottom to make sure the grid is not offset from the origin. Snap only has a single distance port, so vertical and horizontal grid spacing must be the same. If you need to have a vertical separation that differs from the horizontal separation, you can use a scale node to stretch or shrink the grid in one dimension after the snap is complete.

    Play with all five of the top nodes to see what kind of directions you get. If the distribution of box sizes is too even, you can replace the simple random node with something more complex. For example, you could produce one big box, a few medium sized boxes, and the rest small. Or explicitly define relative box sizes using a make_numbers node as I did in my second example.

    Let me know if this does what you need. Thanks for an interesting challenge!

    John

  5. 5 Posted by tom on 20 May, 2020 10:59 AM

    tom's Avatar

    wow john,
    thanks again for your fast and profound reply!

    to be honest, i´m even already having trouble outputting the n-rectangles from the ungrouped snap. it´s more than just adding a point and rect node, is it?

    extruding the interior points of the individual rectangles, would be the next big challenge for me.

    tom

  6. Support Staff 6 Posted by john on 21 May, 2020 05:50 AM

    john's Avatar

    Tom,

    Sorry - I didn't see your last note till just now.

    if you render the ungroup node just below the snap node and switch to data view you will see there are 12 paths corresponding to the 12 rectangles. You can feed them into a slice node and look at them one at a time to see which is which.

    If you hook a point node to that ungroup node you will get 48 points (4 for each rectangle). If you want to deal with one rectangle at a time, one way is to make a simple subnetwork. Hook a null node from the ungroup node, control-click it, and "Group into Network".

    You now have a subnetwork that fires once for each of the 12 rectangles feeding into it. If you "Edit Children" and look inside your subnetwork you can attach a point node to the null node and operate on its four corners. Or attach a centroid node to return the center position of each rectangle. Or resample the rectangle to create points around its perimeter. Or feed in the point ellipses through a new port (set to list so they come in all at once) and use a compound node to capture the intersection of your rectangle and the Grid points. Or whatever else you want to do.

    That is the question: what exactly do you want to do with each rectangle?

    John

    P.S. Just for fun I made an animation of Mondrian patterns (attached).

  7. 7 Posted by tom on 24 May, 2020 02:00 PM

    tom's Avatar

    hey john,
    no problem, thanks for your effort!

    i managed to make the subnetwork and extract the individual rectangles.
    i also managed to capture the intersection of rectangle and your ellipse based grid points.

    but what i´m struggling with, is doing the same with points values.
    especially extracting the points of the individual rectangles and those within (as seen in the picture of my first post)

    to answer your question:
    i have this grid filled with about 2500 individually sized rectangles.

    because this already gives me a kind of three-dimensional impression, i´m trying to provoke it a bit more.
    my idea was to seperate the whole grid into rectangles, like you did with the treemap. and then sort the rectangles within by size, starting from the centerpoint of a tile to the borders

    cheers
    tom

  8. Support Staff 8 Posted by john on 24 May, 2020 09:33 PM

    john's Avatar

    Hi Tom,

    I have attached another version which decomposes each rectangle into a mini-grid of interior cells (see screenshot).

    To demonstrate I show the Mondrian decomposition superimposed on the mini-grids on the left, with an exploded view of the mini-grids on the right. There are 50 boxes and a total of 2500 individual cells.

    The interior_grid subnetwork takes each rectangle and spits out an array of square-shaped cells which fill that rectangle as a grouped geometry. If you want the actual points you can ungroup and take the centroids.

    I don't quite follow what you are trying to do, but I hope this will get you one step closer.

    I am enjoying this. Please let me know if there's anything else you need.

    John

Reply to this discussion

Internal reply

Formatting help / Preview (switch to plain text) No formatting (switch to Markdown)

Attaching KB article:

»

Already uploaded files

  • grid_rect.png 10.3 KB

Attached Files

You can attach files up to 10MB

If you don't have an account yet, we need to confirm you're human and not a machine trying to post spam.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac

Recent Discussions

13 Jul, 2020 03:13 AM
07 Jun, 2020 04:08 AM
04 Jun, 2020 11:48 PM
25 May, 2020 09:13 PM
24 May, 2020 09:33 PM