00001 package edu.stanford.hci.r3.pen.gesture;
00002
00003 import java.io.IOException;
00004 import java.io.Writer;
00005 import java.util.ArrayList;
00006
00007 public class Gesture {
00008 ArrayList<ShapeContext> contexts = new ArrayList<ShapeContext>();
00009
00010 String name;
00011
00012 boolean rotationInvariant = false;
00013
00014 boolean timeSensitive = false;
00015
00016 public Gesture(String name) {
00017 this.name = name;
00018 }
00019
00020 public void addGesture(ShapeContext context) {
00021 contexts.add(context);
00022 }
00023
00024 public double averageMatch(ShapeContext context) {
00025
00026 double distance = 0;
00027 for (ShapeContext gesture : contexts) {
00028 distance += ShapeHistogram.shapeContextMetric(context, gesture, rotationInvariant,
00029 timeSensitive, false);
00030 }
00031 return distance / contexts.size();
00032 }
00033
00034 public double bestMatch(ShapeContext context) {
00035 double distance = Double.MAX_VALUE;
00036 for (ShapeContext gesture : contexts) {
00037 distance = Math.min(distance, ShapeHistogram.shapeContextMetric(context, gesture,
00038 rotationInvariant, timeSensitive, false));
00039 }
00040 return distance;
00041 }
00042
00043 public void determineClassParameters() {
00044
00045 int N = contexts.size();
00046 double dNoRotationNoTime = 0;
00047
00048 for (int i = 0; i < contexts.size(); i++) {
00049 ShapeContext context = contexts.get(i);
00050 for (int j = 0; j < contexts.size(); j++) {
00051 if (i == j)
00052 continue;
00053 dNoRotationNoTime += ShapeHistogram.shapeContextMetric(context, contexts.get(j),
00054 false, false, false);
00055 }
00056 }
00057 dNoRotationNoTime /= N * (N - 1);
00058 double dRotationNoTime = 0;
00059
00060 for (int i = 0; i < contexts.size(); i++) {
00061 ShapeContext context = contexts.get(i);
00062 for (int j = 0; j < contexts.size(); j++) {
00063 if (i == j)
00064 continue;
00065 dRotationNoTime += ShapeHistogram.shapeContextMetric(context, contexts.get(j),
00066 true, false, false);
00067 }
00068 }
00069 dRotationNoTime /= N * (N - 1);
00070 double dNoRotationTime = 0;
00071
00072 for (int i = 0; i < contexts.size(); i++) {
00073 ShapeContext context = contexts.get(i);
00074 for (int j = 0; j < contexts.size(); j++) {
00075 if (i == j)
00076 continue;
00077 dNoRotationTime += ShapeHistogram.shapeContextMetric(context, contexts.get(j),
00078 false, true, false);
00079 }
00080 }
00081 dNoRotationTime /= N * (N - 1);
00082 double dRotationTime = 0;
00083
00084 for (int i = 0; i < contexts.size(); i++) {
00085 ShapeContext context = contexts.get(i);
00086 for (int j = 0; j < contexts.size(); j++) {
00087 if (i == j)
00088 continue;
00089 dRotationTime += ShapeHistogram.shapeContextMetric(context, contexts.get(j), true,
00090 true, false);
00091 }
00092 }
00093 dRotationTime /= N * (N - 1);
00094 System.out.println("Class " + name + ": NN: " + dNoRotationNoTime + " YN: "
00095 + dRotationNoTime + " NY: " + dNoRotationTime + " YY: " + dRotationTime);
00096 System.out.println("Rotation score: " + dNoRotationNoTime / dRotationNoTime);
00097 }
00098
00099 public void knnMatch(ShapeContext context, int k, double[] distance, String[] clazz,
00100 boolean verbose) {
00101 for (int c = 0; c < contexts.size(); c++) {
00102 ShapeContext gesture = contexts.get(c);
00103 double d = ShapeHistogram.shapeContextMetric(context, gesture, rotationInvariant,
00104 timeSensitive, verbose);
00105 for (int i = 0; i < k; i++) {
00106 if (d < distance[i]) {
00107 for (int j = k - 1; j > i; j--) {
00108 distance[j] = distance[j - 1];
00109 clazz[j] = clazz[j - 1];
00110 }
00111 distance[i] = d;
00112 clazz[i] = name;
00113 break;
00114 }
00115 }
00116 }
00117 }
00118
00119 public void quillWrite(Writer writer) throws IOException {
00120
00121 String stripTestName = name.replace("TEST", "");
00122 writer.write("name\t" + stripTestName + "\n");
00123 boolean directionInvariant = false;
00124 boolean orientationInvariant = false;
00125 boolean sizeInvariant = false;
00126 writer.write("directionInvariant\t" + directionInvariant + "\n");
00127 writer.write("orientationInvariant\t" + orientationInvariant + "\n");
00128 writer.write("sizeInvariant\t" + sizeInvariant + "\n");
00129 writer.write("gestures\t" + contexts.size() + "\n");
00130 for (int i = 0; i < contexts.size(); i++) {
00131 contexts.get(i).quillWrite(writer);
00132 }
00133 writer.write("endcategory\n");
00134
00135 }
00136
00137 public int size() {
00138 return contexts.size();
00139 }
00140 }