# Curve tilt of instanced curves to follow sampled geometry

I have a node set up that requires curves to follow a plane. (the plane is manipulated outside of geonodes and the curves follow)

Is it possible to have the curve tilt follow the normals of the plane?

*Edit: Ended up following the solution in this thread: https://blender.stackexchange.com/a/275131/88095 *

Current set up, with the tilt of the curve unaffected by the normals of the plane: Desired result, note the normal/tilt of the curve adhering to the normals of the plane (i've used instance on points as demonstration, but not what I'm after):

• do you mean like that? [1]: i.sstatic.net/7rtVM.gif Commented Jan 22 at 10:49
• Yeah I think so Commented Jan 22 at 11:16
• in 4.1 there is a set curve normal node. in earlier versions you have to take the angle between the 'curve normal' and the surface normal around the 'curve tangent' and set that as the tilt. Commented Jan 22 at 23:27
• Thanks, I'll have a look at 4.1, that sounds promising Commented Jan 23 at 0:19
• Hmm, I'm not sure if that's a solution as z up is a global co-ordinate and isn't effected by the normals of the sampled plane, unless I'm not seeing something Commented Jan 23 at 1:57

This GN group will return the signed angle between two vectors A and B about the axis N:

So could be used to rotate an existing Curve Normal about its tangent to align with another vector. In this case, it's aligning to the normal of a surface, on to which the curve is projected:

With this kind of result.. (excuse poor sampling):

.. although I think, if you're instancing on the curve, rather than orienting a mesh-profile for it, you'll run into fewer problems with interpolation by aligning the instances themselves, than the tilt of the curve they're on.

• This is a great solution! Thanks. The instanced cones were there just to communicate the concept. The surface is meant to be a mesh deformation for a single object with a curve deformation, so in this case the tilt is important for the object to twist with the surface, basically as you've shown there. Commented Jan 24 at 12:54
• Great! Hope it works.. as I said, I found the mechanism to be quite twitchy about sampling, handle-types.. Commented Jan 24 at 17:05
• Hi Robin Betts, I left your reply up as the answer as it may be useful to someone else but I actually ended up using this answer which I stumbled across looking for something completely irrelevant: blender.stackexchange.com/a/275131/88095 It doesn't have the same issue with the position randomly twitching back to origin and is more suited to my use case. Commented Feb 4 at 1:57
• Hi, @special_frog! Thanks for taking the trouble to give us the heads up! That pretty much qualifies this answer as a duplicate.. I should have passed it on instead of answering, if I'd known. By using an extra cross-product, Mystiker seems to be taking the angle to the Binormal instead of the Normal (at right-angles around the Tangent). It's not immediately clear to me why that gives you your improvement.. ahh.. maybe it's where the '0' of a signed angle is deemed to be, so not clashing with 'Blender's Tilt' 0. I'll check it out. Commented Feb 4 at 10:34

(Using Blender 3.6.5)

NB: This post is to illustrate/to demonstrate/to complement Robin Betts's answer.

#### Objective

Let $$\vec{N}$$ (in blue), $$\vec{A}$$ (in magenta), $$\vec{B}$$ (in green) be three vectors such that $$\vec{N}$$ is not collinear to $$\vec{A}$$, neither to $$\vec{B}$$. The objective is to compute the rotation angle around the axis defined by $$\vec{N}$$, bringing $$\vec{A}$$ to be coplanar to $$\vec{N}$$ and $$\vec{B}$$ (in red).

#### Mathematics

Rotation around the axis defined by $$\vec{N}$$ is affecting only the vector components projected in a plane perpendicular to $$\vec{N}$$ (illustrated by the blue triangle). The vector component align with $$\vec{N}$$ is unchanged.
Let $$\vec{A}^\perp$$ and $$\vec{B}^\perp$$ be the restrictions of $$\vec{A}$$ and $$\vec{B}$$ perpendicular to $$\vec{N}$$ (illustrated as thinner vectors connected by triangles of same colour). These are defined by removing the projection along the axis, as: $$\left\{ {\begin{array}{rcl} \vec{A}^\perp & = & \vec{A} - (\vec{A} \cdot \vec{n}) \times \vec{n} \\ \vec{B}^\perp & = & \vec{B} - (\vec{B} \cdot \vec{n}) \times \vec{n} \end{array}} \right.$$ where $$\vec{n} = \vec{N} / \| \vec{N}\|$$ is the unitary vector align with the axis.
From the definitions of dot product and cross product, $$\left\{ {\begin{array}{rcl} \vec{A}^\perp \cdot \vec{B}^\perp & = & \| \vec{A}^\perp \| \times \| \vec{B}^\perp \| \times \cos{\alpha} \\ \vec{A}^\perp \wedge \vec{B}^\perp & = & \| \vec{A}^\perp \| \times \| \vec{B}^\perp \| \times \sin{\alpha} \times \vec{n} \end{array}} \right.$$ where $$\alpha$$ is the signed angle from $$\vec{A}^\perp$$ to $$\vec{B}^\perp$$, $$\tan{\alpha}$$ is computed as: $$\tan{\alpha = \frac{\sin{\alpha}}{\cos{\alpha}} = \frac{(\vec{A}^\perp \wedge \vec{B}^\perp) \cdot \vec{n}}{\vec{A}^\perp \cdot \vec{B}^\perp}}$$ Taking advantage of $$\vec{n} \cdot \vec{n} = 1$$, $$\vec{A}^\perp \cdot \vec{B}^\perp$$ is written: $$\vec{A}^\perp \cdot \vec{B}^\perp = \vec{A} \cdot \vec{B} - (\vec{A} \cdot \vec{n}) \times (\vec{B} \cdot \vec{n})$$ Taking advantage of $$\vec{n} \wedge \vec{n} = \vec{0}$$ and of $$\vec{U} \wedge \vec{n} \perp \vec{n}$$, $$(\vec{A}^\perp \wedge \vec{B}^\perp) \cdot \vec{n}$$ is written: $$(\vec{A}^\perp \wedge \vec{B}^\perp) \cdot \vec{n} = (\vec{A} \wedge \vec{B}) \cdot \vec{n}$$ As a conclusion: $$\tan{\alpha} = \frac{(\vec{A} \wedge \vec{B}) \cdot \vec{n}}{\vec{A} \cdot \vec{B} - (\vec{A} \cdot \vec{n}) \times (\vec{B} \cdot \vec{n})}$$

#### Geometry Nodes graph

Without hypothesis for $$\vec{N}$$, $$\vec{A}$$ and $$\vec{B}$$, $$\alpha$$ can then be computed with the following Node Group:

#### Resources

Blender file:

Moving vertices A,B and N, different configurations can be dynamically simulated.

• In his optimized answer, Robin Betts is taking advantage that the "Normal" node is returning a unitary vector (so no need to normalize N) and that the "Normal" and "Curve Tangent" vectors are orthogonal (so not need to subtract (A.N)*(B.N)). Commented Jan 25 at 22:53
• Wow! Just spotted this. That's such a fine explanation! Pretty much what I had to go through with pencil and paper before answering, (but doodling, without the notation, so without the rigour,) to convince myself the expression was good. And according to @special_frog, (see comments on answer), it might not be spot-on. This might have needed another x-product. Commented Feb 4 at 10:19