Dashed Lines

john's Avatar

john

05 Jul, 2024 07:23 AM

NOTE - This initial version has a bug. Download v2 (below) instead.

Attached is a node I've been meaning to make for years: dashed_line.

Dashed_line takes any path or group of paths and replaces solid lines with dashed lines. It will preserve the color (if any) of the original paths, and use the strokeWidth to determine the thickness of the dashes. Uncolored paths will produce black dashes with a thickness of one.

You can adjust the dashes by changing dash length and interval length. The actual dash lengths produced may vary slightly depending on the lengths of all the segments in the path. The node adjusts the dashes so that they start precisely at the start of each segment (regardless of thickness), end precisely at the end of each segment, and all have the same length. Complex paths with multiple segments may appear to have different dash sizes because dashes at each joint may appear to merge.

When using resampled paths, the dash length must be less than the resample length. For best results, try adjusting both the dash and interval lengths until you get a pattern you like.

The computations involved in creating these dashes are surprisingly complex. As a result, this node can bog down if you give it too many paths at once, or a textpath with many words. The dashes are actually rectangles and each path is output as a group.

As always, please play with this thing and let me know if you run into any trouble or have questions or suggestions. Dashed_line will be included in the next release of my library.

Enjoy!

John

  1. 1 Posted by lastvector on 07 Jul, 2024 07:14 PM

    lastvector's Avatar

    Hi John

    Tried the Dashed Line graphics possibilities a bit :)

    thank you
    gottfried

  2. 2 Posted by lastvector on 07 Jul, 2024 07:27 PM

    lastvector's Avatar

    two other tries

    gottfried

  3. Support Staff 3 Posted by john on 08 Jul, 2024 12:16 AM

    john's Avatar

    Gottfried,

    Wow! I am really impressed. Each one is simple and elegant done with ordinary lines, but taken to a new level using dashed lines.

    And this is just the beginning of what's possible. Thank you!

    John

  4. 4 Posted by florisdejonge on 08 Jul, 2024 05:26 PM

    florisdejonge's Avatar

    Great node John! Can't believe it didn't exist yet. In Gottfried application it opens up all kinds op possibilities for types of grids, which is really cool!

  5. 5 Posted by lastvector on 08 Jul, 2024 06:52 PM

    lastvector's Avatar

    John, florisdejonge

    ...it opens up all kinds op possibilities for types of grids...
    and also something like this. The Dash could be replaced with any
    kind of Object in this case a Star. I use also Johns Color Node

    gottfried

  6. 6 Posted by lastvector on 08 Jul, 2024 09:12 PM

    lastvector's Avatar

    another one

  7. Support Staff 7 Posted by john on 09 Jul, 2024 05:22 AM

    john's Avatar

    Gottfried, Floris,

    Thanks. Glad you are enjoying it.

    Attached is another experiment that took me only a minute to make. I just wanted to see what would happen if I attached a balloons node to a dashed_line node. It's a tad slow - but it worked! I also showed how to thicken and color the dashes for each balloon, all using only six nodes.

    Gottfried is right: you can easily turn the dashes into other shapes. I just posted an animation to my Instagram portfolio, Windjammers, that was inspired by Gottfried's simple copied triangles. I did all sorts of things with the dashes, including playing with color cycling:

    https://www.instagram.com/p/C9J5JK3Otc2/

    I am curious to see what Floris and his magical plotter can do with these dashes!

    John

  8. 8 Posted by lastvector on 09 Jul, 2024 06:27 AM

    lastvector's Avatar

    John

    Cool :)
    I thought that's what it looks like
    when vague ideas are bubbling / ballooning in my head

    The Windjammer Idea is also nice
    looks really like a Sail

    gottfried

  9. Support Staff 9 Posted by john on 11 Jul, 2024 06:13 PM

    john's Avatar

    UPDATE

    I just found - and fixed - a small bug. When fed a group instead of just a path (like the balloons), it was making multiple copies of the dashes. Because they were perfectly superimposed, it looked OK. FIXED.

    Revised version of dashed_line attached (with Gottfried-inspired demo). Until the next rev of my library comes out, please use this version.

    John

  10. 10 Posted by lastvector on 11 Jul, 2024 08:13 PM

    lastvector's Avatar

    thanks, John

    I had an idea when I updated the dashed line node,
    but I'm not sure if I'm maybe overthinking it here.

    My thought was, how about putting the release date
    or a version number in the Comment Line of your Node?

    That way a user could know which Node Version they are using.
    Just an idea, you can ignore it if that make no sense from your point of view.

    Thanks for the bug fix
    gottfried

  11. Support Staff 11 Posted by john on 12 Jul, 2024 12:40 AM

    john's Avatar

    Gottfried,

    Floris suggested something similar a long time ago and I've actually been doing that ever since.

    Each time I release a new version of my library, if any existing nodes were updated I add a version notation to the front of the node comment, e.g. v3.3 for any updates made for library release 3.3. So if you ever wonder if a node you are using is the latest version, look at its comment and compare it to the comment from the same node in the latest version of my library. If the node in the latest library has no version prefix in its comment, the original node is still up to date.

    I have NOT been doing this for the "preview" nodes I post in the forum before the next release of my library, however. I sometimes find a bug before the node is officially published for the first time (as happened today with dashed_line). If so I update the announcement in the forum. But I don't start adding version numbers to the comment until after the node is officially published in the library.

    I realize this could cause some confusion for changes that occur before the node is officially published for the first time, but I hope this confusion will be fleeting. I suppose I could start using more complex version IDs, with the first part being the library release and the a sub-part referring to multiple changes made within or before that release, but I'm trying to keep things simple.

    Version 3.4 of my library should be coming out fairly soon.

    John

  12. 12 Posted by lastvector on 12 Jul, 2024 03:06 AM

    lastvector's Avatar

    John

    Thank you for the information. I have no problem
    with the way you want to handle this and your reasons
    make sense to me.

    If I find it necessary, I can add to the comment myself.

    Thank you again
    greetings

    gottfried

  13. 13 Posted by lastvector on 12 Jul, 2024 03:13 AM

    lastvector's Avatar

    John

    Oh, did I already tell you that I find your Node library
    really impressive? I'm excited about the new version

    gottfried

  14. 14 Posted by florisdejonge on 12 Jul, 2024 03:27 PM

    florisdejonge's Avatar

    Hi John and Gottfried,

    Thanks for the comments. I would love to plot some designs with the dash-node. Unfortunately, the dash is actually a rectangle and the plotter would draw the outline. So, I've adapted the node a bit, thereby messing up the controls I guess. To plot it, the dash would have to consist of a line with the width represented by the strokeWidth. Would that be possible?

    Floris

  15. Support Staff 15 Posted by john on 13 Jul, 2024 06:05 AM

    john's Avatar

    Floris,

    Thanks for raising this. It should have occurred to me that rectangular dashes would not be plotter-friendly.

    The reason I used rectangles instead of lines is that rectangles (filled but with no stroke) can be precisely positioned, whereas lines will vary slightly in apparent size and position depending on strokeWidth.

    The real problem with lines is the endpoints, sometimes called the caps. When you increase stroke width to thicken line-based dashes, the strokeWidth also extends on either end (at half the rate as the strokeWidth). At least that's how it works in Nodebox. Other vector drawing tools provide options for rounded caps. I'm not sure what plotters do.

    It is possible to perfectly simulate a rectangle with a line by setting the strokeWidth to the shorter side of the rectangle and shortening the line so that the area extending from either endpoints makes up the difference. But when you use this technique with squares, you end up shortening the line to length zero! This produces something that looks like a square, but behaves strangely, and no longer follows the angle of the original dash. I'm also not sure what a plotter would do with a zero length line.

    So anyway, that's why I made my dashes out of rectangles.

    But it is possible to convert rectangles into line segments and compensate for the issues with square dashes.

    Behold! A new node (attached): rect_to_line.

    Rect_to_line takes any rectangle (or any other shape) and turns it into a line segment which follows the longer axis of the rectangle. By default, the line has a strokeWidth of 1 (with a stokeColor matching the fill of the rectangle, or black if the shape has no fill).

    But if you check the "Fill with stroke" option, the line will be shortened and the strokeWidth increased to create something that looks exactly like the original rectangle. In order to handle the problem with square or near-square dashes, I enforce a minimum line length of 2% of the shorter side. This causes the thickened lines to extend just barely past the correct endpoints, but this effect is not noticeable in most cases. In some cases the thickened lines will be ever so slightly off the correct slope when converted to PNGs, but will be fine when converted to SVGs or PDFs.

    If you pass a shape other than a rectangle, rect_to_line will use the shape's bounding box instead. And if you pass it a group of shapes, it will ungroup, convert the shapes, then regroup.

    To turn the output of my dashed_line node into something more plotter-friendly, just feed it into my rect_to_line node. If you check the "Fill with stroke" option, all the rectangular dashes will be converted to line-based dashes which look the same. If that doesn't work well, you can uncheck the option and get plain line segments which follow the long axis of the shape; you can then use a colorize node to change the thickness of these lines.

    The demo shows three tests combined into one output.

    On the left I show the same rotated square pattern that was giving Floris trouble. I stack three versions vertically. The first is the original pattern produced by dashed_line with a thickness of 2. Below that is that pattern fed into the rect_to_line node with the Fill with stroke option engaged. As you can see this looks exactly the same but should be plottable. Below that is the slightly thinner line-based dashed produced when Fill with stroke is unchecked.

    To prove that the dashes really have been converted to lines, I show a closeup of the first dash in each pattern with the path points shown as blue dots. The rectangles have four dots, the lines only two. I also show the output of two nodes I made for this demo: is_line (which returns true if the path is a straight line), and is_rect (which returns true if the path is a rectangle with four 90 degree angles).

    For my second example I create a dashed balloon, then again show the original and the two rect_to_line conversions with and without the Fill with stroke option. I only generated one balloon, but if I had generated a bunch of balloons each a different color, as I did earlier in this thread, dashed_line would return each dashed balloon as a separate group, and rect_to_line would do the conversion and then regroup each balloon.

    The third example shows one output of a torture test of different shapes fed into the rect_to_line node. If you are curious you can play with this subtree and try different shapes. You can also try reversing the direction of any shape, rotating them, etc.

    Floris, could you please try feeding some dashed patterns into the rect_to_line node and then plot the results? Let me know if this solves your problem. I'm also curious to know how thick you can make your strokeWidths - is this limited by the pens you use? And does increasing strokeWidth cause the ink to extend out from either end in the same way it does in Nodebox? How do square dashes turn out?

    I think this node is pretty cool, and may have uses beyond dashes, so I will probably add it to the next rev of my library. Do you think you would have any general uses for the is_line and is_rect nodes? They were surprisingly hard to make. ALSO, do you see any uses for an opposite node which would turn line segments into rectangles?

    Finally, one more question. Do you think I should add an "Output lines" option to dashed_line so that you wouldn't have to manually add the rect_to_line node when plotting? It might cause a slight slowdown even when you don't choose this option, but perhaps that would be acceptable.

    Thanks again for bring this to my attention and spurring these improvements. I look forward to your feedback!

    John

  16. 16 Posted by florisdejonge on 15 Jul, 2024 12:05 PM

    florisdejonge's Avatar

    John

    Thanks for the response and providing another node. So, I have made another test. The result of which can be found here.

    The rect_to_line node works for transforming the rectangles into lines (as the name suggests).

    In my regard, as I mostly think in applications to penplotting, the strokeWidth is a simulation of the width of the pen to predict the drawn result. It doesn't matter to the plotter which strokeWidth is given: it only follows the paths. With that I mean what is shown in Nodebox when the Points are selected in the Viewer, in Illustrator > View > Outline, and in Inkscape > View > Display Mode > Outline. That's all the plotter is 'seeing'.

    Therefore, the caps aren't relevant (to the plotter at least), but they will arise from the pen width. A zero length line to a penplotter is still a dot, which causes it to go up and down and make a point on the paper. When applied to penplotting (I am not sure for screen-based applications) it seems only logical to integrate the rect_to_line node into the dashed_line node. Right now, I can't think of any other applications for an is_line node.

    I looked up how I have made dashed lines in the past. I used a Resample node and took some points and connected those. I made it in a quick subnetwork which I attach to this message (it might be a bit slow, due to the mask node). I don't know whether this solution is as versatile as yours, but just for comparison it might be interesting.

    I hope this answers your questions and helps the discussion and development of nodes further along.

    Floris

  17. Support Staff 17 Posted by john on 15 Jul, 2024 07:02 PM

    john's Avatar

    UPDATE

    Attached is v3 of the dashed_line node. It now has a new checkbox: "Output lines". If checked, the node will output line-based dashes instead of rect-based dashes. It is easy to distinguish v3 from the two previous releases since only v3 has the new checkbox.

    Thanks to Floris for verifying that line-based nodes do work on plotters. I will respond to his last comment in a separate note (below).

    If you choose the Output lines option, I apply rect_to_lines using "Fill with stroke". This means that the output will look exactly the same. There will half as many points used, though, so you can see the difference by checking the Points option in the viewer pane.

    There are a few issues to be aware of, however, when using line-based dashes.

    A dashed triangle will look exactly the same under either option. But if you then produce drawings like the one's we've seen in this thread, where you use the copy node to repeatedly rotate and scale the triangle, the final result will look different. The reason for this is simple: lines scale differently than rectangles. Scaling a line changes its length but not its height (that is, its stokeWidth); scaling a rectangle changes both dimensions.

    You should also be careful when using dashes that render as perfect squares. Due to the issue I discussed in my previous note, squares rendered as lines with fat strokeWidths behave strangely in Nodebox.

    You can see this in the screenshot of the demo I attached. For this example, I made a triangle colorized with a strokeWidth of 2 and also set the dash length to 2. This makes each dash a perfect square.

    If you render the dashed_line node and switch back and forth between normal and line output, you would normally see no change. But since the dashes are squares, Nodebos has trouble getting the rotation correct with line-based squares. As a result some of the dashes will be slightly askew, and they will randomly wiggle as you zoom in and out.

    This effect becomes more dramatic when you render the rotated and scaled version and zoom in (as shown in the screenshot).

    This effect only happens when Nodebox tries to convert the vectors to pixels. So it appears in the viewer pane and will also persist if you export to PNG. But if you export to SVG or PDF, the triangle will look fine. It should also plot correctly.

    I encourage you to play with the demo to fully appreciate these dynamics. Try changing the strokeWidth in the colorize1 node and the dash length in the dashed_lines2 node. Then render dashed_line2 and check the Output lines box on and off. Then render the copy1 node just below that and again check the Output lines box on and off.

    In most situations, none of this will matter and you can safely choose either mode of dashes. In general I would recommend sticking with default rectangle mode unless you are plotting the output - in which case you should check the Output lines option. But if you are going to scale your dashed lines, be aware that rectangles and lines scale differently.

    I did test the efficiency of this new version by the way. The latest version might be up to 10% slower in some cases, but in most tests the difference was less than the natural variation in run times (even for time-consuming examples), so was not particularly noticeable.

    Enjoy!

    John

  18. Support Staff 18 Posted by john on 15 Jul, 2024 07:37 PM

    john's Avatar

    Floris,

    Thanks once again for your very helpful response. As you can see, I followed your recommendation to add an Output line option to dashed_line.

    Your description of how the plotter deals with strokeWidth was what I expected; but I wanted to be sure. I supposed you must use your experience to choose a strokeWidth that will approximate whatever pen or marker you are using. There may be subtle differences - even from pen to pen - on how much the ink bleeds out from the endpoints, but this is probably not much of an issue in most cases.

    (If it ever is, let me know. The new "Output lines" option in dated_lines uses "Fill with stoke" mode, which shortens that dash lines based on the supplied strokeWidth. This is intended to compensate for any endpoint bleeding that may occur. If you see microscopic gaps or overflows at the junction points between joined paths, you can control this by simply changing the colorized strokeWidth that you feed into dashed_line. This obviously won't affect the actual thickness of the pens you use, but it will slightly adjust the length of the dashes. A VERY subtle point which most people would never even notice.)

    The method you described to make your own dashes is essentially the same approach I use in dashed_line. That is, I base the dash positions on resampled points. This works fairly well for quick and dirty dashed lines, especially for straight lines, but my node is more complicated for two reasons.

    The first is my obsession with making dashes which are all the same length and which stop and start precisely on the endpoints of the path. As we've seen in this thread, that is a trickier issue than it might seem at first.

    The other factor is that when you resample curves (beziers), the points are NOT evenly spaced. The greater the curvature, the more the resampled points bunch up. Even for an ordinary circle this effect is quite noticeable.

    This is a mathematically difficult problem inherent to Bézier curves. I just did an AI-assisted search which verifies there is no magic algorithm that finds evenly spaced points with blazing speed. Instead you have to start with the normal resampled points, measure lengths, interpolate, and iterate to some desired level of accuracy.

    This is a problem I solved long ago with my even_sample node. I used a streamlined version of even_sample inside my dashed_line node. This solves the problem, but makes the node run slower.

    I also agree with you that is_line and is_rect are probably not useful enough to be "library worthy". I may just hide them away in one of the demos instead.

    I am not yet sure whether to include rect_to_line in my library. You no longer need it for dashed lines, but I suspect there may be other uses. Can you think of any?

    As I said on Instagram, I really like the plot you produced using my draw network code with SVG text to show the rotated triangles using both dashed_line and rect_to_line. It's a great example that highlights a number of the nodes you have contributed to. Thanks yet again!

    John

  19. 19 Posted by lastvector on 20 Jul, 2024 05:46 PM

    lastvector's Avatar

    I found a variant as I came up with the idea of ​​connecting
    three quadcurves, but there could also be more quadcurves
    connected.

    I also made a variant with polygons.

    gottfried

  20. Support Staff 20 Posted by john on 22 Jul, 2024 06:06 AM

    john's Avatar

    Gottfried,

    These are way cool! I especially like how simple they are.

    John

  21. 21 Posted by lastvector on 22 Jul, 2024 07:23 AM

    lastvector's Avatar

    John

    yes, your "Dashed Lines" Node allows to add a very nice
    dot pattern effect to such designs and contributes a lot to
    making it look more appealing.

    But some designs look a bit simpler than they are.
    For example, in the last design I used three separate node trees
    to have better fine control over the spacing and position of
    the lines for each part.

  22. Support Staff 22 Posted by john on 22 Jul, 2024 07:50 AM

    john's Avatar

    Gottfried,

    Yes, but they look simple.

    You raise a good point. This is true of most of my designs as well. I go to great lengths to make them look simple, but this apparent simplicity often requires surprising amounts of complexity.

    I like how you have used variations in strokeWdith, dash length, and dash interval to create slightly different "textures". This is another technique I didn't fully foresee when I made the node.

    Most people won't notice the differences, but the overall effect is quite pleasing and wouldn't look nearly as good without this attention to detail.

    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

  • Dashed_Line_Screenshot.png 653 KB
  • Dashed_Line_Demo.ndbx.zip 22.2 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

23 Jul, 2024 04:46 PM
22 Jul, 2024 07:50 AM
11 Jul, 2024 03:48 PM
28 Jun, 2024 01:51 PM
27 Jun, 2024 02:56 PM

 

27 Jun, 2024 01:57 PM
26 Jun, 2024 08:17 PM
26 Jun, 2024 11:35 AM
24 Jun, 2024 02:42 AM
24 Jun, 2024 12:46 AM
23 Jun, 2024 08:07 AM