Expanding boundaries to evenly fill space

Me again, sorry for the conversation with myself…

I saw this animation below and it’s sort of what I’m trying to achieve. I want to be able to offset the curves outwards evenly until they touch one another. That would prevent me having the curved/staggered geometry. I guess I almost want to treat each curve as a cell rather than creating a series of points along the curve the generate the cells.

image https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Voronoi_growth_euclidean.gif/220px-Voronoi_growth_euclidean.gif

It’s doable with native Voronoicomponent. It has the Radius input…

Hello
transforming curve to curve oriented just in 2 directions, X and Y is surely doable. You can use this or something like this.

1 Like

@HS_Kim I am not sure how to achieve the offset of a curve using the Voronoi component and the radius input. The script Laurent posted earlier used Voronoi to create the medial axis by creating a series of points along the curve, I want to offset the curve itself until it hits another offset curve much like an expanding Voronoi cell would stop expanding when it hits another expanding Voronoi cell. Any ideas?

@laurent_delrieu Manhattan is closer to what I am trying to achieve, but it unfortunately only gives me one right turn (unless I’m doing something wrong!). I would like to be able to control the number of right turns in some way, for example in my screenshot below where there are clear bends in the curve. I tried looking at the FitLine component but it doesn’t work with polylines, I can only obtain a best fit line through all points and not just ones in a predominately x- or y-axis orientation.

190716 - Straighten Curve WIP.gh (43.3 KB)

Here a simple way to do that with mesh (here quad mesh), you just have to use the slider.
I put a little C# to put data in Branch, there is surely a component but as I mostly program in C# it is more simple for me



190716 - Straighten Curve WIP_LD.gh (48.4 KB)

5 Likes

This looks just what I am looking! The only issue there appears to be is with the ‘Brep Closest Point’ component, I guess this is what you added C# to? It won’t load for me to test and explore :frowning:

Could you explain briefly what it was you tweaked to get this effect?

