How can I develop a generative shape system ?
I am a Belgian student in typography. I really fell in love with nodbox!
I draw a lot of typography on grids. I would like to be able to generate some shapes on a grid.
I'm very inspired by Norm's work and their generative system, Sol le witt work (like variation of open cubes), and algorithmically generated typographic shapes. I'm trying to produce similar principles on nodebox
I tried to start with simple modular elements, but I can't, it seems very complex...
I would like to be able to generate an infinite number of shapes with my basic modules, by positioning them randomly in my grid (like on my last picture)
I have no idea of the logic I need to follow in nodebox to do this kind of thing, if anyone can give me some hints or enlighten me I'd love to hear from you!
Maybe nodebox is not really adapted for this kind of thing...
Thanks in advance for answer
(This message was translated with a translator, sorry for the potential problem of translation, I hope my message was clear)
Have a nice day!
- tumblr_m467vpb0pp1rnskdco2_1280-2.png 34.1 KB
- image-asset.png 195 KB
- Slanted-Shape-Grammars_06.jpg 159 KB
- Capture_d’écran_2021-12-24_à_05.16.53.png 128 KB
|?||Show this help|
|ESC||Blurs the current field|
|r||Focus the comment reply box|
|^ + ↩||Submit the comment|
You can use
Command ⌘ instead of
Control ^ on Mac
Support Staff 1 Posted by john on 24 Dec, 2021 08:15 AM
Welcome to Nodebox!
This is a really interesting problem, or rather problem space. It is definitely doable in Nodebox and should be a lot of fun.
The three examples you provide are each different. The first is straightforward. I could recreate Norm's system directly and produce every combination of a set of component line or curve segments. The basic technique would be to input a list of N segment shapes, generate all binary numbers from 0 to 2^N, and, for each binary number output segments corresponding to the one bits.
Sol LeWitt's system could be a simple extension of this technique using the twelve line segments of the isometric projection of a cube with additional constraints to cull some of the trivial or redundant patterns.
But that might miss the point. LeWitt was not just exhaustively generating permutations; he was creating specific arrangements in thought-provoking subgroups intended to be looked at from different angles. In other words, not a purely algorithmic construction (at least not a simple one). You could still play with that by generating a master list of possible open cube forms along with a table of properties, and then play with a series of algorithms acting on those properties to sift and sort and cull that list repeatedly to produce different interesting outputs.
Your third example seems like the one you are most interested in. This is quite doable in Nodebox and is similar in spirit to Truchet tiles. Making the tiles is easy. The problem is how to arrange them. Truchet tiles are in a simple fixed grid with a module at each grid position; you want something more complex with different-shaped modules and gaps here and there. You need to describe a more flexible system or grammar of possible arrangements.
NodeBox does have one serious limitation. It doesn't do recursion and, as a result, cannot directly create things like L-systems. You can find some conversation threads in the forum on this topic.
Where there's a will, however, there's always a way. I have demonstrated several techniques to create limited amounts of recursion entirely within Nodebox or by using a custom node. This case is simple enough to be tractable. So I think a simple system or grammar within certain limitations would be possible.
The more fundamental problem is: what, exactly, do you want to do? What framework would you like to work within?
I can think of several very different ways to fit modules together. You could take a binary random walk by generating a series of N bits, with 0 meaning curve left and 1 meaning curve right. Place the first white module at the origin, stick a red module on the end, and repeat using the last endpoint as the new origin. After a given length you could then draw an enclosing grid under the resulting path (you might wind up with an oblong grid).
OR, you could start with a grid of a fixed size and make individual placements which must fit entirely inside that grid. This would be more complex and might involve collision tests (which can be tricky).
These approaches are fairly specific to the modules referenced in your third example. You would probably like to develop a more general system. But this would involve choosing which degrees of freedoms you want to allow and what assumptions or constraints you want to make on possible module shapes.
I'm not sure how best to be of help here. If you like I can create some examples to get you started. I might use a node from the Cartan Node Library to generate binary numbers as that is an easy way to make combinations. You could then take my example, fiddle with it, try to push it a new direction and then come back when you get stuck. We could carry on a conversation like that as long as you want.
Let me know if I'm going too fast, too slow, or not being clear. I'll come back soon (Christmas holiday permitting) with at least one example and meanwhile can answer any questions you might have.
This looks like fun!
2 Posted by 0zera on 25 Dec, 2021 02:52 AM
Thank you for your very clear and complete answer, you help me a lot!
Thank you for taking your time to answer me!
I didn't know the principle of resurrection nor the "L system", it looks really exciting!
I fell in love with a book "Jannis Maroscheck: Shape Grammars" the idea of generating an infinity of shapes (organic, geometric...) with very simple rules fascinates me.
As a typographer, the idea of generating random typographic shapes, based on predefined rules captivates me. I stumbled upon Nodebox by chance, and initially thought it was the perfect software to generate the kind of shapes like in Shapes Grammars!
As a first project I wanted to start generating "all" the existing possibilities based on the modular typeface of a friend (on image 4), but I quickly realized that it was very complex, so I looked at simpler modules...
My final goal is to be able to create my own generative forms, with a certain number of well defined rules.
I'm currently asking myself if it's not better to generate this kind of shapes directly with Python or Processing, without going through nodebox, since the recursion is complex managed in nodbox. The notion of collision seems to me to be a real complex, and I wonder if it would not be easier in Python
I didn't give up on Nodebox though, and I started trying to make simple randomly generated paths on a grid.I don't know if I worked in the most efficient way( my node workflow is certainly not the cleanest) I did it with my current knowledge of the software.
After several hours of work, and with the help of your message, I found a first solution, I send you some captures and my nodebox file!
( for the moment, my generative path is not yet perfect, it is not yet generated on the whole grid)
Thank you again for taking your time to answer me, you answer many questions that have been on my mind for a long time!
Have a great christmas!
Support Staff 3 Posted by john on 26 Dec, 2021 03:55 AM
Good to hear from you again! I've been distracted by holiday festivities but should be able to focus on this very interesting conversation this weekend.
I am attaching my own version of the random walk network you sent. There is nothing wrong with your network; I just thought you might appreciate seeing how I would attack the same challenge. My random walk network starts at the upper left corner and randomly moves either right or down. See attached network and screenshot.
My version is customizable and extensible. You can set any line segment length and any number of segments. The grid will expand to include the extent of the walk. As you did, I tied the seed to the frame node so that each frame produces a different walk. I numbered my segments at the beginning of each segment instead of the end as you did (but this would be easy to change if you care).
As you probably noticed, a random walk has a kind of recursive nature, since each new segment begins where the previous one leaves off. I was able to get around that in this case by taking advantage of the rigid form of this walk. Since each segment is either right or down based on a randomly generated set of bits, I was able to predict the starting positions of each segment in advance by simply keeping a running total of the zeroes and ones. So a single line_angle node was able to produce all the segments at once.
I turned the two settings green to make them easier to find. Just drag to change the value of either one to see how the display reacts.
For my next trick I will create a node for you that produces all combinations of any set of shapes feed in as a list. You can then use that in your future explorations.
I am confident that I could recreate some version of your friend's modular typeface. The trick is define a set of rules that produce not every possible combination of strokes or curves, but rather a subset based on some principles about how and where elements are allowed to connect. By varying these rules you could produce a number of similar typefaces.
I also saw Maroscheck's book. It looks fabulous! I can see why you found it so interesting.
It's a fair question whether you should tackle this in Nodebox, Processing, or Python. I have worked in all three and prefer Nodebox because A) I grew weary of debugging long blocks of text with errant braces and semi-colons, and B) I love the way Nodebox encourages play. With Nodebox you can click on any node and drag parameters to get immediate feedback on what the overall network will display. I find this highly addicting.
Please keep playing and writing. I will return soon with further experiments.
Support Staff 4 Posted by john on 26 Dec, 2021 01:34 PM
As promised, here is the demo of a combos node that takes a list of paths and outputs every possible combination of those paths. This demo is NOT general purpose; it will produce groups of combined paths for any input list, but will only correctly trace certain kinds of paths (paths that are all line segments emanating from a shared central point, like the 8 spokes like Norm and Jurg's Sign Generator).
As you can see, it's very simple. The complexity is hidden inside some subnetworks and sub-subnetworks. I used several nodes from my Node Library (available in the forum for use without restriction) including a base conversion node that requires a custom Python module (included in the zip file).
I'm not sure how familiar you are with subnetworks and custom nodes. You can look inside subnetworks like combos and trace by selecting them, right/control clicking, and choosing "Edit Children" from the menu.
The combos node is fairly simple. It reads in a list of paths (in this example the 8 spokes), computes binary numbers from (in this case) 0 to 255, and uses the one bits as a mask to generate each possible combination of those paths.
As a student of typography you will appreciate that these combination groups are not true characters. In this case each combo is a set of overlapping rectangles with many interior points and unsightly notches or extrusions in some cases. What we want instead is a smooth shape outlined with one continuous, clockwise path. This is what the trace node produces.
You can see an example of one such combination in my first attached screenshot (which has the points and point numbers turned on). On the left is a magnified version of one combo with three spokes including interior points and a notch. On the right is this same combo fed into the trace node, which produces a single, clean, clockwise outline of a single character. Change the value in the number1 node to compare different characters.
Unlike the combos node, this trace node is not general purpose. It assumes that each path represents a straight spoke emanating from the center and arranged in clockwise order. If you were to feed in curving paths or paths that did not radiate from the same center, it would make a mess of things.
So the next step would be to make a more general purpose trace node. This will be difficult, in part because it may be ambiguous how to correctly connect some path combinations. Part of the art of typography is defining the various ways components can come together as gracefully and cleanly as possible. Combining various lumps of clay is easy; sculpting each pile into an artistic final shape is the hard part.
Meanwhile, we do have a replication of Norm's original Sign Generator example - see second screenshot. I drew the 256 characters with thin blue outlines to prove that each is a single fillable, strokable shape.
Feel free to create other lists of paths to feed into the combos node to see what happens. You may need to remove the trace node to get a reasonable output. Choosing a set of component paths and looking at all possible combinations should help you see the gaps between the rough assemblies and the final polished outlines. If you can define clear rules to determine those outlines in every case it should be possible to generate them with Nodebox. I think you would find this process much harder in Processing and even worse in Python.
I will keep thinking about this. Please respond with questions/comments.
5 Posted by 3Cat on 20 Feb, 2022 01:16 PM
A simple set of shape generation using a polygon and a square to delete the points of the polygon. Distributed on a grid. Not exactly an infinite number of shapes can be made, but perhaps this well help with new ideas.
Support Staff 6 Posted by john on 21 Feb, 2022 06:01 AM
This is way cool! It's simple idea, but opens up many new possibilities. Thank you!
Building on your idea, I made a character maker node. Feed it:
The char_maker node will return all possible combinations of bars eating away each side. For triangles, it will produce 8 shapes (2^3), for squares, 16 shapes (2^4), etc. My demo also comes with a gallery node that arranges the characters in a nice chart.
(And, unlike my previous combos node, char_maker does not require any external code libraries.)
You can try even more combinations by reducing the percentage from 100 to remove narrower bars. Not every character shape will be a keeper, but by turning the knobs you can quickly scan the possibilities for inspiration.
Support Staff 7 Posted by john on 21 Feb, 2022 06:15 AM
As an added bonus, I adjusted char_maker to carve up an octagon using only diagonal bars. This produces a chart similar to the one 3Cat created, but containing all 16 possibilities.
8 Posted by edgeofinnerspac... on 13 Apr, 2023 11:02 PM
im thinking though, it would be much easier doing this stuff in nodebox than a graphics editor. i mean this stuff this thread inspired:
doubt the original poster is going to see this though. was just trying to return the inspiration.
"liquid" i can see being simple in nodebox. but the 'tradetactics' might be harder. the hardest part in the vector software was mainly just tedious. it was lining up all the letters on a decently visually pleasing diagonal and sizing them as such. ....because as i didnt preplan the design it involved a bunch of redundant edits. i think it goes back to the variables concept in my other post.
Support Staff 9 Posted by john on 14 Apr, 2023 02:54 AM
I agree: pieces like this are much easier to make in Nodebox than in a graphics editor.
The two pieces you shared are fun and interesting. In Nodebox you could define each character as a path and place them precisely using grids or sampled lines or stacks. You could make a node which would take any string (e.g. "liquid" or "Trade Tactics") and automatically render the corresponding paths and place them instantly.
Even better, you could use that initial placement as a scaffold and then elaborate it further - like adding pixelized color gradients or whatever. Nodebox is particularly good at generating text paths using any font and then manipulating those paths in an infinite number of ways.
I wish the typography student who started this thread would return and continue this conversation. We only scratched the surface of what's possible.