Quadratic Bezier Curves in threejs
In threejs there is a base Curve class as well as a number of classes that work on top of this Curve Class one of which is THREE.QuadraticBezierCurve3. This Quadratic Bezier Curve class creates a Curve that defines a Curve between a start point and end point along with a control point that will effect the curve. This Can then be used for anything the requires a curve such as the tub geometry constrictor function. There are also base curve class methods like the two points method that will return an array of vector3 objects that can then be used to define movement over time, or create a geometry by making use of the set from points method for example.
THREE.QuadraticBezierCurve3 and what to know first
Read up more on the base Curve class
I wrote a post on the base Curve class all ready so that is something that you might want to read about a little first. The QuadraticBezierCurve3 class is a kind of Curve class so there is taking a moment to read about what there is to work with when it comes to curve objects in general. For the most part I do like to just use this QuadraticBezierCurve3 class for making curve objects, however there are a few other built in options for this, and if need be there is also making my own Curve classes as well based off the the main Curve class.
I also have a number of other posts on the subject of curves in threejs such as my post where I am making an updating custom geometry using curves
The Vector3 class
The arguments that I give when calling the QuadraticBezierCurve3 function are instances of the Vector3 class, also I often want to create an array of Vector3 objects. This Vector3 class is worth checking out in detail then if you have not done so all ready.
Source Code is up on Github
The source code examples that I am writing about in this post can also be found on Github.
Version Numbers matter
When I wrote this post I was using r140 of threejs.
1 - Basic examples of THREE.QuadraticBezierCurve3
To start out with this I will want to have at least one if not more basic examples of the THREE.QuadraticBezierCurve3 constructor that will return a Curve object and thus can be used anywhere such an object is called for. For now I will be sticking with just the Quadratic Bezier Curve alone as a way to create curves saving curve paths for a later section. I will be touching base on things like creating a geometry from this Curve object, but will not be getting into advanced topics like updating a geometry and so forth.
1.1 - Single Quadratic Bezier Curve and Points
One has to start somewhere with this sort of thing and with that said here I have a simply hello world style example where I am creating a Quadratic Bezier Curve and then using the Get Points method of the base curve class to create an array of vector3 objects. This array of vector3 objects can then be used to create a geometry by calling the Buffer Geometry constructor function and then using the set from points method. The returned result is then a Buffer Geometry with a position attribute alone, so this might not work well with a Mesh object which requires a few more attributes, but it will work well with say the THREE.Points constructor.
1.2 - Making a tube geometry with a curve
One thing that can be done with a curve is that it can be used as the first argument for the tube geometry constructor.
2 - Curve Paths
The Curve Paths class is a way to create a Curve object that is not just one Curve but a collection of curves. I can create a single instance of this Curve Path class and then start adding curve objects to it, such as Curves created with the Quadratic Bezier Curve constructor. This sepeshail class that is curve that is then a collection of curves is then an impoatane t tool when it comes to using the Quadratic Bezier Curve class for one of the major use case examples that I would like to use if for as ofteh I will want to have not just one but many control points as well as start and end points that make up an over all curve.
2.1 - Curve Path with Quadratic Bezier Curve and Points
There is creating an instance of a curve path by calling the THREE.CurvePath constructor function, then I just need to start adding Curves to it with the add method of this class. For this I created an array with the values that I want to create a start point, and point and control point for each curve. In then just need to loop over this array and create the Vector3 objects that I then pass to the THREE.QuadraticBezierCurve3 constructor and then add each path to the Curve Path.
I can then use the Curve Path like that of any other Curve Object and as such all the Curve class methods are there to work with such as the Get Points method. However I have found that when using a method such as that the number that I give for the number of points will be for each curve object in the curve path rather than the curve path over all.
3 - Animation loop examples
One thing that I would really like to do with curves is to create paths that I can then use to set the position and rotation of objects. That is to define a path with one or more curves, and then use the get points method or some other means to create an array of points in the form of Vector3 class objects. This array of vector3 objects can then be used as a way to go about setting the position of a mesh object over time by copying the state of a current point to the position object of the mesh object. The same can be done when it comes to setting rotation by passing a current Vector3 object to the look at method of a mesh object, or any object3d based object for that matter.
So then the best way to go about showing this would be to create one or more animation projects about the Quadratic Bezier Curve3 class.
3.1 - Setting the position of a mesh object along the path of a curve
For this first animation example I would like to create a helper function to quickly create a curve path with the Quadratic Bezier Curve class for each curve of the curve path. I can then use this helper function to create a curve path that will be used for the current position of a mesh object. I can then use the get points method to create an array of vector3 objects and I can use that to create a geometry that I will then use with the THREE.Points class to get a visual idea of what is going on with these points. Also I can make the length of the array the same as the count of frames for the animation so that I have a point in space for each frame for the mesh object. So then in my animation loop I can use the current frame number to get the current Vector3 object that I want for the mesh object.
Although I have the basic idea of what I want working fine here, I would also like to do this for setting rotation as well. Also I might want to look into other ways of getting the points that might prove to be more efficient and also get the index values for the point along the curve in a way that is different from that of the get points method. So I am going to want to create and write about at least a few more animation loop examples here I think.
3.2 - Using curves to set position an rotation of a camera
For this animation loop example I am doing more or less the same thing as the first one, only now I have to curve paths one of which I am using to set the position of a camera, and the other I am using to set the look at location for the camera. So then over time I can use these paths to define where an object will be, but also where it should be looking over time as well which is great. For this example I also expanding the collection of helper functions to included methods that help with crating an array of vector3 objects as well as creating a collection of that help to show the state of the curve as well.
3.3 - Get Points method along with get alpha methods
The get points method is great for just quickly getting an array of vector3 objects from a curve, but there are still some situations in which I will want to create my own custom get points method actually. There is also the get point method of the curve class and this is what I can use to get a single point along a curve at a time. When calling the get point method the number value that i give is not a count of points that I want, but rather an alpha value between 0 and 1 that is a single point along the curve that I want. If I want to just use a index over total count type alpha value to get the same result that is what is given when using the get points method I can do that, however it would make sense to come up with custom alpha values for this.
So for this example I made changes to the helper functions so that I am using the get point method in place of the get points method. Also I am not just using the get points method but pulling it into a helper function that can be given an get alpha method. By default the get alpha method that is used is just like that of what is used by the get points method of the curve class and I am doing just that for one curve. However I am of course defining a number of custom get alpha methods that use various features of the math utils object of threejs , as well as another one where I am using a 2d curve to define what the alpha value should be when getting a point a long a curve.
This Quadratic Bezier Curve class is then a great way to go about creating curves that can then be used to create lines and points for a scene. There is the idea of using this in conjunction with additional code to create a geometry that would be used with a mesh object, however my real interest with this thus far has to do with having a system for defining the position, and rotation of objects over time. While I was writing this I was also working on an updated revision of my sequence hooks module that I use in just about all of my video projects. While working on it I was adding a new feature that had to do with creating paths that I then use to move objects, so curves are of interest when it comes to the use of this module.