Merge "Added non-uniform scaling for spatial sampling."
diff --git a/core/java/android/gesture/GestureUtilities.java b/core/java/android/gesture/GestureUtilities.java
index d6d4899..b532365 100755
--- a/core/java/android/gesture/GestureUtilities.java
+++ b/core/java/android/gesture/GestureUtilities.java
@@ -27,7 +27,10 @@
import static android.gesture.GestureConstants.*;
final class GestureUtilities {
-
+
+ private static final float SCALING_THRESHOLD = 0.26f;
+ private static final float NONUNIFORM_SCALE = (float) Math.sqrt(2);
+
private GestureUtilities() {
}
@@ -46,63 +49,82 @@
}
}
- static float[] spatialSampling(Gesture gesture, int sampleMatrixDimension) {
+ static float[] spatialSampling(Gesture gesture, int sampleMatrixDimension,
+ boolean uniformScaling) {
final float targetPatchSize = sampleMatrixDimension - 1; // edge inclusive
float[] sample = new float[sampleMatrixDimension * sampleMatrixDimension];
Arrays.fill(sample, 0);
RectF rect = gesture.getBoundingBox();
- float sx = targetPatchSize / rect.width();
- float sy = targetPatchSize / rect.height();
- float scale = sx < sy ? sx : sy;
-
+ final float gestureWidth = rect.width();
+ final float gestureHeight = rect.height();
+ float sx = targetPatchSize / gestureWidth;
+ float sy = targetPatchSize / gestureHeight;
+
+ if (uniformScaling) {
+ float scale = sx < sy ? sx : sy;
+ sx = scale;
+ sy = scale;
+ } else {
+
+ float aspectRatio = gestureWidth / gestureHeight;
+ if (aspectRatio > 1) {
+ aspectRatio = 1 / aspectRatio;
+ }
+ if (aspectRatio < SCALING_THRESHOLD) {
+ float scale = sx < sy ? sx : sy;
+ sx = scale;
+ sy = scale;
+ } else {
+ if (sx > sy) {
+ float scale = sy * NONUNIFORM_SCALE;
+ if (scale < sx) {
+ sx = scale;
+ }
+ } else {
+ float scale = sx * NONUNIFORM_SCALE;
+ if (scale < sy) {
+ sy = scale;
+ }
+ }
+ }
+ }
float preDx = -rect.centerX();
float preDy = -rect.centerY();
float postDx = targetPatchSize / 2;
float postDy = targetPatchSize / 2;
-
final ArrayList<GestureStroke> strokes = gesture.getStrokes();
final int count = strokes.size();
-
int size;
float xpos;
float ypos;
-
for (int index = 0; index < count; index++) {
final GestureStroke stroke = strokes.get(index);
float[] strokepoints = stroke.points;
size = strokepoints.length;
-
final float[] pts = new float[size];
-
for (int i = 0; i < size; i += 2) {
- pts[i] = (strokepoints[i] + preDx) * scale + postDx;
- pts[i + 1] = (strokepoints[i + 1] + preDy) * scale + postDy;
+ pts[i] = (strokepoints[i] + preDx) * sx + postDx;
+ pts[i + 1] = (strokepoints[i + 1] + preDy) * sy + postDy;
}
-
float segmentEndX = -1;
float segmentEndY = -1;
-
for (int i = 0; i < size; i += 2) {
-
float segmentStartX = pts[i] < 0 ? 0 : pts[i];
float segmentStartY = pts[i + 1] < 0 ? 0 : pts[i + 1];
-
if (segmentStartX > targetPatchSize) {
segmentStartX = targetPatchSize;
}
-
if (segmentStartY > targetPatchSize) {
segmentStartY = targetPatchSize;
}
-
plot(segmentStartX, segmentStartY, sample, sampleMatrixDimension);
-
if (segmentEndX != -1) {
// evaluate horizontally
if (segmentEndX > segmentStartX) {
xpos = (float) Math.ceil(segmentStartX);
- float slope = (segmentEndY - segmentStartY) / (segmentEndX - segmentStartX);
+ float slope = (segmentEndY - segmentStartY) /
+ (segmentEndX - segmentStartX);
while (xpos < segmentEndX) {
ypos = slope * (xpos - segmentStartX) + segmentStartY;
plot(xpos, ypos, sample, sampleMatrixDimension);
@@ -110,18 +132,19 @@
}
} else if (segmentEndX < segmentStartX){
xpos = (float) Math.ceil(segmentEndX);
- float slope = (segmentEndY - segmentStartY) / (segmentEndX - segmentStartX);
+ float slope = (segmentEndY - segmentStartY) /
+ (segmentEndX - segmentStartX);
while (xpos < segmentStartX) {
ypos = slope * (xpos - segmentStartX) + segmentStartY;
plot(xpos, ypos, sample, sampleMatrixDimension);
xpos++;
}
}
-
// evaluating vertically
if (segmentEndY > segmentStartY) {
ypos = (float) Math.ceil(segmentStartY);
- float invertSlope = (segmentEndX - segmentStartX) / (segmentEndY - segmentStartY);
+ float invertSlope = (segmentEndX - segmentStartX) /
+ (segmentEndY - segmentStartY);
while (ypos < segmentEndY) {
xpos = invertSlope * (ypos - segmentStartY) + segmentStartX;
plot(xpos, ypos, sample, sampleMatrixDimension);
@@ -129,7 +152,8 @@
}
} else if (segmentEndY < segmentStartY) {
ypos = (float) Math.ceil(segmentEndY);
- float invertSlope = (segmentEndX - segmentStartX) / (segmentEndY - segmentStartY);
+ float invertSlope = (segmentEndX - segmentStartX) /
+ (segmentEndY - segmentStartY);
while (ypos < segmentStartY) {
xpos = invertSlope * (ypos - segmentStartY) + segmentStartX;
plot(xpos, ypos, sample, sampleMatrixDimension);
@@ -137,13 +161,10 @@
}
}
}
-
segmentEndX = segmentStartX;
segmentEndY = segmentStartY;
}
}
-
-
return sample;
}
@@ -162,40 +183,44 @@
sample[index] = 1;
}
} else {
- double topLeft = Math.sqrt(Math.pow(xFloor - x, 2) + Math.pow(yFloor - y, 2));
- double topRight = Math.sqrt(Math.pow(xCeiling - x, 2) + Math.pow(yFloor - y, 2));
- double btmLeft = Math.sqrt(Math.pow(xFloor - x, 2) + Math.pow(yCeiling - y, 2));
- double btmRight = Math.sqrt(Math.pow(xCeiling - x, 2) + Math.pow(yCeiling - y, 2));
- double sum = topLeft + topRight + btmLeft + btmRight;
+ final double xFloorSq = Math.pow(xFloor - x, 2);
+ final double yFloorSq = Math.pow(yFloor - y, 2);
+ final double xCeilingSq = Math.pow(xCeiling - x, 2);
+ final double yCeilingSq = Math.pow(yCeiling - y, 2);
+ float topLeft = (float) Math.sqrt(xFloorSq + yFloorSq);
+ float topRight = (float) Math.sqrt(xCeilingSq + yFloorSq);
+ float btmLeft = (float) Math.sqrt(xFloorSq + yCeilingSq);
+ float btmRight = (float) Math.sqrt(xCeilingSq + yCeilingSq);
+ float sum = topLeft + topRight + btmLeft + btmRight;
- double value = topLeft / sum;
+ float value = topLeft / sum;
int index = yFloor * sampleSize + xFloor;
if (value > sample[index]){
- sample[index] = (float) value;
+ sample[index] = value;
}
value = topRight / sum;
index = yFloor * sampleSize + xCeiling;
if (value > sample[index]){
- sample[index] = (float) value;
+ sample[index] = value;
}
value = btmLeft / sum;
index = yCeiling * sampleSize + xFloor;
if (value > sample[index]){
- sample[index] = (float) value;
+ sample[index] = value;
}
value = btmRight / sum;
index = yCeiling * sampleSize + xCeiling;
if (value > sample[index]){
- sample[index] = (float) value;
+ sample[index] = value;
}
}
}
-
+
/**
- * Featurize a stroke into a vector of a given number of elements
+ * Featurizes a stroke into a vector of a given number of elements
*
* @param stroke
* @param sampleSize
diff --git a/core/java/android/gesture/Instance.java b/core/java/android/gesture/Instance.java
index 68a2985..bb0b340 100755
--- a/core/java/android/gesture/Instance.java
+++ b/core/java/android/gesture/Instance.java
@@ -84,7 +84,7 @@
}
private static float[] spatialSampler(Gesture gesture) {
- return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE);
+ return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE, false);
}
private static float[] temporalSampler(int orientationType, Gesture gesture) {