Instance.java revision 436466d75edb5f6fd848504d998f244426ea5a09
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 17package android.gesture; 18 19import android.graphics.Matrix; 20 21/** 22 * An instance represents a sample if the label is available or a query if the 23 * label is null. 24 */ 25class Instance { 26 private static final int SEQUENCE_SAMPLE_SIZE = 16; 27 28 private static final int PATCH_SAMPLE_SIZE = 16; 29 30 private final static float[] ORIENTATIONS = { 31 0, 45, 90, 135, 180, -0, -45, -90, -135, -180 32 }; 33 34 // the feature vector 35 final float[] vector; 36 37 // the label can be null 38 final String label; 39 40 // the id of the instance 41 final long id; 42 43 private Instance(long id, float[] sample, String sampleName) { 44 this.id = id; 45 vector = sample; 46 label = sampleName; 47 } 48 49 private void normalize() { 50 float[] sample = vector; 51 float sum = 0; 52 53 int size = sample.length; 54 for (int i = 0; i < size; i++) { 55 sum += sample[i] * sample[i]; 56 } 57 58 float magnitude = (float) Math.sqrt(sum); 59 for (int i = 0; i < size; i++) { 60 sample[i] /= magnitude; 61 } 62 } 63 64 /** 65 * create a learning instance for a single stroke gesture 66 * 67 * @param gesture 68 * @param label 69 * @return the instance 70 */ 71 static Instance createInstance(int samplingType, Gesture gesture, String label) { 72 float[] pts; 73 Instance instance; 74 if (samplingType == GestureLibrary.SEQUENCE_SENSITIVE) { 75 pts = temporalSampler(samplingType, gesture); 76 instance = new Instance(gesture.getID(), pts, label); 77 instance.normalize(); 78 } else { 79 pts = spatialSampler(gesture); 80 instance = new Instance(gesture.getID(), pts, label); 81 } 82 return instance; 83 } 84 85 private static float[] spatialSampler(Gesture gesture) { 86 return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE); 87 } 88 89 private static float[] temporalSampler(int samplingType, Gesture gesture) { 90 float[] pts = GestureUtilities.temporalSampling(gesture.getStrokes().get(0), 91 SEQUENCE_SAMPLE_SIZE); 92 float[] center = GestureUtilities.computeCentroid(pts); 93 float orientation = (float) Math.atan2(pts[1] - center[1], pts[0] - center[0]); 94 orientation *= 180 / Math.PI; 95 96 float adjustment = -orientation; 97 if (samplingType == GestureLibrary.ORIENTATION_SENSITIVE) { 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 Matrix m = new Matrix(); 108 m.setTranslate(-center[0], -center[1]); 109 m.postRotate(adjustment); 110 m.mapPoints(pts); 111 112 return pts; 113 } 114 115} 116