Calculating points on the curve - math

Is it possible to calculate intermediate points of a curve...Here is my mirror image
In the above image.Is it possible to calculate the intermediate points(one side) by knowing starting and ending point

If you know something about the curve it is, and it all depends on what you know about the curve (start and end points, initial slopes, center points, etc). There are generally two approaches:
If you know the equation of the curve, it's possible to do this exactly. Commonly curves like this are either circles or Bezier curves, and if you know it's either of these, you can fit all the other points exactly just given a few.
You can also do a cubic spline fit. This is a standard approach to fitting smooth curves so packages to do this are very common. On a smooth curve like this, give then end points, and, say, the middle point, the fit will be almost exact. (Here, you essentially end up with a Bezier curve, though parametrized a bit differently.)

Related

Why is most software dealing with Bézier curves focusing on the cubic ones, to the detriment of other curve orders?

When you enter the Bézier curve feature of software like Microsoft Office, LibreOffice, and Blender, they let you create and juxtapose cubic, aka fourth-order, aka 4-control-point, Bézier curves. You click-and-drag creating the two points P0 and P3 and interpolate them, and the last two control points of the convex hull P1 and P2, that are not on the curve, are usually hidden or displayed as handles.
Why this focus on cubic (4 points) over quadratic (3 points), quintic (5 points), and higher-order curves?
Why is it considered uninteresting to lower or elevate the curve order?
When you complicate your curve design you usually join cubic Bézier curves together: this is what happens when you click repeatedly to add points, or subdivide. Why is so little software allowing you to define all your N control points at once, and then interpolate those with a Nth-order Bézier curve? This would be a constraint-based approach in opposition to the traditional "editing" approach (not sure how to word it).
Quadratic béziers allow curves to be joined so they share a tangent line. But they won't share the curvature. With unequal curvature, highlights and mirror effects will show an ugly discontinuity. The curvature is even more important when the curve is used to control a camera path or a robot trajectory. Cubic béziers can solve that.
Note that quadratic béziers are used in computer graphics, especially in the early days when calculation speed was more limited. For example TrueType fonts and Adobe Flash (the animation package that powered many websites until about a decade ago) depend on quadratic béziers.
Quartic curves are defined by 5 points; the curve will go through the end points, and its derivatives will be controlled by 3 more points. With cubic curves, one quickly gets an intuitive feeling of the function of the two controlling points; with a quartic the exact consequence of moving one of the inner control points is harder to guess. And when even more points would be involved, deformations would even be harder to control. Also, the computational cost goes up for curves involving more points.
These deformations are also the main reason why one doesn't use fully interpolating curves. Between the control points, undesired bends are hard to avoid.
PS: Did you check out "The Beauty of Bézier Curves"? For example, starting at 6:18, derivatives are explained. 9:07 deals with the curvature.
Probably the reason number one to join cubic splines (or low degree splines in general) is to maintain "locality" of control points i.e., moving a single control point only affects one segment of the curve or two at most if it is the joint point. That locality property is highly desirable on modeling applications. On the other hand high degree curves gives a more "global" effect to each control point.
I believe the cubic spline in particular gives the best compromise between locality and flexibility of the curve sice it can provide C^2 continuity when joining segments. The quadratic spline is also useful and valuable tool for the right problem but it only provides C^1 continuity when joining the segments, which can be a limitation for complex modeling applications.

Approximate a list of points with a short list of Bézier curves

I have a list of (x, y) points. I know how to make a list of Bézier curves which pass through all of those points and have a continuous first (and second, though less important) derivative. However, the list that I end up with is far too long. I would prefer to approximate the points I have if it lets me cut down on the number of curves I have. I would like to be able to pass a parameter of either how close an approximation I get or a maximum number of curves, preferably the former.
The reason I want this is that the end result will have a graphical UI where users can edit the Bézier curves, and it isn't critical that the curves pass through each point exactly, as long as they are close. More curves makes it harder to edit.
EDIT:
Some more information about the purpose of this. I'm trying to make image editing software. When someone loads a bitmap, I want to be able to trace a center line. Potrace is what I would use to trace the outline of a shape, but it won't work for tracing strokes. I've been able to identify lots of points along the center line, and I want to turn this data into a list of connected Bézier curves. The reason I don't want to make a Bézier spline is that there will be too many control points for this to be easy to edit. "Too many" is not an easy-to-define term, but I would like to be able to pass a parameter to limit the number of curves. Either a function that minimizes how far the curves are from the points based on a maximum number of curves or a function that minimizes the number of curves based on a maximum deviation from the points.
Several approaches exist for achieving what you want to do:
1) Use RDP algorithm to reduce the number of points, then create a list of Bezier curves passing thru the remaining points.
2) Use curve fitting algorithms (for example, Schneider algorithm) to produce multiple Bezier curves that are connected with G1 (tangent) continuity. Check out Schneider algorithm implementation in this link.
3) Use least square fitting with B-spline to produce a single B-spline curve.
From implementation point of view, approach 1 is probably the easiest one for you as you already know how to create Bezier curves interpolating a list of points. Approach 3 will be much more difficult to implement and you probably will have to convert the B-spline curve into Bezier curves so as to use them at the UI level. Please refer to this SO article for detailed discussion.

