Point IN Path Node
I use the standard point_on_path node all the time. It works great with closed paths.
But it is quite annoying when used on open paths like a line, arc, or curve. If you set point_on_path's T value to 100, you get not the end point of the path, but the START point (presumably because there is a mod 100 inside it somewhere). This is OK with closed paths because in that case the start and end are the same. For open paths this is a pain.
It's easy enough to fix by adding a special test for T=100 and replacing the output with the final point of the path - but after doing this again and again and again I got tired of it. So I made a simple node that I can just copy and paste instead.
Attached is a demo of this node: point_in_path. It works the same way except that T can only vary between 0 and 100, and 100 actually gives you the end point of the path. I find myself using it A LOT.
Enjoy!
John
- point_in_path_screenshot.png 299 KB
- point_in_path_demo.zip 1.51 KB
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
1 Posted by Jen on 05 Jun, 2022 09:29 PM
Hi John
I am stuck. I made the attached by doing the heavy lifting in Excel. I thought it should be totally doable in NB with minimal work in Excel. It seems like I should be able to look up a distance in Excel as the only look up node, and NB could take it from there. But I cannot for the life of me figure out how to find the point at the end of one line and make it the beginning of the next line. I'm using Line_Angle and obtaining the last point with your Point_In_Path node but it seems like everything I try with Rotate, Translate, etc etc, I get either an error or a bunch of parallel lines. Can you please nudge me in the right direction?
Thank you!
Jen
Support Staff 2 Posted by john on 06 Jun, 2022 01:52 AM
Jen,
Part of what you are trying to do is easy and part is surprisingly hard.
Finding the point at the end of a line segment is easy. Given a starting point, direction, and distance you can find the end point by using the coordinates node.
Joining all the lines together is surprisingly hard in Nodebox. The reason for this is that Nodebox has no loops, no recursion, and - worst of all - no "state". State is the ability to create and refer to values stored outside a function. Most languages allow this using, for example, global variables. Nodebox does not allow this.
Aside: global variables are obviously quite powerful and make tasks like this much easier. But they come with a hidden cost. Global variables - and state in general - often have unintended consequences that get harder and harder to predict as your code becomes more complex. State is at the root of the most gnarly bugs in most languages. Because of its purity, Nodebox avoids these issues, making Nodebox code much easier to debug. That's one reason I love it so. But it does make otherwise simple problems like this harder to solve.
The reason we would want to use state in this case is that, for each new segment we need to know the endpoint of the previous segment. But a segment-drawing function only knows about the present; it has no way of knowing about past outputs. So how do we figure out the "previous point"?
There are several kludgy ways of doing this, which I can go into if you're curious. But in this case we can solve the problem using a little cleverness and the running_total node. See attached demo and screenshot.
I assume from your pdf that you are taking distances from your CSV file and drawing them by making a series of 90 degree turns. Is that right? I used a hundred random numbers, but you could replace that with a CSV lookup if you want.
The nice thing about 90 degree turns is that the change in x and y values follows a predictable pattern. X values go in the positive direction when the line goes east, then stay steady while the line goes north, then negative to travel west and steady again while traveling south. So you can find the change in X by simply multiplying the distances by 1, 0, -1, 0, 1, 0, -1, 0,... etc. Y values work the same way except the pattern is shifted: 0, -1, 0, 1,... etc.
The trick, then, is combining all these changes together. We can do this by simply adding them using the running_total node. This node is a way of sneaking some state into Nodebox. These running totals sum the changes and give you the X and Y coordinates of every turning point. All you have to do then is connect them with a connect node.
If you study my example, you will see that I use my own running_start node instead of the standard running_total node. The standard node, unfortunately, does not start "running" until the second value and so finishes without adding the final value. My running_start node fixes this.
(You may also notice the clever way I generated that 1, 0, -1, 0 pattern using a waveform node.)
Please let me know if this gets you unstuck. It's unfortunate that a seemingly simple problem like this should require such cleverness, but I find it part of the fun.
John
3 Posted by Jennifer Concan... on 06 Jun, 2022 12:40 PM
Hi John,
You're right - that is extremely tricky. I was hyper-focused on using the
Line_Angle node and would not have gotten this. I totally understand the
wave function; I've used sine before for alternating between 1 and -1 as a
means to "activate" and "deactivate" parts of a math equation. However, I
would have been stuck again as to how to incorporate it like you did with
the offset port. Very clever! I find it interesting that your division of
the sine function by 4 did not result in a clean value of zero every 4th
line, and that you had to clean it up with the integer node. Why is that?
I'm still studying this to fully digest it, but I am so grateful for the
help!! I had assumed this would have been easier in NB than creating a
pattern of functions in Excel to create the change in direction, and
copying and pasting down the list, but it seems that the reverse is true.
However, I know there will be times when this will not be a good option in
Excel and your example will be a lifesaver. thank you!!
Still having fun with NB,
Jennifer
Support Staff 4 Posted by john on 06 Jun, 2022 01:07 PM
Hi Jen,
Yes, Excel might be better for calculating the values in this case, but it's not much of a drawing tool! Actually I find myself sometimes even using Nodebox for basic sorting and filtering tasks that Excel is arguably better at just because I like representing chains of functions visually.
You are perceptive to notice the rounding error I had to deal with. Nodebox will produce subtle rounding errors every now and then, especially when using trig functions or logarithms. The errors are very tiny, like 0.00000001, but they can become a nuisance.
I didn't really need the integer node in this case since the change in distance of a line segment would be imperceptible. But when you are testing values for switches (Nodebox's version of an if-then branch) you have to be careful. If you want to branch when x = 0, a value of 0.00000001 will fail. If an integer node is too heavyhanded you can use my handy precision node to control these rounding errors while still allowing fractional values.
Glad to hear you're still having fun. Keep playing!
John