package fr.umlv.escapeir.gesture;
import java.awt.Point;
import java.util.ArrayList;
import fr.umlv.escapeir.EscapeIR;
import fr.umlv.escapeir.gesture.GestureRecognizer.GestureID;
public abstract class CircleGesture extends Gesture {
private static final int JOIN_SHAKINESS = (int) ((EscapeIR.DIAGONALE * 2) / 100);
private static final int MINIMAL_RADIUS = (int) (EscapeIR.DIAGONALE / 35);
private static final int MAXIMAL_RADIUS = (int) (EscapeIR.DIAGONALE / 15);
/**
* defines the ID of the gesture.
*/
public CircleGesture(GestureID id) {
super(id);
}
/**
* Recognize a circle. it tests if the first and last point are close enough then it finds the largest distance between two points.
* This line will be used as a diameter for the circle, if the points draw by the user are not too far away from this circle the gesture will be recognized.
* @param ArrayList<point>
* @return boolean
*
*/
@Override
public boolean recognized(ArrayList<Point> points) {
if (points.size() < 2)
return false;
if ((int)points.get(0).distance(points.get(points.size() - 1)) > CircleGesture.JOIN_SHAKINESS)
return false;
Point farestPoint = points.get(0);
for (Point point : points)
farestPoint = ((int) points.get(0).distance(point) > (int)points.get(0).distance(farestPoint)) ? point : farestPoint;
Point center = CircleGesture.segmentMiddle(points.get(0), farestPoint);
int radius = (int) center.distance(points.get(0));
if (radius < CircleGesture.MINIMAL_RADIUS || radius > CircleGesture.MAXIMAL_RADIUS)
return false;
for (Point point : points) {
if (center.distance(point) < (radius - Gesture.shakiness))
return false;
if (center.distance(point) > (radius + Gesture.shakiness))
return false;
}
return true;
}
/**
*
* This method determines the circle's center.
* @param point1
* @param point2
* @return a point
*/
public static Point segmentMiddle(Point point1, Point point2) {
int x = (int) ((point1.getX() + point2.getX()) / 2);
int y = (int) ((point1.getY() + point2.getY()) / 2);
return new Point(x, y);
}
/**
* @param Point reference
* @param Point p1
* @param Point p2
* @param Point p3
* @return true if the circle is clockwise false other wise
*/
public static boolean isClockwise(Point reference, Point p1, Point p2, Point p3) {
return ((Gesture.isNorthWest(reference, p1) && Gesture.isNorth(reference, p2) && Gesture.isNorthEast(reference, p3))
|| (Gesture.isNorthEast(reference, p1) && Gesture.isEast(reference, p2) && Gesture.isSouthEast(reference, p3))
|| (Gesture.isSouthEast(reference, p1) && Gesture.isSouth(reference, p2) && Gesture.isSouthWest(reference, p3))
|| (Gesture.isSouthWest(reference, p1) && Gesture.isWest(reference, p2) && Gesture.isNorthWest(reference, p3)));
}
/**
* @param Point reference
* @param Point p1
* @param Point p2
* @param Point p3
* @return true if the circle is counterclockwise false other wise
*/
public static boolean isCounterClockwise(Point reference, Point p1, Point p2, Point p3) {
return CircleGesture.isClockwise(reference, p3, p2, p1);
}
}