From 1dda5b088ca7525a5f2ddf67f36674653bc0cfe2 Mon Sep 17 00:00:00 2001
From: Adrian Mariano <avm4@cornell.edu>
Date: Fri, 24 Jul 2020 16:36:57 -0400
Subject: [PATCH] Fixed docs for path2d. Modified pointlist_bounds to give
 output that matches input dimension and to work on any input dimension.  Also
 made it ~20 times faster.

---
 coords.scad              |  1 -
 geometry.scad            | 17 ++++++++++-------
 tests/test_geometry.scad | 17 +++++++++++++++++
 3 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/coords.scad b/coords.scad
index 97729be..e45eab1 100644
--- a/coords.scad
+++ b/coords.scad
@@ -28,7 +28,6 @@ function point2d(p, fill=0) = [for (i=[0:1]) (p[i]==undef)? fill : p[i]];
 //   every vector has the same length.  
 // Arguments:
 //   points = A list of 2D or 3D points/vectors.
-//   fill = Value to fill missing values in vectors with.
 function path2d(points) =
     assert(is_path(points,dim=undef,fast=true),"Input to path2d is not a path")
     let (result = points * concat(ident(2), repeat([0,0], len(points[0])-2)))
diff --git a/geometry.scad b/geometry.scad
index 62dd436..dd35ddc 100644
--- a/geometry.scad
+++ b/geometry.scad
@@ -1380,15 +1380,18 @@ function find_noncollinear_points(points) =
 // Usage:
 //   pointlist_bounds(pts);
 // Description:
-//   Finds the bounds containing all the 2D or 3D points in `pts`.
-//   Returns `[[MINX, MINY, MINZ], [MAXX, MAXY, MAXZ]]`
+//   Finds the bounds containing all the points in `pts` which can be a list of points in any dimension.
+//   Returns a list of two items: a list of the minimums and a list of the maximums.  For example, with
+//   3d points `[[MINX, MINY, MINZ], [MAXX, MAXY, MAXZ]]`
 // Arguments:
 //   pts = List of points.
-function pointlist_bounds(pts) = [
-    [for (a=[0:2]) min([ for (x=pts) point3d(x)[a] ]) ],
-    [for (a=[0:2]) max([ for (x=pts) point3d(x)[a] ]) ]
-];
-
+function pointlist_bounds(pts) =
+    assert(is_matrix(pts))
+    let(ptsT = transpose(pts))
+    [
+      [for(row=ptsT) min(row)],
+      [for(row=ptsT) max(row)]
+    ];
 
 // Function: closest_point()
 // Usage:
diff --git a/tests/test_geometry.scad b/tests/test_geometry.scad
index 92b9f16..78c3e57 100644
--- a/tests/test_geometry.scad
+++ b/tests/test_geometry.scad
@@ -613,6 +613,23 @@ module test_pointlist_bounds() {
         [23,57,-42]
     ];
     assert(pointlist_bounds(pts) == [[-63,-32,-42], [84,97,42]]);
+    pts2d = [
+        [-53,12],
+        [-63,36],
+        [84,-5],
+        [63,42],
+        [23,-42] 
+    ];
+    assert(pointlist_bounds(pts2d) == [[-63,-42],[84,42]]);
+    pts5d = [
+        [-53,27,12,-53,12],
+        [-63,97,36,-63,36],
+        [84,-32,-5,84,-5], 
+        [63,-24,42,63,42], 
+        [23,57,-42,23,-42]
+    ];
+    assert(pointlist_bounds(pts5d) == [[-63,-32,-42,-63,-42],[84,97,42,84,42]]);
+    assert(pointlist_bounds([[3,4,5,6]]), [[3,4,5,6],[3,4,5,6]]);
 }
 test_pointlist_bounds();