Loading core/java/android/gesture/GestureLibrary.java +7 −3 Original line number Diff line number Diff line Loading @@ -136,7 +136,7 @@ public class GestureLibrary { * @return a list of predictions of possible entries for a given gesture */ public ArrayList<Prediction> recognize(Gesture gesture) { Instance instance = Instance.createInstance(mSequenceType, gesture, null); Instance instance = Instance.createInstance(mSequenceType, mOrientationStyle, gesture, null); return mClassifier.classify(mSequenceType, instance.vector); } Loading @@ -156,7 +156,7 @@ public class GestureLibrary { mNamedGestures.put(entryName, gestures); } gestures.add(gesture); mClassifier.addInstance(Instance.createInstance(mSequenceType, gesture, entryName)); mClassifier.addInstance(Instance.createInstance(mSequenceType, mOrientationStyle, gesture, entryName)); mChanged = true; } Loading Loading @@ -337,10 +337,14 @@ public class GestureLibrary { for (int j = 0; j < gestureCount; j++) { final Gesture gesture = Gesture.deserialize(in); gestures.add(gesture); classifier.addInstance(Instance.createInstance(mSequenceType, gesture, name)); classifier.addInstance(Instance.createInstance(mSequenceType, mOrientationStyle, gesture, name)); } namedGestures.put(name, gestures); } } Learner getLearner() { return mClassifier; } } core/java/android/gesture/GestureStroke.java +6 −5 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package android.gesture; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; Loading Loading @@ -147,10 +146,12 @@ public class GestureStroke { final float[] pts = GestureUtilities.temporalSampling(this, numSample); final RectF rect = boundingBox; final Matrix matrix = new Matrix(); matrix.setTranslate(-rect.left, -rect.top); matrix.postScale(width / rect.width(), height / rect.height()); matrix.mapPoints(pts); GestureUtilities.translate(pts, -rect.left, -rect.top); float sx = width / rect.width(); float sy = height / rect.height(); float scale = sx > sy ? sy : sx; GestureUtilities.scale(pts, scale, scale); float mX = 0; float mY = 0; Loading core/java/android/gesture/GestureUtilities.java +35 −9 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package android.gesture; import android.graphics.RectF; import android.graphics.Matrix; import android.util.Log; import java.util.ArrayList; Loading Loading @@ -380,22 +379,17 @@ final class GestureUtilities { } static OrientedBoundingBox computeOrientedBoundingBox(float[] points, float[] centroid) { Matrix tr = new Matrix(); tr.setTranslate(-centroid[0], -centroid[1]); tr.mapPoints(points); translate(points, -centroid[0], -centroid[1]); double[][] array = computeCoVariance(points); double[] targetVector = computeOrientation(array); float angle; if (targetVector[0] == 0 && targetVector[1] == 0) { angle = -90; angle = (float) -Math.PI/2; } else { // -PI<alpha<PI angle = (float) Math.atan2(targetVector[1], targetVector[0]); angle = (float) (180 * angle / Math.PI); Matrix trans = new Matrix(); trans.setRotate(-angle); trans.mapPoints(points); rotate(points, -angle); } float minx = Float.MAX_VALUE; Loading Loading @@ -446,4 +440,36 @@ final class GestureUtilities { } return targetVector; } static float[] rotate(float[] points, double angle) { double cos = Math.cos(angle); double sin = Math.sin(angle); int size = points.length; for (int i = 0; i < size; i += 2) { float x = (float) (points[i] * cos - points[i + 1] * sin); float y = (float) (points[i] * sin + points[i + 1] * cos); points[i] = x; points[i + 1] = y; } return points; } static float[] translate(float[] points, float dx, float dy) { int size = points.length; for (int i = 0; i < size; i += 2) { points[i] += dx; points[i + 1] += dy; } return points; } static float[] scale(float[] points, float sx, float sy) { int size = points.length; for (int i = 0; i < size; i += 2) { points[i] *= sx; points[i + 1] *= sy; } return points; } } core/java/android/gesture/Instance.java +15 −17 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package android.gesture; import android.graphics.Matrix; /** * An instance represents a sample if the label is available or a query if the Loading @@ -28,7 +27,9 @@ class Instance { private static final int PATCH_SAMPLE_SIZE = 16; private final static float[] ORIENTATIONS = { 0, 45, 90, 135, 180, -0, -45, -90, -135, -180 0, (float) (Math.PI / 4), (float) (Math.PI / 2), (float) (Math.PI * 3 / 4), (float) Math.PI, -0, (float) (-Math.PI / 4), (float) (-Math.PI / 2), (float) (-Math.PI * 3 / 4), (float) -Math.PI }; // the feature vector Loading Loading @@ -68,11 +69,11 @@ class Instance { * @param label * @return the instance */ static Instance createInstance(int samplingType, Gesture gesture, String label) { static Instance createInstance(int sequenceType, int orientationType, Gesture gesture, String label) { float[] pts; Instance instance; if (samplingType == GestureLibrary.SEQUENCE_SENSITIVE) { pts = temporalSampler(samplingType, gesture); if (sequenceType == GestureLibrary.SEQUENCE_SENSITIVE) { pts = temporalSampler(orientationType, gesture); instance = new Instance(gesture.getID(), pts, label); instance.normalize(); } else { Loading @@ -86,15 +87,14 @@ class Instance { return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE); } private static float[] temporalSampler(int samplingType, Gesture gesture) { private static float[] temporalSampler(int orientationType, Gesture gesture) { float[] pts = GestureUtilities.temporalSampling(gesture.getStrokes().get(0), SEQUENCE_SAMPLE_SIZE); float[] center = GestureUtilities.computeCentroid(pts); float orientation = (float)Math.atan2(pts[1] - center[1], pts[0] - center[0]); orientation *= 180 / Math.PI; float adjustment = -orientation; if (samplingType == GestureLibrary.ORIENTATION_SENSITIVE) { if (orientationType == GestureLibrary.ORIENTATION_SENSITIVE) { int count = ORIENTATIONS.length; for (int i = 0; i < count; i++) { float delta = ORIENTATIONS[i] - orientation; Loading @@ -104,10 +104,8 @@ class Instance { } } Matrix m = new Matrix(); m.setTranslate(-center[0], -center[1]); m.postRotate(adjustment); m.mapPoints(pts); GestureUtilities.translate(pts, -center[0], -center[1]); GestureUtilities.rotate(pts, adjustment); return pts; } Loading core/java/android/gesture/InstanceLearner.java +2 −7 Original line number Diff line number Diff line Loading @@ -16,14 +16,9 @@ package android.gesture; import android.util.Config; import android.util.Log; import static android.gesture.GestureConstants.*; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.TreeMap; /** Loading @@ -32,7 +27,7 @@ import java.util.TreeMap; class InstanceLearner extends Learner { @Override ArrayList<Prediction> classify(int gestureType, float[] vector) { ArrayList<Prediction> classify(int sequenceType, float[] vector) { ArrayList<Prediction> predictions = new ArrayList<Prediction>(); ArrayList<Instance> instances = getInstances(); int count = instances.size(); Loading @@ -43,7 +38,7 @@ class InstanceLearner extends Learner { continue; } double distance; if (gestureType == GestureLibrary.SEQUENCE_SENSITIVE) { if (sequenceType == GestureLibrary.SEQUENCE_SENSITIVE) { distance = GestureUtilities.cosineDistance(sample.vector, vector); } else { distance = GestureUtilities.squaredEuclideanDistance(sample.vector, vector); Loading Loading
core/java/android/gesture/GestureLibrary.java +7 −3 Original line number Diff line number Diff line Loading @@ -136,7 +136,7 @@ public class GestureLibrary { * @return a list of predictions of possible entries for a given gesture */ public ArrayList<Prediction> recognize(Gesture gesture) { Instance instance = Instance.createInstance(mSequenceType, gesture, null); Instance instance = Instance.createInstance(mSequenceType, mOrientationStyle, gesture, null); return mClassifier.classify(mSequenceType, instance.vector); } Loading @@ -156,7 +156,7 @@ public class GestureLibrary { mNamedGestures.put(entryName, gestures); } gestures.add(gesture); mClassifier.addInstance(Instance.createInstance(mSequenceType, gesture, entryName)); mClassifier.addInstance(Instance.createInstance(mSequenceType, mOrientationStyle, gesture, entryName)); mChanged = true; } Loading Loading @@ -337,10 +337,14 @@ public class GestureLibrary { for (int j = 0; j < gestureCount; j++) { final Gesture gesture = Gesture.deserialize(in); gestures.add(gesture); classifier.addInstance(Instance.createInstance(mSequenceType, gesture, name)); classifier.addInstance(Instance.createInstance(mSequenceType, mOrientationStyle, gesture, name)); } namedGestures.put(name, gestures); } } Learner getLearner() { return mClassifier; } }
core/java/android/gesture/GestureStroke.java +6 −5 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package android.gesture; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; Loading Loading @@ -147,10 +146,12 @@ public class GestureStroke { final float[] pts = GestureUtilities.temporalSampling(this, numSample); final RectF rect = boundingBox; final Matrix matrix = new Matrix(); matrix.setTranslate(-rect.left, -rect.top); matrix.postScale(width / rect.width(), height / rect.height()); matrix.mapPoints(pts); GestureUtilities.translate(pts, -rect.left, -rect.top); float sx = width / rect.width(); float sy = height / rect.height(); float scale = sx > sy ? sy : sx; GestureUtilities.scale(pts, scale, scale); float mX = 0; float mY = 0; Loading
core/java/android/gesture/GestureUtilities.java +35 −9 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package android.gesture; import android.graphics.RectF; import android.graphics.Matrix; import android.util.Log; import java.util.ArrayList; Loading Loading @@ -380,22 +379,17 @@ final class GestureUtilities { } static OrientedBoundingBox computeOrientedBoundingBox(float[] points, float[] centroid) { Matrix tr = new Matrix(); tr.setTranslate(-centroid[0], -centroid[1]); tr.mapPoints(points); translate(points, -centroid[0], -centroid[1]); double[][] array = computeCoVariance(points); double[] targetVector = computeOrientation(array); float angle; if (targetVector[0] == 0 && targetVector[1] == 0) { angle = -90; angle = (float) -Math.PI/2; } else { // -PI<alpha<PI angle = (float) Math.atan2(targetVector[1], targetVector[0]); angle = (float) (180 * angle / Math.PI); Matrix trans = new Matrix(); trans.setRotate(-angle); trans.mapPoints(points); rotate(points, -angle); } float minx = Float.MAX_VALUE; Loading Loading @@ -446,4 +440,36 @@ final class GestureUtilities { } return targetVector; } static float[] rotate(float[] points, double angle) { double cos = Math.cos(angle); double sin = Math.sin(angle); int size = points.length; for (int i = 0; i < size; i += 2) { float x = (float) (points[i] * cos - points[i + 1] * sin); float y = (float) (points[i] * sin + points[i + 1] * cos); points[i] = x; points[i + 1] = y; } return points; } static float[] translate(float[] points, float dx, float dy) { int size = points.length; for (int i = 0; i < size; i += 2) { points[i] += dx; points[i + 1] += dy; } return points; } static float[] scale(float[] points, float sx, float sy) { int size = points.length; for (int i = 0; i < size; i += 2) { points[i] *= sx; points[i + 1] *= sy; } return points; } }
core/java/android/gesture/Instance.java +15 −17 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package android.gesture; import android.graphics.Matrix; /** * An instance represents a sample if the label is available or a query if the Loading @@ -28,7 +27,9 @@ class Instance { private static final int PATCH_SAMPLE_SIZE = 16; private final static float[] ORIENTATIONS = { 0, 45, 90, 135, 180, -0, -45, -90, -135, -180 0, (float) (Math.PI / 4), (float) (Math.PI / 2), (float) (Math.PI * 3 / 4), (float) Math.PI, -0, (float) (-Math.PI / 4), (float) (-Math.PI / 2), (float) (-Math.PI * 3 / 4), (float) -Math.PI }; // the feature vector Loading Loading @@ -68,11 +69,11 @@ class Instance { * @param label * @return the instance */ static Instance createInstance(int samplingType, Gesture gesture, String label) { static Instance createInstance(int sequenceType, int orientationType, Gesture gesture, String label) { float[] pts; Instance instance; if (samplingType == GestureLibrary.SEQUENCE_SENSITIVE) { pts = temporalSampler(samplingType, gesture); if (sequenceType == GestureLibrary.SEQUENCE_SENSITIVE) { pts = temporalSampler(orientationType, gesture); instance = new Instance(gesture.getID(), pts, label); instance.normalize(); } else { Loading @@ -86,15 +87,14 @@ class Instance { return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE); } private static float[] temporalSampler(int samplingType, Gesture gesture) { private static float[] temporalSampler(int orientationType, Gesture gesture) { float[] pts = GestureUtilities.temporalSampling(gesture.getStrokes().get(0), SEQUENCE_SAMPLE_SIZE); float[] center = GestureUtilities.computeCentroid(pts); float orientation = (float)Math.atan2(pts[1] - center[1], pts[0] - center[0]); orientation *= 180 / Math.PI; float adjustment = -orientation; if (samplingType == GestureLibrary.ORIENTATION_SENSITIVE) { if (orientationType == GestureLibrary.ORIENTATION_SENSITIVE) { int count = ORIENTATIONS.length; for (int i = 0; i < count; i++) { float delta = ORIENTATIONS[i] - orientation; Loading @@ -104,10 +104,8 @@ class Instance { } } Matrix m = new Matrix(); m.setTranslate(-center[0], -center[1]); m.postRotate(adjustment); m.mapPoints(pts); GestureUtilities.translate(pts, -center[0], -center[1]); GestureUtilities.rotate(pts, adjustment); return pts; } Loading
core/java/android/gesture/InstanceLearner.java +2 −7 Original line number Diff line number Diff line Loading @@ -16,14 +16,9 @@ package android.gesture; import android.util.Config; import android.util.Log; import static android.gesture.GestureConstants.*; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.TreeMap; /** Loading @@ -32,7 +27,7 @@ import java.util.TreeMap; class InstanceLearner extends Learner { @Override ArrayList<Prediction> classify(int gestureType, float[] vector) { ArrayList<Prediction> classify(int sequenceType, float[] vector) { ArrayList<Prediction> predictions = new ArrayList<Prediction>(); ArrayList<Instance> instances = getInstances(); int count = instances.size(); Loading @@ -43,7 +38,7 @@ class InstanceLearner extends Learner { continue; } double distance; if (gestureType == GestureLibrary.SEQUENCE_SENSITIVE) { if (sequenceType == GestureLibrary.SEQUENCE_SENSITIVE) { distance = GestureUtilities.cosineDistance(sample.vector, vector); } else { distance = GestureUtilities.squaredEuclideanDistance(sample.vector, vector); Loading