1 /*
2  * Copyright (C) 2008-2009 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 
17 package android.gesture;
18 
19 
20 /**
21  * An instance represents a sample if the label is available or a query if the
22  * label is null.
23  */
24 class Instance {
25     private static final int SEQUENCE_SAMPLE_SIZE = 16;
26 
27     private static final int PATCH_SAMPLE_SIZE = 16;
28 
29     private final static float[] ORIENTATIONS = {
30             0, (float) (Math.PI / 4), (float) (Math.PI / 2), (float) (Math.PI * 3 / 4),
31             (float) Math.PI, -0, (float) (-Math.PI / 4), (float) (-Math.PI / 2),
32             (float) (-Math.PI * 3 / 4), (float) -Math.PI
33     };
34 
35     // the feature vector
36     final float[] vector;
37 
38     // the label can be null
39     final String label;
40 
41     // the id of the instance
42     final long id;
43 
Instance(long id, float[] sample, String sampleName)44     private Instance(long id, float[] sample, String sampleName) {
45         this.id = id;
46         vector = sample;
47         label = sampleName;
48     }
49 
normalize()50     private void normalize() {
51         float[] sample = vector;
52         float sum = 0;
53 
54         int size = sample.length;
55         for (int i = 0; i < size; i++) {
56             sum += sample[i] * sample[i];
57         }
58 
59         float magnitude = (float)Math.sqrt(sum);
60         for (int i = 0; i < size; i++) {
61             sample[i] /= magnitude;
62         }
63     }
64 
65     /**
66      * create a learning instance for a single stroke gesture
67      *
68      * @param gesture
69      * @param label
70      * @return the instance
71      */
createInstance(int sequenceType, int orientationType, Gesture gesture, String label)72     static Instance createInstance(int sequenceType, int orientationType, Gesture gesture, String label) {
73         float[] pts;
74         Instance instance;
75         if (sequenceType == GestureStore.SEQUENCE_SENSITIVE) {
76             pts = temporalSampler(orientationType, gesture);
77             instance = new Instance(gesture.getID(), pts, label);
78             instance.normalize();
79         } else {
80             pts = spatialSampler(gesture);
81             instance = new Instance(gesture.getID(), pts, label);
82         }
83         return instance;
84     }
85 
spatialSampler(Gesture gesture)86     private static float[] spatialSampler(Gesture gesture) {
87         return GestureUtils.spatialSampling(gesture, PATCH_SAMPLE_SIZE, false);
88     }
89 
temporalSampler(int orientationType, Gesture gesture)90     private static float[] temporalSampler(int orientationType, Gesture gesture) {
91         float[] pts = GestureUtils.temporalSampling(gesture.getStrokes().get(0),
92                 SEQUENCE_SAMPLE_SIZE);
93         float[] center = GestureUtils.computeCentroid(pts);
94         float orientation = (float)Math.atan2(pts[1] - center[1], pts[0] - center[0]);
95 
96         float adjustment = -orientation;
97         if (orientationType != GestureStore.ORIENTATION_INVARIANT) {
98             int count = ORIENTATIONS.length;
99             for (int i = 0; i < count; i++) {
100                 float delta = ORIENTATIONS[i] - orientation;
101                 if (Math.abs(delta) < Math.abs(adjustment)) {
102                     adjustment = delta;
103                 }
104             }
105         }
106 
107         GestureUtils.translate(pts, -center[0], -center[1]);
108         GestureUtils.rotate(pts, adjustment);
109 
110         return pts;
111     }
112 
113 }
114