Ver código fonte

fix convexHull()

bstouls 9 anos atrás
pai
commit
b33da9c798
1 arquivos alterados com 26 adições e 11 exclusões
  1. 26 11
      h2d/col/Polygon.hx

+ 26 - 11
h2d/col/Polygon.hx

@@ -56,24 +56,39 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 			return points;
 			return points;
 
 
 		//find lowest y points
 		//find lowest y points
-		var pts = points.copy();
-		var p0 = pts[0];
-		for( p in pts ) {
+		var p0 = points[0];
+		for( p in points ) {
 			if( p.y < p0.y || (p.y == p0.y && p.x < p0.x) )
 			if( p.y < p0.y || (p.y == p0.y && p.x < p0.x) )
 				p0 = p;
 				p0 = p;
 		}
 		}
 
 
-		//sort by polar angle from/to P
-		for(p in pts)
-			if(p.x == p0.x && p.y == p0.y)
-				pts.remove(p);
-		pts.sort(function(p1, p2) return side(p0, p1, p2) > 0 ? -1 : 1);
+		//sort by angle from p0
+		var pts : Array<{p : h2d.col.Point, a : Float}> = [];
+		var p1 = new h2d.col.Point(p0.x + 1e5, p0.y);
+		for(p in points) {
+			if(p.x == p0.x && p.y == p0.y) continue;
+			pts.push({p : p, a : side(p0, p1, p)});
+		}
+		pts.sort(function(pa, pb) return side(p0, pa.p, pb.p) > 0 ? -1 : 1);
+
+		//remove same angle points (includes duplicated points)
+		var index = pts.length - 1;
+		while(index > 0) {
+			var cur = pts[index];
+			var prev = pts[index - 1];
+			if(cur.a == prev.a) {
+				if(Math.distanceSq(cur.p.x - p0.x, cur.p.y - p0.y) < Math.distanceSq(prev.p.x - p0.x, prev.p.y - p0.y))
+					pts.remove(cur);
+				else pts.remove(prev);
+			}
+			index--;
+		}
 
 
 		//set hull
 		//set hull
-		var hull = [ p0, pts[0], pts[1] ];
+		var hull = [ p0, pts[0].p, pts[1].p ];
 		for (i in 2...pts.length) {
 		for (i in 2...pts.length) {
-			var pi = pts[i];
-			while (side(hull[hull.length - 2], hull[hull.length - 1], pi) < 0)
+			var pi = pts[i].p;
+			while (side(hull[hull.length - 2], hull[hull.length - 1], pi) <= 0)
 				hull.pop();
 				hull.pop();
 			hull.push(pi);
 			hull.push(pi);
 		}
 		}