How to smooth hand drawn lines?

So I am using Kinect with Unity.
With the Kinect, we detect a hand gesture and when it is active we draw a line on the screen that follows where ever the hand is going. Every update the location is stored as the newest (and last) point in a line. However the lines can often look very choppy.
Here is a general picture that shows what I want to achieve:
With the red being the original line, and the purple being the new smoothed line. If the user suddenly stops and turns direction, we think we want it to not exactly do that but instead have a rapid turn or a loop.
My current solution is using Cubic Bezier, and only using points that are X distance away from each other (with Y points being placed between the two points using Cubic Bezier). However there are two problems with this, amongst others:
1) It often doesn't preserve the curves to the distance outwards the user drew them, for example if the user suddenly stop a line and reverse the direction there is a pretty good chance the line won't extend to point where the user reversed the direction.
2) There is also a chance that the selected "good" point is actually a "bad" random jump point.
So I've thought about other solutions. One including limiting the max angle between points (with 0 degrees being a straight line). However if the point has an angle beyond the limit the math behind lowering the angle while still following the drawn line as best possible seems complicated. But maybe it's not. Either way I'm not sure what to do and looking for help.
Keep in mind this needs to be done in real time as the user is drawing the line.
You can try the Ramer-Douglas-Peucker algorithm to simplify your curve:
https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
It's a simple algorithm, and parameterization is reasonably intuitive. You may use it as a preprocessing step or maybe after one or more other algorithms. In any case it's a good algorithm to have in your toolbox.
Using angles to reject "jump" points may be tricky, as you've seen. One option is to compare the total length of N line segments to the straight-line distance between the extreme end points of that chain of N line segments. You can threshold the ratio of (totalLength/straightLineLength) to identify line segments to be rejected. This would be a quick calculation, and it's easy to understand.
If you want to take line segment lengths and segment-to-segment angles into consideration, you could treat the line segments as vectors and compute the cross product. If you imagine the two vectors as defining a parallelogram, and if knowing the area of the parallegram would be a method to accept/reject a point, then the cross product is another simple and quick calculation.
https://www.math.ucdavis.edu/~daddel/linear_algebra_appl/Applications/Determinant/Determinant/node4.html
If you only have a few dozen points, you could randomly eliminate one point at a time, generate your spline fits, and then calculate the point-to-spline distances for all the original points. Given all those point-to-spline distances you can generate a metric (e.g. mean distance) that you'd like to minimize: the best fit would result from eliminating points (Pn, Pn+k, ...) resulting in a spline fit quality S. This technique wouldn't scale well with more points, but it might be worth a try if you break each chain of line segments into groups of maybe half a dozen segments each.
Although it's overkill for this problem, I'll mention that Euler curves can be good fits to "natural" curves. What's nice about Euler curves is that you can generate an Euler curve fit by two points in space and the tangents at those two points in space. The code gets hairy, but Euler curves (a.k.a. aesthetic curves, if I remember correctly) can generate better and/or more useful fits to natural curves than Bezier nth degree splines.
https://en.wikipedia.org/wiki/Euler_spiral

Finding sections of a NURBS curve that has a curvature over a predefined value

