MicroGestureDetectionStrategyCurvature.java :  » UnTagged » ba10-bsha-1 » ch » zhaw » ba10_bsha_1 » fingerpad » Android Open Source

Android Open Source » UnTagged » ba10 bsha 1 
ba10 bsha 1 » ch » zhaw » ba10_bsha_1 » fingerpad » MicroGestureDetectionStrategyCurvature.java
package ch.zhaw.ba10_bsha_1.fingerpad;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import android.util.Log;

public class MicroGestureDetectionStrategyCurvature implements IMicroGestureDetectionStrategy {
  private static final String TAG = "CurvatureStrategy"; 
  
  public Collection<MicroGesture> detectMicroGestures(Collection<TouchPoint> points) {
    
    float tolerance = 230;
    
    // Remove points that are too close together
    TouchPoint[] temp = new TouchPoint[points.size()];
    temp = points.toArray(temp);
    ArrayList<TouchPoint> tempResult = new ArrayList<TouchPoint>();
    TouchPoint prev = temp[0];
    tempResult.add(temp[0]);
    for(int i = 1; i < temp.length; i++) {
      double dist = Math.sqrt(Math.pow(prev.x - temp[i].x, 2) + Math.pow(prev.y - temp[i].y, 2));  
      if(dist > 15) {
        tempResult.add(temp[i]);
        prev = temp[i];
      }
    }
    ArrayList<MicroGesture> result = new ArrayList<MicroGesture>();
    MicroGesture curr_mg = new MicroGesture();

    if ((points != null) && (tempResult.size() > 3)) {
      TouchPoint[] pts = new TouchPoint[tempResult.size()];
      pts = tempResult.toArray(pts);

      float lastCurve = 0;
      for (int i = 1; i < pts.length-1; i++) {
        curr_mg.addPoint(pts[i]);
        float x1, y1;
        float x2, y2;
        x1 = pts[i-1].x - pts[i].x;
        y1 = pts[i-1].y - pts[i].y;
        x2 = pts[i+1].x - pts[i].x;
        y2 = pts[i+1].y - pts[i].y;
        float zn;    
        zn = x1 * y2 - y1 * x2;
        //Log.v(TAG, "Z: " + zn);
        if(lastCurve == 0) {
          lastCurve = zn;
        }
        else if(Math.abs(zn - lastCurve) > tolerance) {
          curr_mg.addPoint(pts[i+1]);
          
          setMicroGesture(curr_mg);
          curr_mg.setDirection(analyseMicroGestureDirection(curr_mg));
          result.add(curr_mg);
          
          curr_mg = new MicroGesture();
          //Log.v(TAG, "New Gesture: old:" + lastCurve + ", new:" + zn);
          lastCurve = 0;
        }
        else {
          //lastCurve = zn;
        }
      }
      curr_mg.addPoint(pts[pts.length -1]);
      
      setMicroGesture(curr_mg);
      curr_mg.setDirection(analyseMicroGestureDirection(curr_mg));
      result.add(curr_mg);
      
    } else {
      curr_mg = new MicroGesture(points);
      result.add(curr_mg);
    }
    
    /*ArrayList<MicroGesture> result2 = new ArrayList<MicroGesture>();
    result2.add(result.get(0));
    for (int i = 1; i < result.size(); i++) {
      MicroGesture previous = result.get(i-1);
      MicroGesture current = result.get(i);
      if (current.getPoints().size() > 3) {
        if (current.toString().equals(previous.toString())) {
          ArrayList<TouchPoint> list = current.getPoints();
          for (TouchPoint p : list) {
            previous.addPoint(p);
          }
        }
        else {
          result2.add(current);
        }
      }
      else {
        ArrayList<TouchPoint> list = current.getPoints();
        for (TouchPoint p : list) {
          previous.addPoint(p);
        }
      }
    }*/
    
    return result;
  }

  public boolean validateMicroGesture(MicroGesture microGesture) {
    // TODO Auto-generated method stub
    return false;
  }

  @Override
  public String toString() {
    return "Curvature";
  }
  
  private void setMicroGesture(MicroGesture mg) {
    ArrayList<TouchPoint> points = mg.getPoints();
    // calculate slope from first to last point
    TouchPoint a = points.get(0);
    TouchPoint b = points.get(points.size()-1);
    double m = (b.y - a.y) / (b.x - a.x);
    double q = a.y - m * a.x;
    
    // calculate if left or right, 
    // this will be decided on the point the farthest away from the line
    double max = 0;
    for(Iterator<TouchPoint> it = points.iterator(); it.hasNext(); ) {
      TouchPoint temp = it.next();
      double distance = calculateDistance(temp, m, q);
      if (Math.abs(distance) > Math.abs(max)) {
        max = distance;
      }
    }
    
    // Normalize distance by taking length of the curve into account
    max = max / Math.sqrt(Math.pow(b.y - a.y, 2) + Math.pow(b.x - a.x, 2));
    
    if (max < 0.15) {
      if (Math.sqrt(Math.pow(b.y - a.y, 2) + Math.pow(b.x - a.x, 2)) > 110) {
        mg.setType(MicroGesture.TYPE_LONG_LINE);
      }
      else {
        mg.setType(MicroGesture.TYPE_SHORT_LINE);
      }
    }
    else if (max < 0.5) {
      mg.setType(MicroGesture.TYPE_WIDE_CURVE);
    }
    else {
      mg.setType(MicroGesture.TYPE_NARROW_CURVE);
    }
    
    //Log.v(TAG, "y = " + m + "x + " + q + "; abstand: " + max);
    
    //
  }
  
  private double calculateDistance(TouchPoint a, double m1, double q1) {
    // Orthogonal line m2*x + q2
    double m2 = -1 / m1;
    
    // Calculate offset so the line goes through the point a
    double q2 = a.y - m2 * a.x;
    
    // Calculate crossing point between the two lines
    double x = (q2 - q1) / (m1 - m2);
    double y = m1 * x + q1;
    x = x - a.x;
    y = y - a.y;
    
    // Calculate the distance between point a and crossing point
    return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
  }
  
  private float analyseMicroGestureDirection(MicroGesture mg) {
    float result = 0;
    if (mg.getPoints().size() > 1) {
      TouchPoint first  = mg.getPoints().get(0);
      TouchPoint second = mg.getPoints().get(1);
      float dx = first.x - second.x;
      float dy = first.y - second.y;
      result = (float) (StrictMath.atan2(dy, dx));// - (Math.PI / 2));
    }
    return result;
  }

  @Override
  public void setFieldHeight(float field_height) {
    //fieldHeight = field_height;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.