# Structure for Bezier curves

Hello,

in my private math library i have structures for calculating bezier curves. I think this could be useful for OpenTK too, or? Within my personal projekt i use these structures to calculate and draw bezier curves with OpenGL.

I have one structure for quadric bezier curves, one structure for cubic bezier curves and one struct for bezier curves with any count of anchor points.

georg

## Comment viewing options

### Re: Structure for Bezier curves

This would be interesting for sure, but does it use the OpenTK.Math structs? What do the command parameters and return look like?

### Re: Structure for Bezier curves

OpenTK.Math consists almost entirely of use contributions, and enhancements are always welcome. This would be an especially welcome addition, as this part of GLU doesn't fit well the managed world.

Can you post a few usage examples?

### Re: Structure for Bezier curves

at the moment it does not use the OpenTK.Math structs, but of course i'll change this.

usage for example:

```BezierCurveCubic bezier = new BezierCurveCubic();

// setup anchor points and control points
bezier.StartAnchor = new Vector2D(0.0f, 0.0f);
bezier.EndAnchor = new Vector2D(10.0f, 10.0f);
bezier.FirstControlPoint = new Vector2D(3.0f, 8.0f);
bezier.SecondControlPoint = new Vector2D(7.0f, 2.0f);

Vector2D oldPoint = bezier.StartAnchor;
Vector2D point = new Vector2D();

// calculate 100 points on the curve
for (float t = 0.0f; t <= 1.0f; t += 0.01f)
{
point = bezier.CalculatePoint(t);

// draw with opengl a line from oldPoint to point
oldPoint = point;
}

// calculate length of curve with a precision of 0.01f (100 steps)
float length = bezier.CalculateLength(0.01f);```

The structure `BezierCurveQuadric` has only one control point and the generic structure `BezierCurve` has a list of all points (where the first and the last point are the anchor points).

Additionally my structures have a field `Parallel` which enables you to calculate the prallel curve of a bezier curve. Example:

```BezierCurveCubic bezier2 = bezier; // bezier from above

bezier2.Parallel = 5.0f;
bezier.Parallel = -5.0f;

// drawing both curves results in a smooth track```

Greetings

Georg

### Re: Structure for Bezier curves

Interesting API, I was kinda expecting something like
`static Vec3[] GetBezierCubicPath(Vec3 Start, Vec3 Control1, Vec3 Control2, Vec3 End, uint steps);`
Your approach is way more flexible though, and it should be trivial to port it to use OpenTK.Math's Vector3 struct :)

### Re: Structure for Bezier curves

Ok, so i'll start working on a Patch that adds theses threes structures to the repository. Is the code already going into the next release or will it be integrated later?

Ah and by the way i add one or two functions to the `OpenTK.Math.Functions` class for calculating binomial coefficents (that is needed for the bezier calculations).

I saw that in the trunk there are now `double` versions of structures like `Vector3`. So i'm wondering ...
1) will `Vector3` keep its name or will it be renamed to `Vector3f` (would be very reasonable)
2) is thare already code inside OpenTK that uses OpenTK.Math structures actively? Or is it more or less a 'give-away' to the users of OpenTK so that they get a math library for free?

I think the best would be to have one generic structure `Vector3<float>`, that would allow us to reduce code size. Additionally it would be cool to define an alias `Vector3f` for `Vector3<float>`, but sadly that does not work with C#.

And if we don't use generic version ... should the bezier structures go with `floats` or `doubles` (at the moment i use floats)?

georg

### Re: Structure for Bezier curves

1) They'll stay `Vector3`. No need to add clutter to the default codepath (if you need double versions you'll have to call them explicitly).
2) Two parts rely on OpenTK.Math: OpenGL/OpenAL (overloads) and OpenTK.Fonts. 0.9.1 and later versions will ship with an OpenTK.Utilities.dll (shorthand: TKU), and some utilities will be moved there (OpenTK.Fonts, for example). Since Bezier curves rely on the core OpenTK.dll and not vice versa, they belong to TKU.

There is an advantage in being in TKU: there's more time to add features. If you get the patch ready by next week, beziers will be in 0.9.1 - I'd be more reluctant to add functionality to the core late in the release cycle. :)

Regarding generics, this was decided against in the past. The base OpenTK.Math structures (vectors, matrices, quaternions) should be as lightweight as possible. Generics would reduce the neccessary code at the expense of execution speed (relevant discussion) - and since the bulk of the code is already written, there's little point to rewrite everything at this point :)

It's probably best to target the float version first, as that's the most useful one. We can always add the double version in the future when/if it becomes necessary. Also, TKU classes do not need to be lightweight (how many bezier curves are you going to pass around per frame?) Generics are allowed there - the only limitation is to avoid generating garbage, if at all possible.

### Re: Structure for Bezier curves

Ok ... i will keep the bezier structs non-generic and let them use floats.

"how many bezier curves are you going to pass around per frame?"

not so many .. sometimes zero and sometimes 20, but anyway i put the geometry - when possible - into a precomputed vertex array or a vertex buffer object.

georg

### Re: Structure for Bezier curves

So ... the patch is ready ... i used the current source code out of the subversion repository to create the patch.

Changes:

* Added BezierCurve structure for bezier curves with as many points as you want
* Added BezierCurveQuadric structure with two anchor points and one control point
* Added BezierCurveCubic structure with two anchor points and two control points
* Added two functions to Functions.cs for calculating the factorial of a number and for calculating the binomial coefficient
* Added the property 'Perpendicular' to Vector2 and Vector2d for creating a vector that is perpendicular to the current one (the cross product in two dimensions)

Here is the patch: http://trackplanner.de/files/BezierPatch.patch

feel free to 'criticize' my code :-)

georg

### Re: Structure for Bezier curves

Good work! I skimmed through the code and it looks solid enough, will test more thoroughly tomorrow.

1. Replace the `public BezierCurve(List<Vector2> points)` constructor with `public BezierCurve(IEnumerable<Vector2> points)`. The more general the interface, the better: `IEnumerable` or `IList` allow the user to pass a `Vector2[]`, while `List` doesn't.
2. Store the points into a `Vector2[]` instead of `List<Vector2>`. Since you don't actually `Add` or `Remove` elements, there is no need to create a new generic list.
3. Foreach loops can be more efficient than for-loops, by skipping bound checking. You can also concatenate the two loops in e.g. `private Vector2 CalculatePointOfDerivative(float t)` for a nice speed gain (hope I parsed the code correctly! :) )
```foreach (Vector2 v in Points)
{
r.X += ...
r.Y += ...
}```
4. Check for null references in the constructors:
```if (points == null)
throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures.");```

Small changes, but they'll help make the code more robust and efficient. :)

### Re: Structure for Bezier curves

Thanks.

1) yes, that makes sense
2) the property 'Points' is public, so you can access/add/remove points from outside. In my project i need this functionality, because i must manipulate curves during runtime. And the performance difference between lists and arrays is imo not so large, especcialy when using enumerators (foreach).
3) Yes you're completely right. I don't not whether i merged the two loops not myself.
4) Ok.

i'll make the changes at home