tag:support.nodebox.net,2012-11-01:/discussions/show-your-work/642-hilbert-nodeNodeBox: Discussion 2023-12-11T08:49:29Ztag:support.nodebox.net,2012-11-01:Comment/607865322023-11-15T05:05:41Z2023-11-15T05:17:08ZHilbert Node<div><p>FILL SHAPES WITH COOL FRACTAL PATTERNS!</p>
<p>ARRANGE OBJECTS IN A NEW WAY!</p>
<p>Attached is a demo of a new node: hilbert. The hilbert node creates a meandering path that fills an arbitrary rectangular area, and is based on the Hilbert Curve fractal. <strong>People using Nodebox to drive plotters may find it especially useful.</strong> Thanks to Ramanraj for suggesting this.</p>
<p>NOTE: this node requires an external Python module, gilbert2d.py, included in the zip file. The Nodebox code library module was adapted from code by Jakub Červený and was released under a BSD 2-Clause License (free for public use with copyright notice and disclaimers). For an explanation of the algorithm and licensing details see <a href="https://github.com/jakubcerveny/gilbert">https://github.com/jakubcerveny/gilbert</a></p>
<p>The hilbert node outputs a single, open, meandering line comprised of short line segments that turn at right angles (with one short diagonal line segment only in rare cases). The path Is comprised of square cells arranged in a grid of rows and columns. By specifying the number of columns and rows, and the length of the base segment, you can fill any rectangular space. You can then use a compound node to fill any other shape.</p>
<p>It's fast (up to a quarter million cells or so) and fun to play with. You can immediately see how it works by simply copying the node and adjusting the size values.</p>
<p>Hilbert takes four parameters:</p>
<ul>
<li><strong>Columns.</strong> The number of columns which determine the width of the rectangle.</li>
<li><strong>Rows.</strong>. The number of rows which determines the height of the rectangle</li>
<li><strong>Segment length.</strong>. The segment size in pixels which determines how tightly the pattern is packed.</li>
<li><strong>Corners only.</strong> Check this box to only include points in places where the curve turns. Leave it unchecked to include all points of the grid, even those at regular intervals along longer edges.</li>
</ul>
<p>In order to see the effect of the "Corners only" checkbox, turn on the Points checkbox above the rendering pane to see little blue dots whenever a point occurs in the path. Checking "Corners only" will reduce the total number of points without affecting the shape of the path. If you leave it unchecked and feed the hilbert node into a point node, you will get a perfect grid of points, just like the output of a grid node, but in a Hilbert Curve order (check Point Numbers above the render pane to see this order).</p>
<p>So you can also think of the hilbert node as an alternative to the grid node which can arrange objects in space in a way that keeps objects near each other in the list also near each other in space.</p>
<p>An easy way of appreciating this effect is shown in the demo. Take a list of squares colored along a color spectrum from red through yellow, green, and blue to violet. If you arrange these squares using a hilbert grid, you will see a more organic flow of color than you would get in a standard left-to-right, top-to-bottom grid. Crank up the number of columns and rows in the hilbert node to see an ever more subtle flow of color. Changing the ratio of columns to rows will also cause the path to meander in different ways. If you set the segment length to less than the square size, you will get a cool crinkling effect. The "Corners only" should remain unchecked for this use; if you check it you will create holes in the grid (which might also be kind of cool).</p>
<p>The top part of the demo shows how to use a hilbert curve to fill an arbitrary shape (in this case a circle). I intersect a hilbert-filled rectangle with a circle using a compound node. Although the result still shows as a single path, it is actually composed of multiple contours because sections of the path along the edge of the circle formed separate islands. To clarify this I use my contours node to reveal 16 separate paths, then create a table to sort by path length and lookup the longest path. I add a clean node at the end to tidy up minor artifacts along the outer edge produced by the compound node.</p>
<p>The hilbert node produces a Hilbert-like path, not a classic Hilbert Curve. A classic Hilbert Curve is a perfect square with sides that are powers of two (e.g. 32 x 32). If you set the column and row values to values like that, you will get a perfect Hilbert Curve. But if you supply different values, you will get curves which meander in the same way but fill arbitrary rectangles, even with odd sides. In certain cases (when the larger dimension is odd and the smaller is even) a single diagonal step cannot be avoided (for example, try 15x12).</p>
<p>The path created by the hilbert node always starts at the origin and proceeds to the right and down. If the number of rows is less than or equal to the number of columns, the path will start at the upper left of the rectangle and exit at the upper right. If there are more rows than columns, it will exit at the lower left instead. If you want to change which side the path starts and ends on, use rotate or reflect nodes.</p>
<p>For more about the Hilbert Curve, see: <a href="https://en.wikipedia.org/wiki/Hilbert_curve">https://en.wikipedia.org/wiki/Hilbert_curve</a></p>
<p>Hilbert will be added to the next release of the Cartan Node Library.</p>
<p>Enjoy!</p></div>johntag:support.nodebox.net,2012-11-01:Comment/607865322023-12-09T14:07:14Z2023-12-09T14:07:14ZHilbert Node<div><p>This is again a really cool node, John. It's fast, both in rendering and while plotting! Looking forward to trying the other recent new nodes.</p></div>florisdejongetag:support.nodebox.net,2012-11-01:Comment/607865322023-12-11T08:49:26Z2023-12-11T08:49:26ZHilbert Node<div><p>Thanks, Floris! I love what you did with it. Your inkblots are cool.</p>
<p>John</p></div>john