<p>For a two dimensional spline it is possible to define a left and a right side, or let us call the directions counterclockwise and clockwise side (or maybe port and starboard would be appropriate). The side is easily identified as the cross product of the tangent in direction of point order crossed by the paper plane.</p>

<p><a href="https://i.sstatic.net/TtQpx.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/TtQpx.png" alt="offset side"></a></p>

<p><strong>Image 1</strong>: Offset side in 2D.</p>

<p>The higher dimensional cases are more problematic, I will be examining the 3D space only. A free space curve has no inherent good second direction. Mathematicians have defined, what is essentially a hack, that the second direction is in the direction of curvature which has a mathematical definition. The only problem is that curvature is subject to change and can flip direction along the curve. This is not good. </p>

<p>So how to counter this? Well simplest is if a curve on a surface of a 2D plane or surface. In this case you can simply use the underlying primitives directions as reference and do a 2D case. This has the added benefit of not doing a somewhat random offset direction.</p>

<p>For the free curve case there are several approaches you can use, they all have the downside of needing to keep some extra data with you. </p>

<p>One is to calculate the location where the curvature is 0 and "cut" the curve at that point and continue with a flipped curvature direction. In case of a straight line just continue with last good direction. A variation of this is not to use curvature but a user defined vector and use that instead. </p>

<p>This can also be done numerically by sampling multiple points along and detect the flip by comparing nearby result and not letting it turn more than a certain degree untill you declare a flip (what your doing sound like a variation of this). One other is to propagate a vector along the curve. One way to do this is to specify a vector at each point and let the user flip them if he feels the need. Or interpolate vectors only at certain points on the curve.</p>

<p>Most applications simply just use the will not do it or bug out option. This has the benefit of being rather sane, as the curvature based bi-normal is a bit erratic to say the least. This way the user has to come up with a way to make the directional control with for example a ruled surface.</p>

<p>*  Bézier, NURBS or something other like a <a href="https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline" rel="nofollow noreferrer">Catmul-Rom</a> spline doesn't matter</p>

CC BY-SA 3.0
2016-08-15T17:41:23.913Z
2016-08-15T17:41:23.913Z
joojaa
<p>Using the dot product on the offset vectors provides the answer. There are three distinct cases (when I mention handles, I am refering to Bezier handles such as the ones used in Blender):</p>

<ul>
<li>the angle between the Bezier handles is greater than 90º. The dot product has to be positive</li>
<li>the angle between the Bezier handles is less than 90º. The dot product has to be negative</li>
<li>the angle is 90º.</li>
</ul>

<p>This last case is trickier. You have to sum the offset vectors, and them sum the handle vectors (which are defined as the vector from the control point to the relevant left or right handle). The dot product of these two vectors has to be positive.</p>

CC BY-SA 3.0
2016-08-14T16:23:25.170Z
2016-08-14T16:23:25.170Z
user1790813
<p>I am implementing Bezier curve offset.</p>

<p>My approach is simple:</p>

<ol>
<li>Given the handles, calculate the vectors normal to them</li>
<li>Move the handle along the normal vector.</li>
<li>If the new curve intersects the old one, reverse the offset direction.</li>
<li>etc.</li>
</ol>

<p>I would like to find an alternative to step 3. I believe the problem comes from my careless handling of vector maths (mainly calculations involving the cross product). Are there other ways to check the offset direction other than the one I just described?</p>

CC BY-SA 3.0
2016-08-15T07:02:52.420Z
Is this in 2D or 3D? In 2D what do you do if both offsets intersect?
joojaa
<bezier-curve>
Checking the correct offset direction for Bezier curve offset
user1790813
# Checking the correct offset direction for Bezier curve offset

(Asked by: username_0 on 2016-08-12)

I am implementing Bezier curve offset.

My approach is simple:

1. Given the handles, calculate the vectors normal to them
2. Move the handle along the normal vector.
3. If the new curve intersects the old one, reverse the offset direction.
4. etc.

I would like to find an alternative to step 3. I believe the problem comes from my careless handling of vector maths (mainly calculations involving the cross product). Are there other ways to check the offset direction other than the one I just described?

**Tags:** bezier-curve

> **Comments:**
> **username_1**: Is this in 2D or 3D? In 2D what do you do if both offsets intersect?  

---

## 2 answers

### Answer by username_1 on 2016-08-15. Score: 1

For a two dimensional spline it is possible to define a left and a right side, or let us call the directions counterclockwise and clockwise side (or maybe port and starboard would be appropriate). The side is easily identified as the cross product of the tangent in direction of point order crossed by the paper plane.

[![offset side](https://i.sstatic.net/TtQpx.png)](https://i.sstatic.net/TtQpx.png)

**Image 1**: Offset side in 2D.

The higher dimensional cases are more problematic, I will be examining the 3D space only. A free space curve has no inherent good second direction. Mathematicians have defined, what is essentially a hack, that the second direction is in the direction of curvature which has a mathematical definition. The only problem is that curvature is subject to change and can flip direction along the curve. This is not good.

So how to counter this? Well simplest is if a curve on a surface of a 2D plane or surface. In this case you can simply use the underlying primitives directions as reference and do a 2D case. This has the added benefit of not doing a somewhat random offset direction.

For the free curve case there are several approaches you can use, they all have the downside of needing to keep some extra data with you.

One is to calculate the location where the curvature is 0 and "cut" the curve at that point and continue with a flipped curvature direction. In case of a straight line just continue with last good direction. A variation of this is not to use curvature but a user defined vector and use that instead.

This can also be done numerically by sampling multiple points along and detect the flip by comparing nearby result and not letting it turn more than a certain degree untill you declare a flip (what your doing sound like a variation of this). One other is to propagate a vector along the curve. One way to do this is to specify a vector at each point and let the user flip them if he feels the need. Or interpolate vectors only at certain points on the curve.

Most applications simply just use the will not do it or bug out option. This has the benefit of being rather sane, as the curvature based bi-normal is a bit erratic to say the least. This way the user has to come up with a way to make the directional control with for example a ruled surface.

\* Bézier, NURBS or something other like a [Catmul-Rom](https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline) spline doesn't matter


---

### Answer by username_0 on 2016-08-14. Score: 0

Using the dot product on the offset vectors provides the answer. There are three distinct cases (when I mention handles, I am refering to Bezier handles such as the ones used in Blender):

* the angle between the Bezier handles is greater than 90º. The dot product has to be positive
* the angle between the Bezier handles is less than 90º. The dot product has to be negative
* the angle is 90º.

This last case is trickier. You have to sum the offset vectors, and them sum the handle vectors (which are defined as the vector from the control point to the relevant left or right handle). The dot product of these two vectors has to be positive.


---

