in ConstraintLayoutExamples/CycleEditor/src/com/google/androidstudio/motionlayoutcycles/MonotoneSpline.java [29:67]
public MonotoneSpline(double[] time, double[][] y) {
final int N = time.length;
final int dim = y[0].length;
double[][] slope = new double[N - 1][dim]; // could optimize this out
double[][] tangent = new double[N][dim];
for (int j = 0; j < dim; j++) {
for (int i = 0; i < N - 1; i++) {
double dt = time[i + 1] - time[i];
slope[i][j] = (y[i + 1][j] - y[i][j]) / dt;
if (i == 0) {
tangent[i][j] = slope[i][j];
} else {
tangent[i][j] = (slope[i - 1][j] + slope[i][j]) * 0.5f;
}
}
tangent[N - 1][j] = slope[N - 2][j];
}
for (int i = 0; i < N - 1; i++) {
for (int j = 0; j < dim; j++) {
if (slope[i][j] == 0.) {
tangent[i][j] = 0.;
tangent[i + 1][j] = 0.;
} else {
double a = tangent[i][j] / slope[i][j];
double b = tangent[i + 1][j] / slope[i][j];
double h = Math.hypot(a, b);
if (h > 9.0) {
double t = 3. / h;
tangent[i][j] = t * a * slope[i][j];
tangent[i + 1][j] = t * b * slope[i][j];
}
}
}
}
mT = time;
mY = y;
mTangent = tangent;
}