136545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley/*
236545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley * Copyright (C) 2017 The Android Open Source Project
336545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley *
436545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley * Licensed under the Apache License, Version 2.0 (the "License");
536545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley * you may not use this file except in compliance with the License.
636545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley * You may obtain a copy of the License at
736545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley *
836545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley *      http://www.apache.org/licenses/LICENSE-2.0
936545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley *
1036545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley * Unless required by applicable law or agreed to in writing, software
1136545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley * distributed under the License is distributed on an "AS IS" BASIS,
1236545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1336545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley * See the License for the specific language governing permissions and
1436545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley * limitations under the License.
1536545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley */
1636545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley
1736545bb3f2b12af352e550c278cff9026a18ca54Sean Kelleypackage android.support.wear.widget;
1836545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley
1936545bb3f2b12af352e550c278cff9026a18ca54Sean Kelleyimport android.animation.TimeInterpolator;
2036545bb3f2b12af352e550c278cff9026a18ca54Sean Kelleyimport android.annotation.TargetApi;
2136545bb3f2b12af352e550c278cff9026a18ca54Sean Kelleyimport android.os.Build;
2236545bb3f2b12af352e550c278cff9026a18ca54Sean Kelleyimport android.support.annotation.RestrictTo;
2336545bb3f2b12af352e550c278cff9026a18ca54Sean Kelleyimport android.support.annotation.RestrictTo.Scope;
2436545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley
2536545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley/**
2636545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley * Interpolator that uses a Bezier derived S shaped curve.
2736545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley *
2836545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley * @hide
2936545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley */
3036545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley@RestrictTo(Scope.LIBRARY_GROUP)
3136545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
32e6d045e13c43411c459e3535ede6abc6b6aa1c7bSean Kelleyclass BezierSCurveInterpolator implements TimeInterpolator {
3336545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley
3436545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley    /**
35e6d045e13c43411c459e3535ede6abc6b6aa1c7bSean Kelley     * An instance of {@link BezierSCurveInterpolator}.
3636545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley     */
37e6d045e13c43411c459e3535ede6abc6b6aa1c7bSean Kelley    public static final BezierSCurveInterpolator INSTANCE = new BezierSCurveInterpolator();
3836545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley    /**
3936545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley     * Lookup table values. Generated using a Bezier curve from (0,0) to (1,1) with control points:
4036545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley     * P0 (0,0) P1 (0.4, 0) P2 (0.2, 1.0) P3 (1.0, 1.0)
4136545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley     *
4236545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley     * <p>Values sampled with x at regular intervals between 0 and 1.
4336545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley     */
4436545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley    private static final float[] VALUES = new float[]{
4536545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            0.0f, 0.0002f, 0.0009f, 0.0019f, 0.0036f, 0.0059f, 0.0086f, 0.0119f, 0.0157f, 0.0209f,
4636545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            0.0257f, 0.0321f, 0.0392f, 0.0469f, 0.0566f, 0.0656f, 0.0768f, 0.0887f, 0.1033f,
4736545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            0.1186f, 0.1349f, 0.1519f, 0.1696f, 0.1928f, 0.2121f, 0.237f, 0.2627f, 0.2892f, 0.3109f,
4836545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            0.3386f, 0.3667f, 0.3952f, 0.4241f, 0.4474f, 0.4766f, 0.5f, 0.5234f, 0.5468f, 0.5701f,
4936545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            0.5933f, 0.6134f, 0.6333f, 0.6531f, 0.6698f, 0.6891f, 0.7054f, 0.7214f, 0.7346f,
5036545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            0.7502f, 0.763f, 0.7756f, 0.7879f, 0.8f, 0.8107f, 0.8212f, 0.8326f, 0.8415f, 0.8503f,
5136545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            0.8588f, 0.8672f, 0.8754f, 0.8833f, 0.8911f, 0.8977f, 0.9041f, 0.9113f, 0.9165f,
5236545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            0.9232f, 0.9281f, 0.9328f, 0.9382f, 0.9434f, 0.9476f, 0.9518f, 0.9557f, 0.9596f,
5336545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            0.9632f, 0.9662f, 0.9695f, 0.9722f, 0.9753f, 0.9777f, 0.9805f, 0.9826f, 0.9847f,
5436545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            0.9866f, 0.9884f, 0.9901f, 0.9917f, 0.9931f, 0.9944f, 0.9955f, 0.9964f, 0.9973f,
5536545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            0.9981f, 0.9986f, 0.9992f, 0.9995f, 0.9998f, 1.0f, 1.0f
5636545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley    };
5736545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley    private static final float STEP_SIZE = 1.0f / (VALUES.length - 1);
5836545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley
5936545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley    /**
6036545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley     * To avoid users of this class creating multiple copies needlessly, the constructor is
6136545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley     * private.
6236545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley     */
63e6d045e13c43411c459e3535ede6abc6b6aa1c7bSean Kelley    private BezierSCurveInterpolator() {
6436545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley    }
6536545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley
6636545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley    @Override
6736545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley    public float getInterpolation(float input) {
6836545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley        if (input >= 1.0f) {
6936545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            return 1.0f;
7036545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley        }
7136545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley
7236545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley        if (input <= 0f) {
7336545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley            return 0f;
7436545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley        }
7536545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley
7636545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley        int position = Math.min((int) (input * (VALUES.length - 1)), VALUES.length - 2);
7736545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley
7836545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley        float quantized = position * STEP_SIZE;
7936545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley        float difference = input - quantized;
8036545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley        float weight = difference / STEP_SIZE;
8136545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley
8236545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley        return VALUES[position] + weight * (VALUES[position + 1] - VALUES[position]);
8336545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley    }
8436545bb3f2b12af352e550c278cff9026a18ca54Sean Kelley}
85