Curving from one point to another - c++

I have tiles that are in random spots, and they wind up at x',y' (to make a nice 2d array) by doing :
Xt = (((X′-X)/T)*t)+X ,
Yt = (((Y′-Y)/T)*t)+Y
This works well, but it is linear. I'm looking for something curvier. A little bit like a parabola works. Basically instead of getting to X' in a straight line, I'm looking for an algorithm that will curve out and end up at X' and the amount of curvature is base on a variable.
Thanks
*EDIT
I think Bezier curve look to be what I want, but I'm not sure how to implement it. Could someone please explain the quadratic bezier formula. I'm also unsure what the 'E' - like symbol does. I think it relates to a range but I'm not sure, Thanks

You're looking for Bezier Curves, or some other similar parametric curve. These are programatically quite easy to code and have the advantage of being intuitively straightforward to manipulate. The best treatise I know of is in the classic book Mathematical Elements of Computer Graphics, but any textbook on computer graphics will probably include a basic introduction.

What you're looking for is a Catmul-Rom spline, it's a type of Hermite spline that passes though the control points. Bezier curves are not the way to go, they are difficult to control in this situation.

Have a look at this page about Perlin Noise, in particular the "Interpolation" section. The general idea is that instead of a linear transfer function over t in [0, 1], you can apply something to result in smoother curves. The "smoothest" noise is a cos(t) function, but cubic or quintic polynomials can be used to approximate a cosine.

Related

B-Spline for any number of control points

I am currently working on a soft body system using numeric spring physics and I have finally got that working. My issue is that everything is currently in straight lines.
I am aiming to replicate something similar to the game "The floor is Jelly" and everything work except the smooth corners and deformation which currently are straight and angular.
I have tried using Cubic Bezier equations but that just means every 3 nodes I have a new curve. Is there an equation for Bezier splines that take in n number of control points that will work with loop of vec2's (so node[0] is the first and last control point).
Sorry I don't any code to show for this but i'm completely stumped and googling is bringing up nothing.
Simply google "B-spline library" will give you many references. Having said this, B-spline is not your only choice. You can use cubic Hermite spline (which is defined by a series of points and derivatives) (see link for details) as well.
On the other hand, you can also continue using straight lines in your system and create a curve interpolating the straight line vertices just for display purpose. To create an interpolating curve thru a series of data points, Catmull-Rom spline is a good choice for easy implementation. This approach is likely to have a better performance than really using a B-spline curve in your system.
I would use B-splines for this problem since they can represent smooth curves with minimal number of control points. In addition finding the approximate smooth surface for a given data set is a simple linear algebra problem.
I have written a simple B-spline C++ library (includes Bezier curves as well) that I am using for scientific computations, here:
https://github.com/feevos/bsplines
it can accept arbitrary number of control points / multiplicities and give you back a basis. However, creating the B-spline curve that fits your data is something you have to do.
A great implementation of B-splines (but no Bezier curves) exists also in GNU GSL (
https://www.gnu.org/software/gsl/manual/html_node/Basis-Splines.html). Again here you have to implement the control points to be 2/3D for the given basis, and fix the boundary conditions to fit your data.
More information on open/closed curves and B-splines here:
https://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/index.html

Curve fitting a series of line segments

There are a lot of curve fitting questions on SO but I can't seem to find one that addresses what I'm looking for.
The scenario is simple: I capture X/Y points on a tablet screen. I'd like to draw the resulting line segments as a smooth curve instead of a series of line segments. Many apps do this, for example: Penultimate (sketching demo at 0:36) or Autodesk Sketchbook.
Bezier curve algorithms take a fixed number of points to draw a curve and don't seem to work well with numerous multiple points. Can anyone point to an algorithm which does this well?
Fit-Curve is a Spline and not a Bezier Curve in fact. However, you can make a Bezier Curve to look like your Spline (Splines have no control points). I've searched a lot on this problem and introduced/implemented a lot of too-complex algorithms to myself, and finally I found that the task is much easier than I supposed (I do felt it must to, I swear :) )
Here is the best description on that, I'll take an excerpt from this article:
In most implementations, Bezier Curve drawing function takes two control points and a point itself (for a segment) as an arguments, so everything you need is just iteratively finding the control points for new segments (I think it is best to update last segment and draw a new one in the end of curve for every new point):
Here comes the JavaScript code (t for a simplest case is a constant smoothness of your curve):
function getControlPoints(x0,y0,x1,y1,x2,y2,t){
var d01=Math.sqrt(Math.pow(x1-x0,2)+Math.pow(y1-y0,2));
var d12=Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));
var fa=t*d01/(d01+d12);
var fb=t*d12/(d01+d12);
var p1x=x1-fa*(x2-x0);
var p1y=y1-fa*(y2-y0);
var p2x=x1+fb*(x2-x0);
var p2y=y1+fb*(y2-y0);
return [p1x,p1y,p2x,p2y];
}
Please be sure to read and understand the article, I think it is a best, shortest and clearest one.
Check out splines. They basically take a set of control points as input and output a set of cubic curve where each curve is tangent to the previous one giving a smooth outline.
See this: http://en.wikipedia.org/wiki/Cubic_Hermite_spline

