# How can I align the tilt of a GN generated curve to the nearest surface normal of a target?

To simplify some modelling tasks (like hair), I would like to align the tilt of a curve to the nearest surface normal of some other object.

Here's what I get if I just shrinkwrap a mesh line to an object and generate a curve with GN:

Here's roughly what I would like it to look like:

I don't want to just shrinkwrap the geometry to the surface, because that would change edge lengths; I want to create a curve inside the geometry nodes that is aligned to the surface normals of the target object. I think this should be possible by comparing the direction that a +X vertex deformed by the curve points, as compared to the surface normal from a transfer attribute, and then offsetting the tilt by the angle between those two vectors, but I'm having trouble wrapping my brain around how to get that done in GN.

• just a dumb question: do we get this information at all? i mean the angle/surface normal of the target. I just can think of proximity node, but it just provides distance and position. But no normal info.... Feb 2, 2022 at 16:00
• ok...possible with raycast...but then it gets complicated....ðŸ˜« Feb 2, 2022 at 16:01
• @Chris We can get the nearest surface normal with a "transfer attribute" node, with a normal node plugged into the attribute we want. It's okay that basic curves don't have normals-- this attribute is just a field, a virtual attribute that we can use for math on attributes that the curve does have, like tilt. Feb 2, 2022 at 16:05
• thank you! that question could keep me busy for days ....ðŸ¤­ Feb 2, 2022 at 16:15

By using this StackOverflow answer you can easily get perfect tilt alignment:

This only works for Poly curves, so you'll need to use a Set Spline Type / Resample Curve node to convert a Bezier / Catmull Rom / NURBS curve into a Poly curve:

Also, if you use the Object Info node to load the Surface mesh, then you must set the transformation to Relative:

If the transformation is set to Original, then the normals will be calculated incorrectly, so the alignment won't work.

Okay, it's not pretty, but I did it:

I'm using Robin Betts's curve modifier group to make a copy of the curve, as a mesh in order to measure the base tilt, then I'm comparing the vector from the curve control to its mesh counterpart to the nearest surface normal of the target object. I'm using a simple stretch/clamp group I made to put the mesh line in the proper place.

There are a lot of cross products and dot products here. I need to repair any vectors I measure to be orthogonal to the curve tangent. I also need to measure the direction of the vectors relative to the curve tangent to be able to know whether I should be rotating postively or negatively.

This version resamples the curve, so that I can use a mesh line with the same number of vertices to measure the tilt. I believe that a version that didn't need to resample the curve would be doable; we'd need to make a mesh with some actual faces to measure our base tilt, and then transfer attribute from nearest face interpolated rather than from index. But for my purposes, resampling the curve is fine.

Of course, with all those node groups and the fact that it barely fits into a readable pic that Imgur is willing to host, anybody that wants to recreate this will want the file: