diff options
author | Yang Li <liyang@google.com> | 2009-12-14 15:41:07 -0800 |
---|---|---|
committer | Yang Li <liyang@google.com> | 2009-12-14 15:41:07 -0800 |
commit | 4758f1216bd16763c72500bc3c2f0fb43c08d613 (patch) | |
tree | 9a34ad5d82a1fd1a03e517de873f1bf41019e6eb /core/java | |
parent | ba8e4d240b3d5eaebbdba9351b247ac20bedadc5 (diff) | |
download | frameworks_base-4758f1216bd16763c72500bc3c2f0fb43c08d613.zip frameworks_base-4758f1216bd16763c72500bc3c2f0fb43c08d613.tar.gz frameworks_base-4758f1216bd16763c72500bc3c2f0fb43c08d613.tar.bz2 |
Added the Protractor algorithm for calculating the minimum cosine distance between gestures
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/gesture/GestureStore.java | 7 | ||||
-rwxr-xr-x | core/java/android/gesture/GestureUtilities.java | 32 | ||||
-rwxr-xr-x | core/java/android/gesture/Instance.java | 2 | ||||
-rw-r--r-- | core/java/android/gesture/InstanceLearner.java | 4 | ||||
-rwxr-xr-x | core/java/android/gesture/Learner.java | 2 |
5 files changed, 42 insertions, 5 deletions
diff --git a/core/java/android/gesture/GestureStore.java b/core/java/android/gesture/GestureStore.java index 5f1a445..11a94d1 100644 --- a/core/java/android/gesture/GestureStore.java +++ b/core/java/android/gesture/GestureStore.java @@ -65,7 +65,12 @@ public class GestureStore { // ORIENTATION_SENSITIVE and ORIENTATION_INVARIANT are only for SEQUENCE_SENSITIVE gestures public static final int ORIENTATION_INVARIANT = 1; + // at most 2 directions can be recognized public static final int ORIENTATION_SENSITIVE = 2; + // at most 4 directions can be recognized + static final int ORIENTATION_SENSITIVE_4 = 4; + // at most 8 directions can be recognized + static final int ORIENTATION_SENSITIVE_8 = 8; private static final short FILE_FORMAT_VERSION = 1; @@ -131,7 +136,7 @@ public class GestureStore { public ArrayList<Prediction> recognize(Gesture gesture) { Instance instance = Instance.createInstance(mSequenceType, mOrientationStyle, gesture, null); - return mClassifier.classify(mSequenceType, instance.vector); + return mClassifier.classify(mSequenceType, mOrientationStyle, instance.vector); } /** diff --git a/core/java/android/gesture/GestureUtilities.java b/core/java/android/gesture/GestureUtilities.java index 40d7029..f1dcd89 100755 --- a/core/java/android/gesture/GestureUtilities.java +++ b/core/java/android/gesture/GestureUtilities.java @@ -366,6 +366,38 @@ final class GestureUtilities { } return Math.acos(sum); } + + /** + * Calculate the "minimum" cosine distance between two instances + * + * @param vector1 + * @param vector2 + * @param numOrientations the maximum number of orientation allowed + * @return the distance between the two instances (between 0 and Math.PI) + */ + static double minimumCosineDistance(float[] vector1, float[] vector2, int numOrientations) { + final int len = vector1.length; + double a = 0; + double b = 0; + for (int i = 0; i < len; i += 2) { + a += vector1[i] * vector2[i] + vector1[i + 1] * vector2[i + 1]; + b += vector1[i] * vector2[i + 1] - vector1[i + 1] * vector2[i]; + } + if (a != 0) { + final double tan = b/a; + final double angle = Math.atan(tan); + if (numOrientations > 2 && Math.abs(angle) >= Math.PI / numOrientations) { + return Math.acos(a); + } else { + final double cosine = Math.cos(angle); + final double sine = cosine * tan; + return Math.acos(a * cosine + b * sine); + } + } else { + return Math.PI / 2; + } + } + static OrientedBoundingBox computeOrientedBoundingBox(ArrayList<GesturePoint> pts) { GestureStroke stroke = new GestureStroke(pts); diff --git a/core/java/android/gesture/Instance.java b/core/java/android/gesture/Instance.java index ef208ac..68a2985 100755 --- a/core/java/android/gesture/Instance.java +++ b/core/java/android/gesture/Instance.java @@ -94,7 +94,7 @@ class Instance { float orientation = (float)Math.atan2(pts[1] - center[1], pts[0] - center[0]); float adjustment = -orientation; - if (orientationType == GestureStore.ORIENTATION_SENSITIVE) { + if (orientationType != GestureStore.ORIENTATION_INVARIANT) { int count = ORIENTATIONS.length; for (int i = 0; i < count; i++) { float delta = ORIENTATIONS[i] - orientation; diff --git a/core/java/android/gesture/InstanceLearner.java b/core/java/android/gesture/InstanceLearner.java index b93b76f..9987e69 100644 --- a/core/java/android/gesture/InstanceLearner.java +++ b/core/java/android/gesture/InstanceLearner.java @@ -41,7 +41,7 @@ class InstanceLearner extends Learner { }; @Override - ArrayList<Prediction> classify(int sequenceType, float[] vector) { + ArrayList<Prediction> classify(int sequenceType, int orientationType, float[] vector) { ArrayList<Prediction> predictions = new ArrayList<Prediction>(); ArrayList<Instance> instances = getInstances(); int count = instances.size(); @@ -53,7 +53,7 @@ class InstanceLearner extends Learner { } double distance; if (sequenceType == GestureStore.SEQUENCE_SENSITIVE) { - distance = GestureUtilities.cosineDistance(sample.vector, vector); + distance = GestureUtilities.minimumCosineDistance(sample.vector, vector, orientationType); } else { distance = GestureUtilities.squaredEuclideanDistance(sample.vector, vector); } diff --git a/core/java/android/gesture/Learner.java b/core/java/android/gesture/Learner.java index feacde5..60997e0 100755 --- a/core/java/android/gesture/Learner.java +++ b/core/java/android/gesture/Learner.java @@ -79,5 +79,5 @@ abstract class Learner { instances.removeAll(toDelete); } - abstract ArrayList<Prediction> classify(int gestureType, float[] vector); + abstract ArrayList<Prediction> classify(int sequenceType, int orientationType, float[] vector); } |