1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.inputmethod.keyboard.internal;
18
19import android.test.AndroidTestCase;
20import android.test.suitebuilder.annotation.SmallTest;
21
22@SmallTest
23public class HermiteInterpolatorTests extends AndroidTestCase {
24    private final HermiteInterpolator mInterpolator = new HermiteInterpolator();
25
26    @Override
27    protected void setUp() throws Exception {
28        super.setUp();
29    }
30
31    private static final float EPSLION = 0.0000005f;
32
33    private static void assertFloatEquals(final String message, float expected, float actual) {
34        if (Math.abs(expected - actual) >= EPSLION) {
35            fail(String.format("%s expected:<%s> but was:<%s>", message, expected, actual));
36        }
37    }
38
39    // t=0 p0=(0,1)
40    // t=1 p1=(1,0)
41    // t=2 p2=(3,2)
42    // t=3 p3=(2,3)
43    //   y
44    //   |
45    // 3 +       o p3
46    //   |
47    // 2 +           o p2
48    //   |
49    // 1 o p0
50    //   |    p1
51    // 0 +---o---+---+-- x
52    //   0   1   2   3
53    private final int[] mXCoords = { 0, 1, 3, 2 };
54    private final int[] mYCoords = { 1, 0, 2, 3 };
55    private static final int p0 = 0;
56    private static final int p1 = 1;
57    private static final int p2 = 2;
58    private static final int p3 = 3;
59
60    public void testP0P1() {
61        // [(p0 p1) p2 p3]
62        mInterpolator.reset(mXCoords, mYCoords, p0, p3 + 1);
63        mInterpolator.setInterval(p0 - 1, p0, p1, p1 + 1);
64        assertEquals("p0x", mXCoords[p0], mInterpolator.mP1X);
65        assertEquals("p0y", mYCoords[p0], mInterpolator.mP1Y);
66        assertEquals("p1x", mXCoords[p1], mInterpolator.mP2X);
67        assertEquals("p1y", mYCoords[p1], mInterpolator.mP2Y);
68        // XY-slope at p0=3.0 (-0.75/-0.25)
69        assertFloatEquals("slope x p0", -0.25f, mInterpolator.mSlope1X);
70        assertFloatEquals("slope y p0", -0.75f, mInterpolator.mSlope1Y);
71        // XY-slope at p1=1/3.0 (0.50/1.50)
72        assertFloatEquals("slope x p1",  1.50f, mInterpolator.mSlope2X);
73        assertFloatEquals("slope y p1",  0.50f, mInterpolator.mSlope2Y);
74        // t=0.0 (p0)
75        mInterpolator.interpolate(0.0f);
76        assertFloatEquals("t=0.0 x", 0.0f, mInterpolator.mInterpolatedX);
77        assertFloatEquals("t=0.0 y", 1.0f, mInterpolator.mInterpolatedY);
78        // t=0.2
79        mInterpolator.interpolate(0.2f);
80        assertFloatEquals("t=0.2 x", 0.02400f, mInterpolator.mInterpolatedX);
81        assertFloatEquals("t=0.2 y", 0.78400f, mInterpolator.mInterpolatedY);
82        // t=0.5
83        mInterpolator.interpolate(0.5f);
84        assertFloatEquals("t=0.5 x", 0.28125f, mInterpolator.mInterpolatedX);
85        assertFloatEquals("t=0.5 y", 0.34375f, mInterpolator.mInterpolatedY);
86        // t=0.8
87        mInterpolator.interpolate(0.8f);
88        assertFloatEquals("t=0.8 x", 0.69600f, mInterpolator.mInterpolatedX);
89        assertFloatEquals("t=0.8 y", 0.01600f, mInterpolator.mInterpolatedY);
90        // t=1.0 (p1)
91        mInterpolator.interpolate(1.0f);
92        assertFloatEquals("t=1.0 x", 1.0f, mInterpolator.mInterpolatedX);
93        assertFloatEquals("t=1.0 y", 0.0f, mInterpolator.mInterpolatedY);
94    }
95
96    public void testP1P2() {
97        // [p0 (p1 p2) p3]
98        mInterpolator.reset(mXCoords, mYCoords, p0, p3 + 1);
99        mInterpolator.setInterval(p1 - 1, p1, p2, p2 + 1);
100        assertEquals("p1x", mXCoords[p1], mInterpolator.mP1X);
101        assertEquals("p1y", mYCoords[p1], mInterpolator.mP1Y);
102        assertEquals("p2x", mXCoords[p2], mInterpolator.mP2X);
103        assertEquals("p2y", mYCoords[p2], mInterpolator.mP2Y);
104        // XY-slope at p1=1/3.0 (0.50/1.50)
105        assertFloatEquals("slope x p1",  1.50f, mInterpolator.mSlope1X);
106        assertFloatEquals("slope y p1",  0.50f, mInterpolator.mSlope1Y);
107        // XY-slope at p2=3.0 (1.50/0.50)
108        assertFloatEquals("slope x p2",  0.50f, mInterpolator.mSlope2X);
109        assertFloatEquals("slope y p2",  1.50f, mInterpolator.mSlope2Y);
110        // t=0.0 (p1)
111        mInterpolator.interpolate(0.0f);
112        assertFloatEquals("t=0.0 x", 1.0f, mInterpolator.mInterpolatedX);
113        assertFloatEquals("t=0.0 y", 0.0f, mInterpolator.mInterpolatedY);
114        // t=0.2
115        mInterpolator.interpolate(0.2f);
116        assertFloatEquals("t=0.2 x", 1.384f, mInterpolator.mInterpolatedX);
117        assertFloatEquals("t=0.2 y", 0.224f, mInterpolator.mInterpolatedY);
118        // t=0.5
119        mInterpolator.interpolate(0.5f);
120        assertFloatEquals("t=0.5 x", 2.125f, mInterpolator.mInterpolatedX);
121        assertFloatEquals("t=0.5 y", 0.875f, mInterpolator.mInterpolatedY);
122        // t=0.8
123        mInterpolator.interpolate(0.8f);
124        assertFloatEquals("t=0.8 x", 2.776f, mInterpolator.mInterpolatedX);
125        assertFloatEquals("t=0.8 y", 1.616f, mInterpolator.mInterpolatedY);
126        // t=1.0 (p2)
127        mInterpolator.interpolate(1.0f);
128        assertFloatEquals("t=1.0 x", 3.0f, mInterpolator.mInterpolatedX);
129        assertFloatEquals("t=1.0 y", 2.0f, mInterpolator.mInterpolatedY);
130    }
131
132    public void testP2P3() {
133        // [p0 p1 (p2 p3)]
134        mInterpolator.reset(mXCoords, mYCoords, p0, p3 + 1);
135        mInterpolator.setInterval(p2 - 1, p2, p3, p3 + 1);
136        assertEquals("p2x", mXCoords[p2], mInterpolator.mP1X);
137        assertEquals("p2y", mYCoords[p2], mInterpolator.mP1Y);
138        assertEquals("p3x", mXCoords[p3], mInterpolator.mP2X);
139        assertEquals("p3y", mYCoords[p3], mInterpolator.mP2Y);
140        // XY-slope at p2=3.0 (1.50/0.50)
141        assertFloatEquals("slope x p2",  0.50f, mInterpolator.mSlope1X);
142        assertFloatEquals("slope y p2",  1.50f, mInterpolator.mSlope1Y);
143        // XY-slope at p3=1/3.0 (-0.25/-0.75)
144        assertFloatEquals("slope x p3", -0.75f, mInterpolator.mSlope2X);
145        assertFloatEquals("slope y p3", -0.25f, mInterpolator.mSlope2Y);
146        // t=0.0 (p2)
147        mInterpolator.interpolate(0.0f);
148        assertFloatEquals("t=0.0 x", 3.0f, mInterpolator.mInterpolatedX);
149        assertFloatEquals("t=0.0 y", 2.0f, mInterpolator.mInterpolatedY);
150        // t=0.2
151        mInterpolator.interpolate(0.2f);
152        assertFloatEquals("t=0.2 x", 2.98400f, mInterpolator.mInterpolatedX);
153        assertFloatEquals("t=0.2 y", 2.30400f, mInterpolator.mInterpolatedY);
154        // t=0.5
155        mInterpolator.interpolate(0.5f);
156        assertFloatEquals("t=0.5 x", 2.65625f, mInterpolator.mInterpolatedX);
157        assertFloatEquals("t=0.5 y", 2.71875f, mInterpolator.mInterpolatedY);
158        // t=0.8
159        mInterpolator.interpolate(0.8f);
160        assertFloatEquals("t=0.8 x", 2.21600f, mInterpolator.mInterpolatedX);
161        assertFloatEquals("t=0.8 y", 2.97600f, mInterpolator.mInterpolatedY);
162        // t=1.0 (p3)
163        mInterpolator.interpolate(1.0f);
164        assertFloatEquals("t=1.0 x", 2.0f, mInterpolator.mInterpolatedX);
165        assertFloatEquals("t=1.0 y", 3.0f, mInterpolator.mInterpolatedY);
166    }
167
168    public void testJustP1P2() {
169        // [(p1 p2)]
170        mInterpolator.reset(mXCoords, mYCoords, p1, p2 + 1);
171        mInterpolator.setInterval(p1 - 1, p1, p2, p2 + 1);
172        assertEquals("p1x", mXCoords[p1], mInterpolator.mP1X);
173        assertEquals("p1y", mYCoords[p1], mInterpolator.mP1Y);
174        assertEquals("p2x", mXCoords[p2], mInterpolator.mP2X);
175        assertEquals("p2y", mYCoords[p2], mInterpolator.mP2Y);
176        // XY-slope at p1=1.0 (2.0/2.0)
177        assertFloatEquals("slope x p1", 2.00f, mInterpolator.mSlope1X);
178        assertFloatEquals("slope y p1", 2.00f, mInterpolator.mSlope1Y);
179        // XY-slope at p2=1.0 (2.0/2.0)
180        assertFloatEquals("slope x p2", 2.00f, mInterpolator.mSlope2X);
181        assertFloatEquals("slope y p2", 2.00f, mInterpolator.mSlope2Y);
182        // t=0.0 (p1)
183        mInterpolator.interpolate(0.0f);
184        assertFloatEquals("t=0.0 x", 1.0f, mInterpolator.mInterpolatedX);
185        assertFloatEquals("t=0.0 y", 0.0f, mInterpolator.mInterpolatedY);
186        // t=0.2
187        mInterpolator.interpolate(0.2f);
188        assertFloatEquals("t=0.2 x", 1.4f, mInterpolator.mInterpolatedX);
189        assertFloatEquals("t=0.2 y", 0.4f, mInterpolator.mInterpolatedY);
190        // t=0.5
191        mInterpolator.interpolate(0.5f);
192        assertFloatEquals("t=0.5 x", 2.0f, mInterpolator.mInterpolatedX);
193        assertFloatEquals("t=0.5 y", 1.0f, mInterpolator.mInterpolatedY);
194        // t=0.8
195        mInterpolator.interpolate(0.8f);
196        assertFloatEquals("t=0.8 x", 2.6f, mInterpolator.mInterpolatedX);
197        assertFloatEquals("t=0.8 y", 1.6f, mInterpolator.mInterpolatedY);
198        // t=1.0 (p2)
199        mInterpolator.interpolate(1.0f);
200        assertFloatEquals("t=1.0 x", 3.0f, mInterpolator.mInterpolatedX);
201        assertFloatEquals("t=1.0 y", 2.0f, mInterpolator.mInterpolatedY);
202    }
203}
204