package cz.urbangaming.galgs.algorithms.triangulation;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import android.opengl.GLES20;
import android.util.Log;
import android.util.Pair;
import cz.urbangaming.galgs.GAlg;
import cz.urbangaming.galgs.utils.Point2D;
import cz.urbangaming.galgs.utils.Utils;
import cz.urbangaming.galgs.utils.XYOrderComparator;
/**
*
* @author Michal Karm Babacek
* @license GNU GPL 3.0
*
*/
public class SweepTriangulation {
private static SweepTriangulation instance = null;
private SweepTriangulation() {
}
/**
* We ain't wanna more instances lying around...
*
* @return
*/
public static synchronized SweepTriangulation getInstance() {
if (instance == null) {
instance = new SweepTriangulation();
}
return instance;
}
/**
* It still doesn't work properly :-(
* Not even for some convex polygons!
* Debug in progress...
*
* Ffffffffffffuuuuuuuuuuuuuuuuu!
*
* @param V
* @return
*/
public Pair<List<Point2D>, Integer> sweepTriangulation(List<Point2D> V) {
List<Point2D> originalV = new ArrayList<Point2D>(V);
Collections.sort(V, new XYOrderComparator());
List<Point2D> triangles = new ArrayList<Point2D>();
Deque<Point2D> stack = new ArrayDeque<Point2D>();
Log.d(GAlg.DEBUG_TAG, "Sorted V:" + V.toString());
stack.push(V.get(0));
stack.push(V.get(1));
for (int i = 2; i < V.size(); i++) {
Point2D p = V.get(i);
if (Utils.areOnTheSameChain(p, stack.getFirst(), V)) {
Log.d(GAlg.DEBUG_TAG, "Entered Case1");
Point2D tempTop = stack.pop();
while (!stack.isEmpty() && Utils.isItLegalDiagonal(p, tempTop, originalV)) {
Log.d(GAlg.DEBUG_TAG, "Case1 While loop");
triangles.add(p);
triangles.add(tempTop);
tempTop = stack.pop();
}
stack.push(p);
} else {
Log.d(GAlg.DEBUG_TAG, "Entered Case2");
Point2D top = stack.pop();
triangles.add(p);
triangles.add(top);
while (!stack.isEmpty()) {
Log.d(GAlg.DEBUG_TAG, "Case2 While loop");
triangles.add(p);
triangles.add(stack.pop());
}
stack.push(top);
stack.push(p);
}
}
//TODO: This is wrong :-)
//Add boundary
for (int i = 1; i < originalV.size(); i++) {
triangles.add(originalV.get(i));
triangles.add(originalV.get(i - 1));
}
//First and last from boundary
triangles.add(originalV.get(0));
triangles.add(originalV.get(originalV.size() - 1));
return new Pair<List<Point2D>, Integer>(triangles, GLES20.GL_LINES);
}
/**
* This method works, but it's fiendishly suboptimal...
*
* @param V
* @return
*/
public Pair<List<Point2D>, Integer> naiveTriangulation(List<Point2D> V) {
Collections.sort(V, new XYOrderComparator());
List<Point2D> triangles = new ArrayList<Point2D>();
Log.d(GAlg.DEBUG_TAG, "Sorted V:" + V.toString());
triangles.add(V.get(0));
triangles.add(V.get(1));
for (int i = 2; i < V.size(); i++) {
for (int j = 1; j <= i; j++) {
if (Utils.isItLegalDiagonal(V.get(i), V.get(i - j), triangles)) {
triangles.add(V.get(i));
triangles.add(V.get(i - j));
}
}
}
return new Pair<List<Point2D>, Integer>(triangles, GLES20.GL_LINES);
}
}