瀏覽代碼

optimize rayIntersection()

bstouls 9 年之前
父節點
當前提交
ea126d6d37
共有 2 個文件被更改,包括 21 次插入18 次删除
  1. 15 8
      h2d/col/Polygon.hx
  2. 6 10
      h2d/col/Segment.hx

+ 15 - 8
h2d/col/Polygon.hx

@@ -147,19 +147,26 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 		}
 	}
 
-	public function rayIntersection( r : h2d.col.Ray ) {
-		var segs = toSegments();
+	public function rayIntersection( r : h2d.col.Ray, ?pt : Point ) {
 		var dmin = 1E9;
-		var pt = null;
-		for(s in segs) {
-			var p = s.rayIntersection(r);
-			if( p == null) continue;
-			var d = Math.distanceSq(p.x - r.x, p.y - r.y);
+		var p0 = points[points.length - 1];
+		for(p in points) {
+			if(r.side(p0) * r.side(p) > 0) continue;
+
+			var u = ( r.dx * (p0.y - r.y) - r.dy * (p0.x - r.x) ) / ( r.dy * (p.x - p0.x) - r.dx * (p.y - p0.y) );
+			var x = p0.x + u * (p.x - p0.x);
+			var y = p0.y + u * (p.y - p0.y);
+			var d = Math.distanceSq(x - r.x, y - r.y);
+
 			if(d < dmin) {
-				pt = p;
+				if( pt == null ) pt = new Point();
+				pt.x = x;
+				pt.y = y;
 				dmin = d;
 			}
+			p0 = p;
 		}
+
 		return pt;
 	}
 

+ 6 - 10
h2d/col/Segment.hx

@@ -63,20 +63,16 @@ class Segment {
 		}
 	}
 
-	public function rayIntersection( r : h2d.col.Ray ) {
+	public inline function rayIntersection( r : h2d.col.Ray, ?pt : Point ) {
 		if(r.side(new Point(x, y)) * r.side(new Point(x + dx, y + dy)) > 0)
 			return null;
 
-		var x1 = x, y1 = y;
-		var x2 = x + dx, y2 = y + dy;
-		var x3 = r.x, y3 = r.y;
-		var x4 = r.x + r.dx, y4 = r.y + r.dy;
+		var u = ( r.dx * (y - r.y) - r.dy * (x - r.x) ) / ( r.dy * dx - r.dx * dy );
+		if( pt == null ) pt = new Point();
+		pt.x = x + u * dx;
+		pt.y = y + u * dy;
 
-		var u = ( (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3) ) / ( (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1) );
-		var px = x1 + u * (x2 - x1);
-		var py = y1 + u * (y2 - y1);
-
-		return new Point(px, py);
+		return pt;
 	}
 
 }