Reputation: 689
As an input I have set of 'base' points (e.g. 9 points), and as an output I must return another set of points, which describe a curve.
A1-A9 is an input; these are the 'base' points. My task is to return a set of points, from which the user can build the depicted curve, the black line from A1-A9
My mathematical skills are low, and Googling is not very helpful. As I understand, this can be a cubic spline. I have found some C-based source code, but this code loops endlessly when I try to build spline parts, where nextPoint.x < currentPoint.x
.
Please, explain me, what kind of splines, bezier paths, or other constructs I should use for my task. It will be very good if you point me to code, an algorithm, or a good manual for dummies.
Upvotes: 2
Views: 1992
Reputation: 1
If you have MATLAB license,
x = -4:4;
y = [0 .15 1.12 2.36 2.36 1.46 .49 .06 0];
cs = spline(x,[0 y 0]);
xx = linspace(-4,4,101);
y=ppval(cs,xx);
Upvotes: 0
Reputation: 689
Thank you all. I found the solution. For build 2D curve by basic points I do follow:
I found this article about a cubic spline with C++ and C# examples. This example allows to find interpolation values of 'one dimension' cubic spline by base points. Because I need a two dimension cubic spline - I create two one dimension splines - for 'x' and 'y' axes. Next, Next, I was run a cycle from first point to end point with some step and in each iteration of cycle I found interpolation value. From interpolation value I was make a point. So, when cycle has be ended I get a curve.
pseudo code (using spline class from article pointed above):
- (array*)splineByBasePoints:(array*)basePoints
{
int n = basePoints.count;
cubic_spline xSpline, ySpline;
xSpline.build_spline(basePoints.pointNumbers, basePoints.XValuesOfPoints, n);
ySpline.build_spline(basePoints.pointNumbers, basePoints.YValuesOfPoints, n);
array curve;
int t = 1; //t - intermediate point. '1' because number of point, not index
for (; t <= n; t += step)
{
[curve addToArray:PontWithXY([xSpline f:t], [ySpline f:t])];
}
return array;
}
Upvotes: 0
Reputation: 3775
Use Interpolation methods to generate the intermediate points on your curve.
For example, given the CubicInterpolate function:
double CubicInterpolate(
double y0,double y1,
double y2,double y3,
double mu)
{
double a0,a1,a2,a3,mu2;
mu2 = mu*mu;
a0 = y3 - y2 - y0 + y1;
a1 = y0 - y1 - a0;
a2 = y2 - y0;
a3 = y1;
return(a0*mu*mu2+a1*mu2+a2*mu+a3);
}
to find the point halfway between point[1]
and point[2]
on a cubic spline, you would use:
newPoint.X = CubicInterpolate(point[0].X, point[1].X, point[2].X, point[3].X, 0.5);
newPoint.Y = CubicInterpolate(point[0].Y, point[1].Y, point[2].Y, point[3].Y, 0.5);
point[0]
and point[3]
do affect the section of the curve between point[1]
and point[2]
. At either end of the curve, simply use the end point again.
To ensure a roughly equal distance between points, you can calculate the distance between input points to determine how many intermediate points (and mu
values) to generate. So, for points that are further apart, you would use many more mu
values between 0
and 1
. Conversely, for points that are very close together, you may not need to add intermediate points at all.
Upvotes: 1