## Curve Parameter Space

### September 27, 2013

One of the more common misconceptions people have regarding computational geometry has to do with curve parameters. Since the mathematics of Nurbs curves are rather involved —much of it is certainly beyond high-school level— it is quite difficult to explain how control-point coordinates, control-point weights, curve degrees and knot-vectors all conspire to complicate the parameterization of a nurbs curve. My own grip on Nurbs maths is slippery at best so I think it’s better for everyone involved if I start this discussion using much simpler types of curves.

But before we can start talking about the problem, we should first lay down some ground rules for what sort of shapes qualify as ‘curves’:

- A curve is a finite, one-dimensional object, existing in some space with an arbitrary number of dimensions. In this blog post I’ll only concern myself with two-dimensional and three-dimensional spaces as we are all familiar with them.
- Every curve must have exactly two endpoints. No more, no less.
- If the endpoints coincide, the curve is considered to be closed.
- There may be no gaps on the interior of a curve, as that would result in more than two endpoints.
- There may be no branching points on the curve, except where an endpoint is coincident with some interior point of the curve.

Basically, think of all possible curves as liquorice laces, you can stretch, bend, twist and kink them, but ultimately it’s nothing more than a bunch of deformations applied to a straight piece of chewy goop. Note that the definition above differs from the common mathematical definition of curves. Mathematicians tend to be far more inclusive and rigorous.

Since all curves have two endpoints (let’s call them *startpoint* and *endpoint*, so we know which is which) we can also say that the curve exists within a numeric interval or *domain*. This domain will consist of all the numbers in between and including two extremes^{[1]}:

The above image shows a two-dimensional curve with a domain of [0.0, 1.0]. Zero represents the startpoint of the curve, one represents the endpoint, and every number in between zero and one represents some point on the curve interior. I picked zero and one because they are neat numbers, but every domain which has a non-zero length is technically valid. It could have been [-π, +π] or [1000000.0, 1000000.1]^{[2]}.

The first thing which confuses people is that the domain of a curve has little or nothing to do with the length of the curve. You can change the domain without affecting the shape or size of a curve, and you can change the shape without affecting the domain. Worse, the amount of curve that belongs to some part of the domain has little or nothing to do with the size of that sub-domain. You can see that in the image above, there’s clearly a lot more curve in the [0.25, 0.5] subdomain than in the [0.0, 0.25] subdomain.

So what are *curve parameters* and what is meant exactly by *curve parameterization*? Every mathematical curve is defined by some collection of functions. A very famous function that you probably know well is the Sine function which —when graphed—results in the Sine wave. Since this is a two-dimensional curve, we need two functions to describe it:

*x = t**y = Sin(t)*

The first equation tells us how the curve behaves along the X-axis and the second equation defines the behaviour along the Y-axis. The variable *t* here is called the *parameter*. The curve parameterization is the word we use to describe the parameter properties of the curve, as opposed to the geometric properties. The parameterization includes things such as the domain and the parameter density, which defines the ‘speed’ of any part of the curve. If you’re still thinking of curves as stretchy liquorice, then the ‘speed’ of the curve would be akin to the thickness of the liquorice. The more you stretch a curve, the thinner the liquorice gets and the higher the curve speed.

If you want to know the *location* of this curve at any given parameter *t*, all you have to do is evaluate these two functions and you know the coordinate at *t*. If you want to know the tangent vector of this curve at the same parameter, you evaluate not the equations themselves but their first derivatives, if you want to know the curvature, you use the second derivatives and so on and so forth^{[3]}.

If we solve these equations for a collection of equally spaced *t* parameters, we get something like this:

The horizontal distance between all the red points is identical, but the vertical distance changes as a function of the Sine wave. Because of this, the actual distance between two adjacent points varies all the time. It can be as much as 0.28 when the curve is racing upwards at maximum speed and as little as 0.13 when the curve is levelling out at the top. This is a prime example of how parameter ‘density’ can vary in different portions of a curve.

Because of the way we’ve defined the above curve (using the Sine function), it is very easy and very quick to evaluate it at a certain parameter. It is however very difficult and time consuming to evaluate it at a given length. The amount of mathematical steps required to find out which parameter represents a point exactly *x* units from the startpoint along the curve is staggering. That is why practically all curve methods in Rhino and Grasshopper require parameters rather than lengths.

So let’s have a look at the progression of parameters along a Nurbs curve to see how they behave in a more complicated type of geometry. Behold a degree=2 nurbs curve with 3 equally spaced, co-linear control-points:

It actually looks like the parameter density is constant along this curve. This is because of the complete symmetry of the control-points, any effect that would cause a stretching of parameters in one place is balanced out by an equal and opposite effect. However do not think that *every* linear nurbs curve with equally spaced control-points is this neat. Introduce any additional complexity and getting a consistent parameter density will be difficult to achieve. We can see what happens when we move the middle point away from the centre:

This is causing smooth stretching and compression in both ends of the curve. The immediate *shape* of the curve is exactly the same as before, but it is no longer the same curve. The position of control-points is not the only factor determining parameter density. The knot-vector (which we will not discuss here) and the control-point weighting also play major roles. For example here the middle point has been given a weight of 10.0 as opposed to the end-points which have a weight of 1.0:

If you were to pick a random point somewhere along the length of this curve, chances are you will be on relatively straight piece. However if you pick a random parameter, then you are likely to end up somewhere on the sharp bend. So depending on your angle of attack, this curve will either appear very curvy or very straight. When you are dealing with higher order nurbs curves (degree=3 and degree=5 are very popular) then there also tends to be significant stretching of parameters near the ends of the curve^{[4]}, even without any weighting.

So now we’ve talked about Sine wave curves and Nurbs curves, what about simpler types such as lines, polylines, circles and arcs? For these types of curve it is actually easy to define them in such a way that parameter density is constant. When you sample an arc at equal *t* intervals, your step-size will be constant. And it’s not just the distance which is constant, the first, second, third, etc. etc. derivatives are also immaculate:

However convert this arc into the Nurbs equivalent (for example by turning on the control-points in Rhino), and all that beauty comes crashing down. As before, the shape of the Nurbs curve is the same as the shape of the arc, but because the parameter density is now variable, the derivatives have become unmoored as well:

So, to recap:

- Don’t confuse curve parameters with curve length.
- Don’t assume the domain of a curve has to have a specific value, it could be almost anything.
- Don’t think that walking through the domain of a curve with equal steps means you’re also moving along the curve at constant speed.
- Curves that have the same shape can have wildly different parameterizations.

I wrote an addendum to this post with a good analogy for curve parameters.

[1] If the domain consists of two complex numbers, then we’re dealing with surface-like objects. Though note that in Physics, curves with complex domains are often still called curves.

[2] In a digital environment it usually makes sense to pick a domain that is roughly equivalent (within a few orders of magnitude) with the size of the curve. But this is due to the imperfect way in which numeric operations are performed by digital computers.

[3] That is not technically correct, tangency and curvature are closely related to first and second derivatives, but they are not the same thing.

[4] Except in the case of periodic curves which are not clamped and therefore don’t get stretched.