I put the old Brep closest point from Rhino 5 so it must now work for you.
The logic is simple

  1. Divide the surface with curves (it allows to suppress part of curves not linked)
  2. Make a division of the surface (here a mesh) on the surface
  3. For each division (face of the mesh) search the distance from the surface division
  4. Make a index for each surface (with series component)
  5. Order the distance and index
  6. Take the first distance/index, so the closest surface division from mesh face
  7. Put each face in a branch of tree (use of the C#, but I am sure there is a component for that)
  8. Join the faces on each branch so it becomes a mesh
  9. Extract the edges of the meshes

There are others strategies :

  • populate each surface division with mesh faces, make each “island” grow. I have a script for that but I don’t want to share it (Mesh clustering)
  • Make a program that takes the curves and simplify them
1 Like

Amazing, thanks a lot. I’m going to try and reconstruct this myself to learn the process better, your explanation of the logic was very useful!

I stumbled across the below thread with @laffarguee and @anikolo by chance earlier, and it has got me thinking about how to go about this task for non-rectilinear starting boundaries.

It appears that the pink curves have been used to form the regions, but how would one go about generating this pink centreline if the regions were the starting point? The starting boundaries may not always be equidistant apart as in this example, but would you be able to easily create a centreline for non-parallel lines in a similar way to before?

What is the difference with that ?

I guess that actually is what I was looking for! :rofl:

The issue was that the regions were very close together and the medial axis wasn’t generating, but once I increased the number of division points sufficiently it seemed to work better. Thanks!

The problem you mention is also a good reminding that it is always better to post YOUR data and script.

2 Likes

So I am still playing about with this and trying to figure out how this works.

I am trying to achieve this without using meshes or c#, mainly because I want to learn to walk before running! I have started with a similar approach as before (create grid, divide surface, etc) but am not great with trees! Can you elaborate a little more on putting faces into branches of a tree please?

An alternative approach I thought of was to divide the boundary curves and then pull these points to the closest grid line. I could then dispatch all lines that had a point on them and use those curves to split the original surface. I think this will probably cause a few issues where the bends in the curve are only picked up by one edge rather than two, etc, but how would I go about testing for a point/line intersection? Does this approach have any mileage in it do you think?

Sorry for still going on with this, but I want to try and learn! :slight_smile:

190725 - Boundary Expansion - WIP.gh (31.3 KB)

I’ve been following this thread and have actually enjoyed trying the challenge, teaching myself a few things along the way. I’ve been working on another method independent of Voronoi, but it still needs some work and inspiration. In the meantime, I have a few responses…

@laurent_delrieu and @stu92, I put together an alternative to using the C# code, see attached. I couldn’t think of a component alternative to your code, so I took a slightly different route. I thought the sorting of the Series is a pretty interesting technique. Personally, I like to avoid meshes unless necessary, but it seems to be pretty useful here.
190716 - Straighten Curve WIP_LD_NoC#.gh (65.0 KB)


@stu92 Here are some notes I took when looking over your file:
190725 - Boundary Expansion - WIP-Comment 190725.gh (42.0 KB)

I like what you did with the sorting the two offset curves by length and choosing the longest side. Alternatively, I’d use the flip C (component) using a GH constructed circle as the guide.

The reason why @laurent_delrieu sorts the point distances is to select the closest point in the brep, which becomes the first point in the path, and then translates it into something his C# code could work with. When you grafted the four regions, the BrepCP stopped analyzing each point by all four regions and paired them off, analyzing the first of each list, then the second, and so on (see the image). I hope this answers your first question.

I’m not certain I follow your logic in the second question, but you can use ‘Curve Closest Point’ for the point/line intersection and test for which points have a 0 distance. Hope that helps.

Btw, not to be ‘that guy,’ but “tree?” is not a question! :stuck_out_tongue_closed_eyes:


If I can’t finish or make any progress in my version in a week or so, I’ll share it and see if anyone here has any ideas to make it work.

2 Likes

Wow, that was really helpful. I think I have understood this a bit more as a result of there being no c# and I follow your logic. I’ll be taking it apart and putting back together now to really test my understanding!

If I’m being honest I still don’t fully understand how to use trees to my benefit but am working on it. I hate to be ‘that guy’ also, what it really should have said was “I then believe there to be some sort of process involving sorting data in trees, but I haven’t a clue where to begin”! :laughing:

My logic on the second point is flawed the more I investigate. The issue comes where there is a bend in the curve, and only one edge of the grid surface is selected as opposed to the two required for a 90 degree angle. Back to the drawing board on that one!

1 Like

Well, I’m spent. I was hoping to figure it out myself, but it’s distracting (and draining) me too much :tired_face:. I hope some of the geniuses out there can fill in the gaps…if anything, I may learn a new trick.

190730 - Expanding Boundaries.gh (82.9 KB)

-The first step was to divide the inner boundary into rectangles.
-The second (missing) step is to combine these small rectangles into ‘parent,’ overlapping rectangles.
-Third step is to make and split lines that run between those parent rectangles.
-The fourth (missing) step is to filter out the unwanted split lines to get the desired paths.

For the second step, I was thinking we could make every rectangle combination possible and deduct the rectangles that are completely within another, but when I tried it, I was still getting intersection results between the child and parent rectangles (maybe we could dispatch based on more-than-1 intersection curves?). I was also wondering if there could be a method using mesh components, something that could test for rectangles that are adjacent to one another.

For the fourth step, I was thinking that of among the parallel segments, we can choose the one that has the highest ratio of their body in their respective rectangular areas (maybe place points along each segment and choose the one with the most points in each parent rectangle?). Also, I was thinking we could at least filter out any segments that are only intersected by another segment once.

For a little something extra, a filter can be added for paths that lead out to the boundary, or remove paths that lie between the plots and boundary.


Is this the sort of solution you were looking for @stu92?

Can’t wait to see if anyone can fill in the missing steps!

1 Like

Yes! If I were to draw this ye olde fashioned way with pen and paper, this is probably the approach I would have gone with.

I’m without Rhino access for the next few days but will test my far inferior knowledge then and get back to you. When I first looked at the image I wondered if there was a method of shattering each line at its intersections and then keeping just the longest segment, effectively removing the redundant end pieces, but this may not work where a line has an intersection at the middle. Removing the two shortest ends instead may be an option? I’ll test this approach anyway in the absence of someone more talented. :laughing:

What if your starting point is not planar i.e. curves?

Think of a Rubik’s cube that you separate X distance from each other individual cube in all dimensions in a non-uniform manner, and want to fill in the space in between and get the boundary geometry, a “deformed bounding box” if you will.

Thanks for the awesome posts and thoughtful explanations.

Keeping the topic alive here, has anyone had luck with this? here is another case of a wicked example
Question forum fill gaps_3rd_try.gh (678.3 KB)

Like many goals, I think yours just cannot be materialized. (at least not the way you imagine it)
On a very basic level the algorithm you want has these objectives:
-divide the distance between the various shapes equally
-use only horizontals and verticals
this creates the problem that you are left with small overlapping squares that you have to decide how you will divide between the the shapes.

I believe in its purest form the algorithm would work like this:
Animated GIF
If you follow the intersecting points you get diagonals which divide the space ‘justly’ and avoid having to solve the distances for more than two ‘tenants’ at a time but already we have failed to have only vertical lines.

where you see the orange diagonals you can chose to replace them with a right triangle on one or the other side but in both cases you will wrong one of the two tenants.

You can replace the diagonal with two triangles (one for each tenant) but you get ugly jiggly lines:


borders.gh (11.0 KB)

Maybe a better way to think about this is calculate the areas of the houses and introduce the percentage of each house’s area as a variable but again it would lead to more complication. I don’t believe you can easily find a formula that is both deterministic and elegant.

*hey, you could make it your thesis!

1 Like