Offsetting curves in the desired direction can be tricky, often resulting in overly complex definitions and makeshift solutions. This was one of the biggest pain points in my Grasshopper definitions, so I decided to delve into the logic underlying the offset component. Here I'll explain what I found and present a step-by-step approach to consistently get the desired output.
There are only three factors that matter to the Offset Direction:
If you can control each of these variables, you'll get the desired Offset Direction. Most likely you have a consistent Offset Plane and Distance Value. Almost all offsetting issues can be solved by constraining the Curve Direction (Variable 2). Flip your curves and make sure that they always face the same direction. Using the "Flip Curve" Component with a guide curve input helps immensely. We will review how the Offset Direction is determined then a few different ways to control Curve Direction.
Here's the core principle:
The positive offset direction at any point along the curve equals the cross product of the Curve Tangent Vector and the Offset Plane Z-Axis
The graphic below helps to visualize this statement. The offset plane is represented to the left of the curve by three axes: X (red), Y (Green), Z (Blue). The curve, in the same image, shows three vectors superimposed: the Z-Axis of the offset plane (Blue), the tangent vector of the curve at that point (Light Blue), and the positive offset direction of the curve (Orange). These vectors are further diagrammed in the second image.
If you flip any of the three core variables, the curve offset direction will change (Flipping the Z-Axis, the Curve Direction, or the distance value from positive to negative). You can carry out these experiments yourself by following the video and script links above. So how can we use this information to get consistent results in our definitions?
There are a couple approaches to this depending on where your curve has originated from and whether it's open or closed. As I've previously mentioned, the Flip Curve component will be your friend here.
The first approach is to control the direction the curve is drawn and maintain that direction through your definition. Whenever you perform an operation that could change the curve direction, you can use your original curve as the "Guide" input for the "Flip Curve" Component and restore the direction
The second approach is to flip the curve in the correct direction only at the end for the Offset function. I've written a few clusters to help with that task.
For open curves, I use my user cluster "Flip Axis" to flip my curve in some general input vector direction. The logic is a little hacky but has surprisingly been one of my most robust components across many of my definitions. Detailed further in the video. Link at the bottom\
For closed curves, I follow a different procedure which works in quite a few situations.
This only works when the centroid is inside the closed curve. In cases where the centroid doesn't fall within the closed curve, you could write some different logic for step one. I have some alternative approaches for these outlier cases which I would be open to sharing if there is interest.
(Insert Link)
ZIP file with:
- Flip Axis User Cluster
- Offset Curve Visualizer (Human and Wombat Plug-Ins Required)