Author: I_dovelemon
Source: csdn,http://www.dxstudio.com/guide_content.aspx?id=70a2b2cf-193e-4019-859c-28210b1da81f
Date: 2015/8/25
Subject: Catmull-rom Spline interpolating
Introduction
In game development, we often encounter the following scenarios: We know some path points, we want our characters to be able to move smoothly along these path points, rather than "straight" from one point to another. For this problem, most of the game development uses a curve called Catmull-rom spline to run through the path, and then just move along the curve. Today, we start with a theoretical understanding of what is Catmull-rom Spline.
Special statement
Because, I am also in the development of the time, encountered such a problem, naturally want to find a solution from the network. In the process of looking for, but also took some detours, but the effort is not negative, and finally found a solution to the method. For the understanding of this problem, I mainly refer to an article on the network, I think it is very good explanation, so here the article no longer explain to everyone to listen to, but the original translation, and share to everyone.
Fundamentals of Mathematics
When there are some points, we tend to draw a spline based on these points, and this spline needs to pass smoothly through these points. If you want to do this, then you can look at the Catmull-rom spline. Catmull-rom spline mathematical background is very complex, but also beyond the scope of this article, no longer explained here, interested readers can search their own relevant articles to understand.
We can assume that the Catmull-rom spline is a special Bezier curve, which guarantees that it will pass through all points from the second point of control to the 2nd of the control point. Therefore, the Catmull-rom spline requires a minimum of 4 control points to be controlled.
The following formula shows how to calculate a point between a two specified point:
Output_point = P0 * (-0,5*t*t*t + t*t – 0,5*t) +
P1 * (1,5*t*t*t - 2,5*t*t + 1,0) +
P2 * (-1,5*t*t*t + 2,0*t*t + 0,5*t) +
P3 * (0,5*t*t*t – 0,5*t*t);
The p0,p1,p2,p3 here are all points on the curve, but know that the formula above only calculates the point from point P1 to P2.
The T range in the formula is [0,1], and when T changes linearly from 0 to 1, the curve moves from point P1 (t=0) to P2 (t=1 at this time). Another feature of this curve is that the tangent vectors of the point P we calculated are parallel to the tangent vectors of the two start and end points around the point.
If you want to deal with more points, you can only use the previous point, the current point and the next two points to construct the curve. For example, if you now have 5 points, p1,p2,p3,p4,p5, then we can construct two different curves, their control points are [P1,P2,P3,P4] and [P2,P3,P4,P5] respectively. When we use these two curves to draw separately from t=[0,1], we will get the two curves of P2-P3,P3-P4.
Additional Information
The attentive reader may have found that although we have 4 control points, the plotted curve can only pass through two points in the middle. This leads to, if I want the curve at the same time over the four points, how to deal with it. In fact, the method of processing, very simple, we just think of the construction of a starting point and end point to form four control points can be. For example, there are now p0,p1,p2,p3, if using [P0,P1,P2,P3] to construct the curve, the curve will only be able to pass through the P1-P2, in order to allow the curve through P0 and P3, we can artificially construct the following control points [2p0-p1, P0, P1, P2], and [P1,p2, P3,2P3-P2]. In this way, you can draw a curve that passes through all the control points.
for (int index = 1; index < points.count-2; index++) {
Cgpoint point0 = [self pointatindex:index-1 ofarray:points];
Cgpoint point1 = [self pointatindex:index ofarray:points];
Cgpoint Point2 = [self Pointatindex:index + 1 ofarray:points];
Cgpoint Point3 = [self Pointatindex:index + 2 ofarray:points];
for (int i = 1; i < granularity; i++) {
float t = (float) i * (1.0f/(float) granularity);
Float TT = t * t;
float TTT = tt * t;
Cgpoint Pi;
pi.x = 0.5 * (2*point1.x+ (point2.x-point0.x) *t + (2*point0.x-5*point1.x+4*point2.x-point3.x) *tt + (* point1.x-point0.x-3*point2.x+point3.x) *TTT);
PI.Y = 0.5 * (2*point1.y+ (POINT2.Y-POINT0.Y) *t + (2*POINT0.Y-5*POINT1.Y+4*POINT2.Y-POINT3.Y) *tt + (* POINT1.Y-POINT0.Y-3*POINT2.Y+POINT3.Y) *TTT);
if (Pi.y > Self.graphView.frame.size.height) {
PI.Y = Self.graphView.frame.size.height;
}
else if (PI.Y < 0) {
PI.Y = 0;
}
if (pi.x > point0.x) {
[Path ADDLINETOPOINT:PI];
}
}
[Path Addlinetopoint:point2];
}
Catmull-rom of interpolation technology Spline interpolating