StepCurve.java
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.constraintlayout.core.motion.utils;
import java.text.DecimalFormat;
import java.util.Arrays;
/**
* This class translates a series of floating point values into a continuous
* curve for use in an easing function including quantize functions
* it is used with the "spline(0,0.3,0.3,0.5,...0.9,1)" it should start at 0 and end at one 1
*/
public class StepCurve extends Easing {
private final static boolean DEBUG = false;
MonotonicCurveFit mCurveFit;
StepCurve(String configString) {
// done this way for efficiency
str = configString;
double[] values = new double[str.length() / 2];
int start = configString.indexOf('(') + 1;
int off1 = configString.indexOf(',', start);
int count = 0;
while (off1 != -1) {
String tmp = configString.substring(start, off1).trim();
values[count++] = Double.parseDouble(tmp);
off1 = configString.indexOf(',', start = off1 + 1);
}
off1 = configString.indexOf(')', start);
String tmp = configString.substring(start, off1).trim();
values[count++] = Double.parseDouble(tmp);
mCurveFit = genSpline(Arrays.copyOf(values, count));
}
private static MonotonicCurveFit genSpline(String str) {
String wave = str;
String[] sp = wave.split("\s+");
double[] values = new double[sp.length];
for (int i = 0; i < values.length; i++) {
values[i] = Double.parseDouble(sp[i]);
}
return genSpline(values);
}
private static MonotonicCurveFit genSpline(double[] values) {
int length = values.length * 3 - 2;
int len = values.length - 1;
double gap = 1.0 / len;
double[][] points = new double[length][1];
double[] time = new double[length];
for (int i = 0; i < values.length; i++) {
double v = values[i];
points[i + len][0] = v;
time[i + len] = i * gap;
if (i > 0) {
points[i + len * 2][0] = v + 1;
time[i + len * 2] = i * gap + 1;
points[i - 1][0] = v - 1 - gap;
time[i - 1] = i * gap + -1 - gap;
}
}
if (DEBUG) {
String t = "t ";
String v = "v ";
DecimalFormat df = new DecimalFormat("#.00");
for (int i = 0; i < time.length; i++) {
t += df.format(time[i]) + " ";
v += df.format(points[i][0]) + " ";
}
System.out.println(t);
System.out.println(v);
}
MonotonicCurveFit ms = new MonotonicCurveFit(time, points);
System.out.println(" 0 " + ms.getPos(0, 0));
System.out.println(" 1 " + ms.getPos(1, 0));
return ms;
}
public double getDiff(double x) {
return mCurveFit.getSlope(x, 0);
}
public double get(double x) {
return mCurveFit.getPos(x, 0);
}
}