ソースを参照

Reduce alloc in h2d.col.Polygon (by Martin)

TothBenoit 1 年間 前
コミット
2365808bc3
2 ファイル変更23 行追加13 行削除
  1. 12 7
      h2d/col/Polygon.hx
  2. 11 6
      h2d/col/Segment.hx

+ 12 - 7
h2d/col/Polygon.hx

@@ -262,21 +262,26 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 
 	/**
 		Return the closest point on the edges of the polygon
+		@param pt The point to test against.
+		@param out Optional Point instance to which closest point is written. If not provided, returns new Point instance.
+		@returns A `Point` instance of the closest point on the edges of the polygon.
 	**/
-	public function projectPoint(pt: h2d.col.Point) {
+	public function projectPoint(pt: h2d.col.Point, ?out : h2d.col.Point) {
 		var p1 = points[points.length - 1];
-		var closestProj = null;
+		var closest = new h2d.col.Point();
+		if (out == null) out = new Point();
 		var minDistSq = 1e10;
 		for(p2 in points) {
-			var proj = new Segment(p1, p2).project(pt);
-			var distSq = proj.distanceSq(pt);
-			if(distSq < minDistSq) {
-				closestProj = proj;
+			new Segment(p1, p2).project(pt, out);
+			var distSq = out.distanceSq(pt);
+			if (distSq < minDistSq) {
+				closest.load(out);
 				minDistSq = distSq;
 			}
 			p1 = p2;
 		}
-		return closestProj;
+		out.load(closest);
+		return out;
 	}
 
 	/**

+ 11 - 6
h2d/col/Segment.hx

@@ -100,19 +100,24 @@ class Segment {
 
 	/**
 		Projects Point `p` onto Segment. Returns position of intersection between Segment and line perpendicular to it going through Point `p`.
+		@param p Point to project onto this Segment.
+		@param out Optional Point instance to which projection point is written. If not provided, returns new Point instance.
+		@returns A `Point` with projection position.
 	**/
-	public inline function project( p : Point ) : Point {
+	public inline function project( p : Point, ?out : Point ) : Point {
 		var px = p.x - x;
 		var py = p.y - y;
 		var t = px * dx + py * dy;
-		return if( t < 0 )
-			new Point(x, y);
-		else if( t > lenSq )
-			new Point(x + dx, y + dy);
+		if (out == null) out = new Point();
+		if( t < 0 ) 
+			out.set(x, y);
+		else if( t > lenSq ) 
+			out.set(x + dx, y + dy);
 		else {
 			var tl2 = t * invLenSq;
-			new Point(x + tl2 * dx, y + tl2 * dy);
+			out.set(x + tl2 * dx, y + tl2 * dy);
 		}
+		return out;
 	}
 
 	/**