Create smooth line to join N points in 3 dimensions

I have N points in 3-dimensional space. I need to join them using a line. However, if I do that using a simple line, it is not smooth and looks ugly.
My current approach is to use a Bezier curve, using the DeCasteljau algorithm for 4 points, and running that for each group of 4 points in my data set. However, the problem with this is that since I run it on say points 1-4, 5-8, 9-12, etc., separately, the line is not smooth between 4-5, 8-9, etc.
I also looked for other approaches; specifically I found this article about Catmull-Rom splines, which seem even better suited for my purpose, because the curve passes through all control points, unlike the Bezier curve. So I almost started implementing that, but then, I saw on that site that the formula works "assuming uniform spacing of control points". That is not the case for my problem.
So, my question is, what approach should I use -- Bezier, Catmull-Rom, or something completely different? If Bezier, then how to fix the non-smoothness between 4-5, 8-9, etc.? If Catmull-Rom, why won't the formula work if points are not evenly spaced, and what do I need instead?
EDIT: I am now pretty sure I want the Catmull-Rom spline, as it passes every control point which is an advantage for my application. Therefore, the main question I would like answered is why won't the formula on the link I provided work for non-uniformly spaced control points?
Thanks.
A couple of solutions:
Use a B-spline. This is a generalization of Bezier curves (a Bezier curve is a B-spline with no internal knot points.)
Use a cubic spline. Cubic splines are particularly easy to calculate. A cubic spline is continuous in the zero, first, and second derivatives across the control points. The third derivative, the cubic term, suffers a discontinuity at the control points, but it is very hard to see those discontinuities.
One key difference between a B-spline and a cubic spline is that the cubic spline will pass through all of the control points, while a B-spline does not. One way to think about it: Those internal control points are just suggestions for a B-spline but are mandatory for a cubic spline.
A meaningful line (although not the simplest to evaluate) can be found via Gaussian Processes. You set (or infer) the lengthscale over which you wish the line to vary (i.e. the smoothness of the line) and then the GP line is the most probable line through the data given the lengthscale. You can add noise to the model if you don't mind the line not passing through the data points.
Its a nice interpolation method because you can also obtain the standard deviation of your line. The line becomes more uncertain when you don't have much data in the vacinity.
You can read about them in chapter 45 of David MacKay's Information Theory, Inference, and Learning Algorithms - which you can download from the author's website here.
one solution is the following page in wikipedia: http://en.wikipedia.org/wiki/Bézier_curve, check the generalized approach for N control points.

Measuring distance along ellipse

Suppose we have an ellipse x^2/a^2 + y^2/b^2 .
Taking a point (a*cos(t),b*sint(t)) on the ellipse, what is the fastest way to find another point on the ellipse such that distance between them is a given d. [d is less than pi*a*b].
The problem was encountered when i have a corner [quarter ellipse] and need to find points along it seperated by some 'd'.
The length of a subsection of an ellipse is an elliptic integral, with no closed form solution.
In order to compute the distance along the ellipse, you will need a numerical integration routine. I recommend Romberg, or Gauss Quadrature (look up on Wikipedia). If you are doing this repeatedly, then precompute the distance across a bunch of points around the Ellipse so that you can rapidly get to the right region, then start integrating.
You will need to bisect (look up on Wikipedia) to find the desired length.
There is no analytical solution for the length of an elliptical arc. This means you won't be able to plug numbers into an equation to find a result, but instead use a method of numerical integration.
Simpsons rule is very easy to implement although most likely slower than the methods mentioned in other answers.
Now that you have a way to find the length of an elliptical arc, just measure different end points until you find one of length d to some acceptable tolerance

Convert Mouse Points to Quadratic BSplines

I'm writing a drawing program. I'm trying to take an ordered list mouse positions, and approximate a smooth Quadratic BSpline Curve. Does anyone know how to accomplish this?
Thanks!
"B-spline curve fitting based on adaptive curve refinement using dominant points" by Park & Lee and "Fair interpolation and approximation of B-splines by energy minimization and points insertion" by Vassilev seem to be solving this problem. Also there look like a few references on the first link that should help you.
Converting data points to control points in areas of high curvature and removing data points in areas of little curvature is a general approach.