To close the open curves, I need to connect the curve at i=0 with the curve at i=1, where i=0 is the start and i=1 is the end. In case both are the same index, it means the curve misses a segment.
Never mind, I don’t need the unique sets for this problem, but rather the sets that overlap (with 3&4 or 4&3 in this case), so I can extend both their start and end for the intersection:
It’s actually pretty simple thinking about this. I have the indices of the curves, so to check branches with the same indices, I can sort them from low to high, then concatenate each branch to be able to treat them as single items. That way, I can use the sets components to find which items are unique and from there get the associated branches:
This problem has nothing to do with “unique sets”, and has everything to do with curve direction. Consequently, the above is not a solution.
The way you are using Point Groups, the tree of indicies will already create unique sets of branches. This is easily evidenced by flattening the indices output of the Point Groups component, and running them into a List Item component with i and +1 exposed. Attaching a slider of even integers to the indices input of List Item will then show you the unique curve end pairings Point Groups produces.
The problem that you are having is that the nearest neighbour to an endpoint is sometimes the endpoint of the same type to which it is being compared. This results in indices of 0 and 1 in the modified indices List you labelled as “Curve index - Start | End” being either both startpoints or endpoints of curves. You can tell which of the curves are in the minority direction because they occur in the modified indices list soley in the 0 or 1 index slot of the list. Examples of these (using your larger curve base) would be curve 12, which only occurs in the 1 slot, curve 21, which occurs only in the 0 slot, and curves 18 and 8, which connect head to head, tail to tail. If you have branches that mirror themselves (as in your opening example of branch {0;0;0;0} being 3,4 and {0;0;0;1} being 4,3) all this means is that curves 3 and 4 are two halves of a loop that connect at both ends head to tail. Furthermore, unless you reverse the index list coming out of Point Groups the indices coming out of “Curve index - Start | End” will actually be “Curve index - End | Start”
If you clean up the source curves, you can use the following script to determine your intersection points:
I would disambiguate for self-intersecting and parallel curves after attempting to get these first intersections since they can be found by 0 intersections (parallel) and 3 intersections (self-intersecting)
I cheaped out and created the connections for the intersecting sets with lines drawn from the endpoints of the polylines to their interection point. If you wanted clean polylines, you would have to move the endpoints of these sets to their intersection point. Or you could take the end result and clean it of colinear line segments.
Either way, you still have the problem of needing to flip certain curves. You could use the list of curve indices to ascertain which curves need flipping by checking which values occur only at index 0 or index 1. For that you’d basically repeat the beginning part of the script. Or you could just make sure that your source curves are properly organized in branches which represent rooms and with curves in a list order that they make them neighbouring. That would make this whole exercise moot, because then you’d simply have to connect the start/endpoints of neighbouring curves.
Not a big fan of Point Groups because of the slider. You could use Closest Points with a count of 2 to find the nearest neighbour. With either Point Groups and Closest Points you will have the problem that if the wall thickness is smaller than the intersection offsets of the polylines you catch the wrong point.
If your curve extensions are going to be linear, you might as well use the Line|Line because that way you won’t have to provide an arbitrary extension length for Extend Curve. It’s wild that Grasshopper doesn’t have an “Extend To” some geometry component for curves.
Might have made a mistake with mixing up two different methods as it was getting late. I wanted to tackle one problem first and ended up doing something else later, thanks for checking. At least I learned how to find similar branches in the process.
I figured out how I can close the open curves that have parallel start/ end segments. From there, I’ll look at extending the curves from start/ end to get the intersection. Working on this atm. That way, I won’t need any flipping.
As for the point group, I settled on using the max wall width as distance (or actually for wall width = x: sqrt(x^2+x^2), this gave me a value with only point groups of 2 points by a fair margin.
This baffles me too, since it is quite tedious to do manually. Since I’ll be using splines, I’ll have to go this route. Also, while Line | Line detects anti-parallel curves, it does not output which error is which:
To be clear what about what I meant by using Line | Line; I meant using it on ficticious lines you create with the end tangents of the lines/curves you are solving an intersection for:
thus creating linear extensions for either curves or lines. That prevents the red error message. The orange warning which throws nulls can disambiguated between parallel and "anti"parallel (co-linear) by seeing if a direct connection between the endpoints produces a discontinuity ( Discontinuity ) or can be simplified with Simplify Curve. by comparing end tangent vectors.
It’s better form to have your data appropriately structured; for the sake legibility when others try to decypher it, or when you want to manipulate it yourself later.
Not sure how you’d want to structure the data when you need to account for all kinds of inputs. I start with open curve offsets, which can be in different directions and their direction changes when you join the segments, even when you flip each curve to be clockwise.
Initially, my problem was that the point group matching for open ends of curves can have bi-directional matches, so I wanted to find only one of these matches; in other words, I wanted a match of index 3 & 4; not 3 & 4 AND 4 & 3, as that would create double segments. The problem changed as I worked on it and changed methods.
@Volker_Rakow I now remember why I opted for point groups, I first used Closest point which messes with the index values, whereas I should have used Closest points.
Great work on the script! To be honest, I don’t fully understand how it work in the details, like why you are breaking down the polylines, but I am sure that when I take the time to sit down and think it through, it will make sense.
I see. I guess, just generally, I found it odd to have a flattened list when I assumed this data was coming from somewhere where on some basis it would be hierarchisized. And of course, when you get to the end of the logic in this script, the polylines will be organized by room.
Yeah, whoops! That’s a mistake. Ironically, if you try to replace Point Groups with Closest Points you will run into the exact problem I told you didn’t have here. Closest Points, unlike Point Groups will not give you a unique set of endpoint pairings, but all the pairings for each start and endpoints of the curves. So you would have to cull the duplicates and for that, the solution came up with for yourself here:
is handy. I don’t know if you are going to make the switch… I would. Just to get rid of the silly slider.
Glad I could help! A little sad I didn’t get check-marked, but you did answer your own question.
Your so called “Matching Start | End Indices” can be used as t paramters on a reparameterized curve to choose the start or end of a curve for extension. Then you can solve for intersection without worrying about parallelity because drawing a polyline through start point, intersection point, end point when there is no intersection point ( Line | Line throws null) will result in a polyline that simply connects start and endpoint. Yes, the Line | Line component will show orange, but the definition will still work.
This will work for splines as well as polylines. The only thing left to solve is seam, because Simplify Curve will not remove it as a colinear point.