content: /*
   * Copyright (C) 2008-2009 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package android.gesture;
  
  
  /**
   * An instance represents a sample if the label is available or a query if the
   * label is null.
   */
  class Instance {
      private static final int SEQUENCE_SAMPLE_SIZE = 16;
  
      private static final int PATCH_SAMPLE_SIZE = 16;
  
      private final static float[] ORIENTATIONS = {
              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
      final float[] vector;
  
      // the label can be null
      final String label;
  
      // the id of the instance
      final long id;
  
      private Instance(long id, float[] sample, String sampleName) {
          this.id = id;
          vector = sample;
          label = sampleName;
      }
  
      private void normalize() {
          float[] sample = vector;
          float sum = 0;
  
          int size = sample.length;
          for (int i = 0; i < size; i++) {
              sum += sample[i] * sample[i];
          }
  
          float magnitude = (float)Math.sqrt(sum);
          for (int i = 0; i < size; i++) {
              sample[i] /= magnitude;
          }
      }
  
      /**
       * create a learning instance for a single stroke gesture
       * 
       * @param gesture
       * @param label
       * @return the instance
       */
      static Instance createInstance(int sequenceType, int orientationType, Gesture gesture, String label) {
          float[] pts;
          Instance instance;
          if (sequenceType == GestureStore.SEQUENCE_SENSITIVE) {
              pts = temporalSampler(orientationType, gesture);
              instance = new Instance(gesture.getID(), pts, label);
              instance.normalize();
          } else {
              pts = spatialSampler(gesture);
              instance = new Instance(gesture.getID(), pts, label);
          }
          return instance;
      }
  
      private static float[] spatialSampler(Gesture gesture) {
          return GestureUtils.spatialSampling(gesture, PATCH_SAMPLE_SIZE, false);
      }
  
      private static float[] temporalSampler(int orientationType, Gesture gesture) {
          float[] pts = GestureUtils.temporalSampling(gesture.getStrokes().get(0),
                  SEQUENCE_SAMPLE_SIZE);
          float[] center = GestureUtils.computeCentroid(pts);
          float orientation = (float)Math.atan2(pts[1] - center[1], pts[0] - center[0]);
  
          float adjustment = -orientation;
          if (orientationType != GestureStore.ORIENTATION_INVARIANT) {
              int count = ORIENTATIONS.length;
              for (int i = 0; i < count; i++) {
                  float delta = ORIENTATIONS[i] - orientation;
                  if (Math.abs(delta) < Math.abs(adjustment)) {
                      adjustment = delta;
                  }
              }
          }
  
          GestureUtils.translate(pts, -center[0], -center[1]);
          GestureUtils.rotate(pts, adjustment);
  
          return pts;
      }
  
  }
  