I am trying to find the the sharp corners of a NURBS curve. For this problem I define a limit curvature. I am trying to find the sections on the curve that has a curvature higher then this value. One option is to interpolate over the curve and calculate curvature for all values but it may take time and some sharp points are likely to be missed. Any ideas about how to find these sections in an effective way?
Computing the derivative of the curvature analytically, I guess that you will find a (terrible) expression with a polynomial at the numerator. A good polynomial solver will allow you to find the roots, hence the extrema, to split the curve in sections with a monotonic curvature, and from there find the precise solutions of k=c by regula falsi or similar.
A much simpler approach is by flattening the curve (convert to a smooth polyline) and estimating the local curvature on all triples of consecutive points (using their circumscribed circle). High curvature sections will probably also be detectable by anomalies in the point density while flattening.
The benefit of flattening over uniform sampling is that it auto-adjusts the point density.
Another idea is to resort to a method of approximation of curves by circular arcs (this can be compared to a second order flattening operation). You will find a few papers on the topic (do not confuse with circle approximation by curves), but usually these methods are complex.
Maybe it is also possible to devise an analytic formula for a lower bound on the NURBS curvature in a given interval and use that to implement a bisection approach.

Point Sequence Interpolation

Given an arbitrary sequence of points in space, how would you produce a smooth continuous interpolation between them?
2D and 3D solutions are welcome. Solutions that produce a list of points at arbitrary granularity and solutions that produce control points for bezier curves are also appreciated.
Also, it would be cool to see an iterative solution that could approximate early sections of the curve as it received the points, so you could draw with it.
The Catmull-Rom spline is guaranteed to pass through all the control points. I find this to be handier than trying to adjust intermediate control points for other types of splines.
This PDF by Christopher Twigg has a nice brief introduction to the mathematics of the spline. The best summary sentence is:
Catmull-Rom splines have C1
continuity, local control, and
interpolation, but do not lie within
the convex hull of their control
points.
Said another way, if the points indicate a sharp bend to the right, the spline will bank left before turning to the right (there's an example picture in that document). The tightness of those turns in controllable, in this case using his tau parameter in the example matrix.
Here is another example with some downloadable DirectX code.
One way is Lagrange polynominal, which is a method for producing a polynominal which will go through all given data points.
During my first year at university, I wrote a little tool to do this in 2D, and you can find it on this page, it is called Lagrange solver. Wikipedia's page also has a sample implementation.
How it works is thus: you have a n-order polynominal, p(x), where n is the number of points you have. It has the form a_n x^n + a_(n-1) x^(n-1) + ...+ a_0, where _ is subscript, ^ is power. You then turn this into a set of simultaneous equations:
p(x_1) = y_1
p(x_2) = y_2
...
p(x_n) = y_n
You convert the above into a augmented matrix, and solve for the coefficients a_0 ... a_n. Then you have a polynomial which goes through all the points, and you can now interpolate between the points.
Note however, this may not suit your purpose as it offers no way to adjust the curvature etc - you are stuck with a single solution that can not be changed.
You should take a look at B-splines. Their advantage over Bezier curves is that each part is only dependent on local points. So moving a point has no effect on parts of the curve that are far away, where "far away" is determined by a parameter of the spline.
The problem with the Langrange polynomial is that adding a point can have extreme effects on seemingly arbitrary parts of the curve; there's no "localness" like described above.
Have you looked at the Unix spline command? Can that be coerced into doing what you want?
There are several algorithms for interpolating (and exrapolating) between an aribtrary (but final) set of points. You should check out numerical recipes, they also include C++ implementations of those algorithms.
Unfortunately the Lagrange or other forms of polynomial interpolation will not work on an arbitrary set of points. They only work on a set where in one dimension e.g. x
xi < xi+1
For an arbitary set of points, e.g. an aeroplane flight path, where each point is a (longitude, latitude) pair, you will be better off simply modelling the aeroplane's journey with current longitude & latitude and velocity. By adjusting the rate at which the aeroplane can turn (its angular velocity) depending on how close it is to the next waypoint, you can achieve a smooth curve.
The resulting curve would not be mathematically significant nor give you bezier control points. However the algorithm would be computationally simple regardless of the number of waypoints and could produce an interpolated list of points at arbitrary granularity. It would also not require you provide the complete set of points up front, you could simply add waypoints to the end of the set as required.
I came up with the same problem and implemented it with some friends the other day. I like to share the example project on github.
https://github.com/johnjohndoe/PathInterpolation
Feel free to fork it.
Google "orthogonal regression".
Whereas least-squares techniques try to minimize vertical distance between the fit line and each f(x), orthogonal regression minimizes the perpendicular distances.
Addendum
In the presence of noisy data, the venerable RANSAC algorithm is worth checking out too.
In the 3D graphics world, NURBS are popular. Further info is easily googled.

Resources