aboutsummaryrefslogtreecommitdiff
path: root/java/api/src/aurelienribon/tweenengine/paths/CatmullRom.java
blob: 5dedae46c23a1e4428b43d427fd3f58704d54d93 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package aurelienribon.tweenengine.paths;

import aurelienribon.tweenengine.TweenPath;

/**
 * @author Aurelien Ribon | http://www.aurelienribon.com/
 */
public class CatmullRom implements TweenPath {
	@Override
	public float compute(float t, float[] points, int pointsCnt) {
		int segment = (int) Math.floor((pointsCnt-1) * t);
		segment = Math.max(segment, 0);
		segment = Math.min(segment, pointsCnt-2);

		t = t * (pointsCnt-1) - segment;

		if (segment == 0) {
			return catmullRomSpline(points[0], points[0], points[1], points[2], t);
		}

		if (segment == pointsCnt-2) {
			return catmullRomSpline(points[pointsCnt-3], points[pointsCnt-2], points[pointsCnt-1], points[pointsCnt-1], t);
		}

		return catmullRomSpline(points[segment-1], points[segment], points[segment+1], points[segment+2], t);
	}

	private float catmullRomSpline(float a, float b, float c, float d, float t) {
		float t1 = (c - a) * 0.5f;
		float t2 = (d - b) * 0.5f;

		float h1 = +2 * t * t * t - 3 * t * t + 1;
		float h2 = -2 * t * t * t + 3 * t * t;
		float h3 = t * t * t - 2 * t * t + t;
		float h4 = t * t * t - t * t;

		return b * h1 + c * h2 + t1 * h3 + t2 * h4;
	}
}