Celtic Knotwork self-intersections and intersections

Hi, I’m struggling with some details on this repeating pattern for a series of ring designs. I’d really like the 2 line intersections (on the pattern that does not join to a continuous curve) to intersect and shatter each other as the self-intersections do. But I just can’t find the logic to make it work.

Also, I’d like the cuts in the boundaries to be parallel to the cutting line, not perpendicular to the line itself. Does anyone have any ideas how I’d do that?

All thoughts much appreciated.

celtic_pattern_boundary_only.gh (6.2 MB)
knots.3dm (4.6 MB)

1 Like

I still can’t work out how to split at self-intersections AND intersections of 2 curves. Anyone please with some insight to help? Perhaps it’s not possible?
celtic_pattern.gh (6.1 MB)
celtic_pattern_boundary_only.3dm (41.7 KB)

Supposed to look like this


I managed to get the first knot to work because it was a single curve self-intersecting.

do you think it is possible to make in such a way any knot could be calculated always and solely as a single curve like you did in the above?

if we get to the point of knowing where all the self intersections are, for instance like this:

there will always be 2 points overlapping

if we average them 2-by-2 we get to this point, where two portions of curve define each crossing, and the becomes (this is my assumption) easier to define what goes on top of what just by their indexes

for instance, in the previous image, the list A has the index of all the curves you will find if you walk from the start to the end, and list B will have the correspondent perpendicular crossing streams

if you decide that while you walk the curve you want to go “one portion up → one portion down” repeatedly, then it will result into even indexes going up and odd indexes going down (or the complete opposite)

now the big question is: will it work for more complex knots? (knowing that it must be a single curve)

took this from your GH file and connected top and bottom through this yellow line and joined everything together

I would like to say it worked, but it didn’t fully :frowning: I’m very sad, gonna have a gin tonic

[edit] ok, it works after simplifying some non-sense :+1:

gin_tonic.gh (19.8 KB)


First of all, your GIANT GH file has some irrelevant internalized geometry that can be deleted.
celtic_pattern_clean.gh (9.8 KB)

Second, you have some Join Curves components that are doing nothing because the curves don’t touch end to end.

I did some refactoring up to the point where the intersections and curve Shatter are done but need a break so left the culling alone.

celtic_pattern_2022Oct2a.gh (15.8 KB)

P.S. For amusement and consideration about culling, I added the white group.

celtic_pattern_2022Oct2aa.gh (29.3 KB)


There was a discussion on one of this subject


Another approach using Rhino.Geometry.Curve.CreateBooleanRegions()

celtic knotwork.gh (17.3 KB)

1 Like

Your “simplified some nonsense” can be further simplified, eh? By applying Dispatch directly to the output of Shatter. I love it!

gin_tonic_2022Oct2a.gh (16.5 KB)

I wonder how well it works with the entire pattern? It’s extremely slow… Still waiting…
And maybe I should have connected their end points instead of start points? Or maybe it’s better to replicate the single set of “knots” you have to get the whole pattern?

P.S. It took ~23 minutes and failed because the pipe radius was way too large. :frowning:

Trying again with 1/10th the radius. Round end caps on the pipes?


RDiff alone took 33 minutes on the complete pattern! (I disabled it in the attached code)
But it works. Looks OK to me except maybe the ‘extra space’ slider could use a bigger value?

celtic_pattern_2022Oct2bb.gh (22.8 KB)
celtic_pattern_internalized__2022Oct2b.gh (2.2 MB)

In the code flatten the parameters input


You need two Fennec components to create the final result: Regions and Offset to point

knotwork_.gh (21.4 KB)

1 Like

Hell. There’s a lot for me to study here. Thank SO much for your solutions @seghierkhaled @Joseph_Oster @maje90 @laurent_delrieu @inno . I’ve got many approaches to study now. I really appreciate the help.

You’re not the first to sacrifice G&T to the cause. It’s already cost me plenty of gin, swear and tears. Neat method thank you!

1 Like

I think that wasd where I learned the end point, list, index and self-intersection process. I don’t have the skills to develop it further yet. Well not until your help!

I think it took my machine longer to attampt my dirty definitions. REALLY frustrating for learning. Thanks for this. I’ll be learning about why my MASSIVE gh definition was so massive.

This is very beautiful. I like that you even adjusted the curve to refine the knot. And the end points are open so could be flowed around the ring I guess? I’ll have a go and post the resulting ring here. Hopefully I can cast some in the near future.

I’ve downloaded Fennec thank you.

As I said, you had some irrelevant code with internalized geometry way off the canvas to the left. It looked like terrain? Left over from another project? HUGE!!


what have you done here? Did you write it all into a little box?

I didn’t realise this would slow it down! I have started to try to use bits at a time, independently and diabling all other parts. Is it ok to just disable a bit you’re not working on?

Was the internalised geometry the ring that the know is flowed around?

I internalized the result from celtic_pattern_2022Oct2bb.gh so you can see it without waiting ~35 minutes for the code to run.

1 Like

Maybe you need to fix the ends manually when you create the ring

1 Like