mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
Bugfixes for hull.scad
This commit is contained in:
parent
3b064c69bf
commit
3a71633f7f
8 changed files with 496 additions and 434 deletions
15
coords.scad
15
coords.scad
|
@ -216,13 +216,14 @@ function xy_to_polar(x,y=undef) = let(
|
|||
// can be useful in taking a set of nearly coplanar points, and converting
|
||||
// them to a pure XY set of coordinates for manipulation, before convering
|
||||
// them back to the original 3D plane.
|
||||
function xyz_to_planar(point, a, b, c) = let(
|
||||
u = normalize(b-a),
|
||||
v = normalize(c-a),
|
||||
n = normalize(cross(u,v)),
|
||||
w = normalize(cross(n,u)),
|
||||
relpoint = point-a
|
||||
) [relpoint * w, relpoint * u];
|
||||
function xyz_to_planar(point, a, b, c) =
|
||||
let(
|
||||
u = normalize(b-a),
|
||||
v = normalize(c-a),
|
||||
n = normalize(cross(u,v)),
|
||||
w = normalize(cross(n,u)),
|
||||
relpoint = point-a
|
||||
) [relpoint * w, relpoint * u];
|
||||
|
||||
|
||||
// Function: planar_to_xyz()
|
||||
|
|
|
@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
// Determine if the point is on the line segment between two points.
|
||||
// Returns true if yes, and false if not.
|
||||
// Arguments:
|
||||
// point = The point to check colinearity of.
|
||||
// point = The point to test.
|
||||
// edge = Array of two points forming the line segment to test against.
|
||||
function point_on_segment(point, edge) =
|
||||
point==edge[0] || point==edge[1] || // The point is an endpoint
|
||||
|
@ -99,9 +99,9 @@ function right_of_line2d(line, pt) =
|
|||
// a = First point.
|
||||
// b = Second point.
|
||||
// c = Third point.
|
||||
// eps = Acceptable max angle variance. Default: EPSILON (1e-9) degrees.
|
||||
// eps = Acceptable variance. Default: `EPSILON` (1e-9)
|
||||
function collinear(a, b, c, eps=EPSILON) =
|
||||
abs(vector_angle(b-a,c-a)) < eps;
|
||||
distance_from_line([a,b], c) < eps;
|
||||
|
||||
|
||||
// Function: collinear_indexed()
|
||||
|
@ -120,7 +120,23 @@ function collinear_indexed(points, a, b, c, eps=EPSILON) =
|
|||
p1=points[a],
|
||||
p2=points[b],
|
||||
p3=points[c]
|
||||
) abs(vector_angle(p2-p1,p3-p1)) < eps;
|
||||
) collinear(p1, p2, p3, eps);
|
||||
|
||||
|
||||
// Function: distance_from_line()
|
||||
// Usage:
|
||||
// distance_from_line(line, pt);
|
||||
// Description:
|
||||
// Finds the perpendicular distance of a point `pt` from the line `line`.
|
||||
// Arguments:
|
||||
// line = A list of two points, defining a line that both are on.
|
||||
// pt = A point to find the distance of from the line.
|
||||
// Example:
|
||||
// distance_from_line([[-10,0], [10,0]], [3,8]); // Returns: 8
|
||||
function distance_from_line(line, pt) =
|
||||
let(a=line[0], n=normalize(line[1]-a), d=a-pt)
|
||||
norm(d - ((d * n) * n));
|
||||
|
||||
|
||||
|
||||
// Function: triangle_area2d()
|
||||
|
@ -146,14 +162,19 @@ function triangle_area2d(a,b,c) =
|
|||
// Usage:
|
||||
// plane3pt(p1, p2, p3);
|
||||
// Description:
|
||||
// Generates the cartesian equation of a plane from three non-colinear points on the plane.
|
||||
// Generates the cartesian equation of a plane from three non-collinear points on the plane.
|
||||
// Returns [A,B,C,D] where Ax+By+Cz+D=0 is the equation of a plane.
|
||||
// Arguments:
|
||||
// p1 = The first point on the plane.
|
||||
// p2 = The second point on the plane.
|
||||
// p3 = The third point on the plane.
|
||||
function plane3pt(p1, p2, p3) =
|
||||
let(normal = normalize(cross(p3-p1, p2-p1))) concat(normal, [normal*p1]);
|
||||
let(
|
||||
p1=point3d(p1),
|
||||
p2=point3d(p2),
|
||||
p3=point3d(p3),
|
||||
normal = normalize(cross(p3-p1, p2-p1))
|
||||
) concat(normal, [normal*p1]);
|
||||
|
||||
|
||||
// Function: plane3pt_indexed()
|
||||
|
@ -173,9 +194,8 @@ function plane3pt_indexed(points, i1, i2, i3) =
|
|||
let(
|
||||
p1 = points[i1],
|
||||
p2 = points[i2],
|
||||
p3 = points[i3],
|
||||
normal = normalize(cross(p3-p1, p2-p1))
|
||||
) concat(normal, [normal*p1]);
|
||||
p3 = points[i3]
|
||||
) plane3pt(p1,p2,p3);
|
||||
|
||||
|
||||
// Function: distance_from_plane()
|
||||
|
|
116
hull.scad
116
hull.scad
|
@ -11,33 +11,64 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Section: 2D Convex Hulls
|
||||
// Section: Convex Hulls
|
||||
|
||||
|
||||
// Module: hull2d_points()
|
||||
// Function: hull()
|
||||
// Usage:
|
||||
// hull2d_points(points);
|
||||
// hull(points);
|
||||
// Description:
|
||||
// Takes a list of 2D points and creates a 2D convex polygon that encloses all those points.
|
||||
// Takes a list of 2D or 3D points (but not both in the same list) and
|
||||
// returns either the list of indexes into `points` that forms the 2D
|
||||
// convex hull perimeter path, or the list of faces that form the 3d
|
||||
// convex hull surface. Each face is a list of indexes into `points`.
|
||||
// Arguments:
|
||||
// points = The set of 2D or 3D points to find the hull of.
|
||||
function hull(points) = let(two_d = len(points[0]) == 2) two_d? hull2d_path(points) : hull3d_faces(points);
|
||||
|
||||
|
||||
// Module: hull_points()
|
||||
// Usage:
|
||||
// hull_points(points, [fast]);
|
||||
// Description:
|
||||
// If given a list of 2D points, creates a 2D convex hull polygon
|
||||
// that encloses all those points. If given a list of 3D points,
|
||||
// creates a 3D polyhedron that encloses all the points. This should
|
||||
// handle about 4000 points in slow mode. If `fast` is set to true,
|
||||
// this should be able to handle far more.
|
||||
// Arguments:
|
||||
// points = The list of points to form a hull around.
|
||||
// fast = If true, uses a faster cheat that may handle more points, but also may emit warnings that can stop your script if you have "Halt on first warning" enabled. Default: false
|
||||
// Example(2D):
|
||||
// pts = [[-10,-10], [0,10], [10,10], [12,-10]];
|
||||
// hull2d_points(pts);
|
||||
module hull2d_points(points) {
|
||||
polygon(points=points, paths=[hull2d_path(points)]);
|
||||
}
|
||||
|
||||
|
||||
// Module: hull2d_points_fast()
|
||||
// Usage:
|
||||
// hull2d_points_fast(points);
|
||||
// Description:
|
||||
// Takes a list of 2D points and creates a 2D convex polygon that encloses all
|
||||
// those points, using a faster method that may emit warning messages.
|
||||
// Example(2D):
|
||||
// pts = [[-10,-10], [0,10], [10,10], [12,-10]];
|
||||
// hull2d_points_fast(pts);
|
||||
module hull2d_points_fast(points) {
|
||||
hull() polygon(points);
|
||||
// hull_points(pts);
|
||||
// Example:
|
||||
// ptr = [for (phi = [30:60:150], theta = [0:60:359]) spherical_to_xyz(10, theta, phi)];
|
||||
// hull_points(pts);
|
||||
module hull_points(points, fast=false) {
|
||||
assert(is_list(points));
|
||||
if (points) {
|
||||
assert(is_list(points[0]));
|
||||
if (fast) {
|
||||
if (len(points[0]) == 2) {
|
||||
hull() polygon(points=points);
|
||||
} else {
|
||||
extra = len(points)%3;
|
||||
faces = concat(
|
||||
[[for(i=[0:extra+2])i]],
|
||||
[for(i=[extra+3:3:len(points)-3])[i,i+1,i+2]]
|
||||
);
|
||||
hull() polyhedron(points=points, faces=faces);
|
||||
}
|
||||
} else {
|
||||
perim = hull(points);
|
||||
if (len(perim[0]) == 2) {
|
||||
polygon(points=points, paths=[perim]);
|
||||
} else {
|
||||
polyhedron(points=points, faces=perim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -118,42 +149,6 @@ function _remove_conflicts_and_insert_point(polygon, conflicts, point) =
|
|||
|
||||
|
||||
|
||||
// Section: 3D Convex Hulls
|
||||
|
||||
|
||||
// Module: hull3d_points()
|
||||
// Usage:
|
||||
// hull3d_points(points);
|
||||
// Description:
|
||||
// Takes a list of 3D points and creates a 3D convex polyhedron that encloses all those points.
|
||||
// Example(3D):
|
||||
// pts = [[-20,-20,0], [20,-20,0], [0,20,5], [0,0,20]];
|
||||
// hull3d_points(pts);
|
||||
module hull3d_points(points) {
|
||||
indices = hull3d_faces(points);
|
||||
if (is_vector(indices)) {
|
||||
polyhedron(points=points, faces=[indices]);
|
||||
} else {
|
||||
polyhedron(points=points, faces=indices);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Module: hull3d_points_fast()
|
||||
// Usage:
|
||||
// hull3d_points_fast(points);
|
||||
// Description:
|
||||
// Takes a list of 3D points and creates a 3D convex polyhedron that encloses all
|
||||
// those points, using a faster method that may emit warning messages.
|
||||
// Example(3D):
|
||||
// pts = [[-20,-20,0], [20,-20,0], [0,20,5], [0,0,20]];
|
||||
// hull3d_points_fast(pts);
|
||||
module hull3d_points_fast(points) {
|
||||
faces = [for (i=[0:len(points)-3]) let(c=_find_first_noncollinear([i,i+1], points, 2)) [i, i+1, c]];
|
||||
hull() polyhedron(points=points, faces=faces);
|
||||
}
|
||||
|
||||
|
||||
// Function: hull3d_faces()
|
||||
// Usage:
|
||||
// hull3d_faces(points)
|
||||
|
@ -170,8 +165,11 @@ module hull3d_points_fast(points) {
|
|||
// %polyhedron(points=pts, faces=faces);
|
||||
function hull3d_faces(points) =
|
||||
(len(points) < 3)? list_range(len(points)) : let (
|
||||
// start with a single triangle
|
||||
a=0, b=1, c=2,
|
||||
// start with a single non-collinear triangle
|
||||
a = 0,
|
||||
b = 1,
|
||||
c = _find_first_noncollinear([a,b], points, 2)
|
||||
) (c == len(points))? _hull2d_collinear(points) : let(
|
||||
plane = plane3pt_indexed(points, a, b, c),
|
||||
d = _find_first_noncoplanar(plane, points, 3)
|
||||
) (d == len(points))? /* all coplanar*/ let (
|
||||
|
|
201
tests/test_arrays.scad
Normal file
201
tests/test_arrays.scad
Normal file
|
@ -0,0 +1,201 @@
|
|||
include <BOSL2/std.scad>
|
||||
|
||||
|
||||
// List/Array Ops
|
||||
|
||||
module test_replist() {
|
||||
assert(replist(1, 4) == [1,1,1,1]);
|
||||
assert(replist(8, [2,3]) == [[8,8,8], [8,8,8]]);
|
||||
assert(replist(0, [2,2,3]) == [[[0,0,0],[0,0,0]], [[0,0,0],[0,0,0]]]);
|
||||
assert(replist([1,2,3],3) == [[1,2,3], [1,2,3], [1,2,3]]);
|
||||
}
|
||||
test_replist();
|
||||
|
||||
|
||||
module test_in_list() {
|
||||
assert(in_list("bar", ["foo", "bar", "baz"]));
|
||||
assert(!in_list("bee", ["foo", "bar", "baz"]));
|
||||
assert(in_list("bar", [[2,"foo"], [4,"bar"], [3,"baz"]], idx=1));
|
||||
}
|
||||
test_in_list();
|
||||
|
||||
|
||||
module test_slice() {
|
||||
assert(slice([3,4,5,6,7,8,9], 3, 5) == [6,7]);
|
||||
assert(slice([3,4,5,6,7,8,9], 2, -1) == [5,6,7,8,9]);
|
||||
assert(slice([3,4,5,6,7,8,9], 1, 1) == []);
|
||||
assert(slice([3,4,5,6,7,8,9], 6, -1) == [9]);
|
||||
assert(slice([3,4,5,6,7,8,9], 2, -2) == [5,6,7,8]);
|
||||
}
|
||||
test_slice();
|
||||
|
||||
|
||||
module test_select() {
|
||||
l = [3,4,5,6,7,8,9];
|
||||
assert(select(l, 5, 6) == [8,9]);
|
||||
assert(select(l, 5, 8) == [8,9,3,4]);
|
||||
assert(select(l, 5, 2) == [8,9,3,4,5]);
|
||||
assert(select(l, -3, -1) == [7,8,9]);
|
||||
assert(select(l, 3, 3) == [6]);
|
||||
assert(select(l, 4) == 7);
|
||||
assert(select(l, -2) == 8);
|
||||
assert(select(l, [1:3]) == [4,5,6]);
|
||||
assert(select(l, [1,3]) == [4,6]);
|
||||
}
|
||||
test_select();
|
||||
|
||||
|
||||
module test_list_range() {
|
||||
assert(list_range(4) == [0,1,2,3]);
|
||||
assert(list_range(n=4, step=2) == [0,2,4,6]);
|
||||
assert(list_range(n=4, s=3, step=3) == [3,6,9,12]);
|
||||
assert(list_range(n=4, s=3, e=9, step=3) == [3,6,9]);
|
||||
assert(list_range(e=3) == [0,1,2,3]);
|
||||
assert(list_range(e=6, step=2) == [0,2,4,6]);
|
||||
assert(list_range(s=3, e=5) == [3,4,5]);
|
||||
assert(list_range(s=3, e=8, step=2) == [3,5,7]);
|
||||
assert(list_range(s=4, e=8, step=2) == [4,6,8]);
|
||||
assert(list_range(n=4, s=[3,4], step=[2,3]) == [[3,4], [5,7], [7,10], [9,13]]);
|
||||
}
|
||||
test_list_range();
|
||||
|
||||
|
||||
module test_reverse() {
|
||||
assert(reverse([3,4,5,6]) == [6,5,4,3]);
|
||||
}
|
||||
test_reverse();
|
||||
|
||||
|
||||
// TODO: list_remove()
|
||||
// TODO: list_insert()
|
||||
|
||||
|
||||
module test_list_shortest() {
|
||||
assert(list_shortest(["foobar", "bazquxx", "abcd"]) == 4);
|
||||
}
|
||||
test_list_shortest();
|
||||
|
||||
|
||||
module test_list_longest() {
|
||||
assert(list_longest(["foobar", "bazquxx", "abcd"]) == 7);
|
||||
}
|
||||
test_list_longest();
|
||||
|
||||
|
||||
module test_list_pad() {
|
||||
assert(list_pad([4,5,6], 5, 8) == [4,5,6,8,8]);
|
||||
assert(list_pad([4,5,6,7,8], 5, 8) == [4,5,6,7,8]);
|
||||
assert(list_pad([4,5,6,7,8,9], 5, 8) == [4,5,6,7,8,9]);
|
||||
}
|
||||
test_list_pad();
|
||||
|
||||
|
||||
module test_list_trim() {
|
||||
assert(list_trim([4,5,6], 5) == [4,5,6]);
|
||||
assert(list_trim([4,5,6,7,8], 5) == [4,5,6,7,8]);
|
||||
assert(list_trim([3,4,5,6,7,8,9], 5) == [3,4,5,6,7]);
|
||||
}
|
||||
test_list_trim();
|
||||
|
||||
|
||||
module test_list_fit() {
|
||||
assert(list_fit([4,5,6], 5, 8) == [4,5,6,8,8]);
|
||||
assert(list_fit([4,5,6,7,8], 5, 8) == [4,5,6,7,8]);
|
||||
assert(list_fit([3,4,5,6,7,8,9], 5, 8) == [3,4,5,6,7]);
|
||||
}
|
||||
test_list_fit();
|
||||
|
||||
|
||||
module test_enumerate() {
|
||||
assert(enumerate(["a","b","c"]) == [[0,"a"], [1,"b"], [2,"c"]]);
|
||||
assert(enumerate([[88,"a"],[76,"b"],[21,"c"]], idx=1) == [[0,"a"], [1,"b"], [2,"c"]]);
|
||||
assert(enumerate([["cat","a",12],["dog","b",10],["log","c",14]], idx=[1:2]) == [[0,"a",12], [1,"b",10], [2,"c",14]]);
|
||||
}
|
||||
test_enumerate();
|
||||
|
||||
|
||||
module test_sort() {
|
||||
assert(sort([7,3,9,4,3,1,8]) == [1,3,3,4,7,8,9]);
|
||||
assert(sort(["cat", "oat", "sat", "bat", "vat", "rat", "pat", "mat", "fat", "hat", "eat"]) == ["bat", "cat", "eat", "fat", "hat", "mat", "oat", "pat", "rat", "sat", "vat"]);
|
||||
assert(sort(enumerate([[2,3,4],[1,2,3],[2,4,3]]),idx=1)==[[1,[1,2,3]], [0,[2,3,4]], [2,[2,4,3]]]);
|
||||
}
|
||||
test_sort();
|
||||
|
||||
|
||||
module test_sortidx() {
|
||||
lst1 = ["d","b","e","c"];
|
||||
assert(sortidx(lst1) == [1,3,0,2]);
|
||||
lst2 = [
|
||||
["foo", 88, [0,0,1], false],
|
||||
["bar", 90, [0,1,0], true],
|
||||
["baz", 89, [1,0,0], false],
|
||||
["qux", 23, [1,1,1], true]
|
||||
];
|
||||
assert(sortidx(lst2, idx=1) == [3,0,2,1]);
|
||||
assert(sortidx(lst2, idx=0) == [1,2,0,3]);
|
||||
assert(sortidx(lst2, idx=[1,3]) == [3,0,2,1]);
|
||||
lst3 = [[-4, 0, 0], [0, 0, -4], [0, -4, 0], [-4, 0, 0], [0, -4, 0], [0, 0, 4], [0, 0, -4], [0, 4, 0], [4, 0, 0], [0, 0, 4], [0, 4, 0], [4, 0, 0]];
|
||||
assert(sortidx(lst3)==[0,3,2,4,1,6,5,9,7,10,8,11]);
|
||||
}
|
||||
test_sortidx();
|
||||
|
||||
|
||||
module test_unique() {
|
||||
assert(unique([]) == []);
|
||||
assert(unique([8]) == [8]);
|
||||
assert(unique([7,3,9,4,3,1,8]) == [1,3,4,7,8,9]);
|
||||
}
|
||||
test_unique();
|
||||
|
||||
|
||||
// Arrays
|
||||
|
||||
|
||||
module test_array_subindex() {
|
||||
v = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]];
|
||||
assert(array_subindex(v,2) == [3, 7, 11, 15]);
|
||||
assert(array_subindex(v,[2,1]) == [[3, 2], [7, 6], [11, 10], [15, 14]]);
|
||||
assert(array_subindex(v,[1:3]) == [[2, 3, 4], [6, 7, 8], [10, 11, 12], [14, 15, 16]]);
|
||||
}
|
||||
test_array_subindex();
|
||||
|
||||
|
||||
module test_array_zip() {
|
||||
v1 = [1,2,3,4];
|
||||
v2 = [5,6,7];
|
||||
v3 = [8,9,10,11];
|
||||
assert(array_zip(v1,v3) == [[1,8],[2,9],[3,10],[4,11]]);
|
||||
assert(array_zip([v1,v3]) == [[1,8],[2,9],[3,10],[4,11]]);
|
||||
assert(array_zip([v1,v2],fit="short") == [[1,5],[2,6],[3,7]]);
|
||||
assert(array_zip([v1,v2],fit="long") == [[1,5],[2,6],[3,7],[4,undef]]);
|
||||
assert(array_zip([v1,v2],fit="long", fill=0) == [[1,5],[2,6],[3,7],[4,0]]);
|
||||
assert(array_zip([v1,v2,v3],fit="long") == [[1,5,8],[2,6,9],[3,7,10],[4,undef,11]]);
|
||||
}
|
||||
test_array_zip();
|
||||
|
||||
|
||||
module test_array_group() {
|
||||
v = [1,2,3,4,5,6];
|
||||
assert(array_group(v,2) == [[1,2], [3,4], [5,6]]);
|
||||
assert(array_group(v,3) == [[1,2,3], [4,5,6]]);
|
||||
assert(array_group(v,4,0) == [[1,2,3,4], [5,6,0,0]]);
|
||||
}
|
||||
test_array_group();
|
||||
|
||||
|
||||
module test_flatten() {
|
||||
assert(flatten([[1,2,3], [4,5,[6,7,8]]]) == [1,2,3,4,5,[6,7,8]]);
|
||||
}
|
||||
test_flatten();
|
||||
|
||||
|
||||
module test_array_dim() {
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) == [2,2,3]);
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 0) == 2);
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 2) == 3);
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9]]]) == [2,undef,3]);
|
||||
}
|
||||
test_array_dim();
|
||||
|
||||
|
||||
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
96
tests/test_coords.scad
Normal file
96
tests/test_coords.scad
Normal file
|
@ -0,0 +1,96 @@
|
|||
include <BOSL2/std.scad>
|
||||
|
||||
|
||||
module test_point2d() {
|
||||
assert(point2d([1,2,3])==[1,2]);
|
||||
assert(point2d([2,3])==[2,3]);
|
||||
assert(point2d([1])==[1,0]);
|
||||
}
|
||||
test_point2d();
|
||||
|
||||
|
||||
module test_path2d() {
|
||||
assert(path2d([[1], [1,2], [1,2,3], [1,2,3,4], [1,2,3,4,5]])==[[1,0],[1,2],[1,2],[1,2],[1,2]]);
|
||||
}
|
||||
test_path2d();
|
||||
|
||||
|
||||
module test_point3d() {
|
||||
assert(point3d([1,2,3,4,5])==[1,2,3]);
|
||||
assert(point3d([1,2,3,4])==[1,2,3]);
|
||||
assert(point3d([1,2,3])==[1,2,3]);
|
||||
assert(point3d([2,3])==[2,3,0]);
|
||||
assert(point3d([1])==[1,0,0]);
|
||||
}
|
||||
test_point3d();
|
||||
|
||||
|
||||
module test_path3d() {
|
||||
assert(path3d([[1], [1,2], [1,2,3], [1,2,3,4], [1,2,3,4,5]])==[[1,0,0],[1,2,0],[1,2,3],[1,2,3],[1,2,3]]);
|
||||
}
|
||||
test_path3d();
|
||||
|
||||
|
||||
module test_translate_points() {
|
||||
pts = [[0,0,1], [0,1,0], [1,0,0], [0,0,-1], [0,-1,0], [-1,0,0]];
|
||||
assert(translate_points(pts, v=[1,2,3]) == [[1,2,4], [1,3,3], [2,2,3], [1,2,2], [1,1,3], [0,2,3]]);
|
||||
assert(translate_points(pts, v=[-1,-2,-3]) == [[-1,-2,-2], [-1,-1,-3], [0,-2,-3], [-1,-2,-4], [-1,-3,-3], [-2,-2,-3]]);
|
||||
}
|
||||
test_translate_points();
|
||||
|
||||
|
||||
module test_scale_points() {
|
||||
pts = [[0,0,1], [0,1,0], [1,0,0], [0,0,-1], [0,-1,0], [-1,0,0]];
|
||||
assert(scale_points(pts, v=[2,3,4]) == [[0,0,4], [0,3,0], [2,0,0], [0,0,-4], [0,-3,0], [-2,0,0]]);
|
||||
assert(scale_points(pts, v=[-2,-3,-4]) == [[0,0,-4], [0,-3,0], [-2,0,0], [0,0,4], [0,3,0], [2,0,0]]);
|
||||
assert(scale_points(pts, v=[1,1,1]) == [[0,0,1], [0,1,0], [1,0,0], [0,0,-1], [0,-1,0], [-1,0,0]]);
|
||||
assert(scale_points(pts, v=[-1,-1,-1]) == [[0,0,-1], [0,-1,0], [-1,0,0], [0,0,1], [0,1,0], [1,0,0]]);
|
||||
}
|
||||
test_scale_points();
|
||||
|
||||
|
||||
module test_rotate_points2d() {
|
||||
pts = [[0,1], [1,0], [0,-1], [-1,0]];
|
||||
s = sin(45);
|
||||
assert(rotate_points2d(pts,45) == [[-s,s],[s,s],[s,-s],[-s,-s]]);
|
||||
assert(rotate_points2d(pts,90) == [[-1,0],[0,1],[1,0],[0,-1]]);
|
||||
assert(rotate_points2d(pts,90,cp=[1,0]) == [[0,-1],[1,0],[2,-1],[1,-2]]);
|
||||
}
|
||||
test_rotate_points2d();
|
||||
|
||||
|
||||
module test_rotate_points3d() {
|
||||
pts = [[0,0,1], [0,1,0], [1,0,0], [0,0,-1], [0,-1,0], [-1,0,0]];
|
||||
assert(rotate_points3d(pts, [90,0,0]) == [[0,-1,0], [0,0,1], [1,0,0], [0,1,0], [0,0,-1], [-1,0,0]]);
|
||||
assert(rotate_points3d(pts, [0,90,0]) == [[1,0,0], [0,1,0], [0,0,-1], [-1,0,0], [0,-1,0], [0,0,1]]);
|
||||
assert(rotate_points3d(pts, [0,0,90]) == [[0,0,1], [-1,0,0], [0,1,0], [0,0,-1], [1,0,0], [0,-1,0]]);
|
||||
assert(rotate_points3d(pts, [0,0,90],cp=[2,0,0]) == [[2,-2,1], [1,-2,0], [2,-1,0], [2,-2,-1], [3,-2,0], [2,-3,0]]);
|
||||
assert(rotate_points3d(pts, 90, v=UP) == [[0,0,1], [-1,0,0], [0,1,0], [0,0,-1], [1,0,0], [0,-1,0]]);
|
||||
assert(rotate_points3d(pts, 90, v=DOWN) == [[0,0,1], [1,0,0], [0,-1,0], [0,0,-1], [-1,0,0], [0,1,0]]);
|
||||
assert(rotate_points3d(pts, 90, v=RIGHT) == [[0,-1,0], [0,0,1], [1,0,0], [0,1,0], [0,0,-1], [-1,0,0]]);
|
||||
assert(rotate_points3d(pts, from=UP, to=BACK) == [[0,1,0], [0,0,-1], [1,0,0], [0,-1,0], [0,0,1], [-1,0,0]]);
|
||||
assert(rotate_points3d(pts, 90, from=UP, to=BACK), [[0,1,0], [-1,0,0], [0,0,-1], [0,-1,0], [1,0,0], [0,0,1]]);
|
||||
assert(rotate_points3d(pts, from=UP, to=UP*2) == [[0,0,1], [0,1,0], [1,0,0], [0,0,-1], [0,-1,0], [-1,0,0]]);
|
||||
assert(rotate_points3d(pts, from=UP, to=DOWN*2) == [[0,0,-1], [0,1,0], [-1,0,0], [0,0,1], [0,-1,0], [1,0,0]]);
|
||||
}
|
||||
test_rotate_points3d();
|
||||
|
||||
|
||||
module test_simplify_path()
|
||||
{
|
||||
path = [[-20,10],[-10,0],[-5,0],[0,0],[5,0],[10,0], [10,10]];
|
||||
assert(simplify_path(path) == [[-20,10],[-10,0],[10,0], [10,10]]);
|
||||
}
|
||||
test_simplify_path();
|
||||
|
||||
|
||||
module test_simplify_path_indexed()
|
||||
{
|
||||
points = [[-20,10],[-10,0],[-5,0],[0,0],[5,0],[10,0], [10,10]];
|
||||
path = list_range(len(points));
|
||||
assert(simplify_path_indexed(points, path) == [0,1,5,6]);
|
||||
}
|
||||
test_simplify_path_indexed();
|
||||
|
||||
|
||||
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
|
@ -1,5 +1,5 @@
|
|||
include <BOSL2/math.scad>
|
||||
include <BOSL2/convex_hull.scad>
|
||||
include <BOSL2/std.scad>
|
||||
include <BOSL2/hull.scad>
|
||||
|
||||
|
||||
testpoints_on_sphere = [ for(p =
|
||||
|
@ -44,7 +44,7 @@ visualize_hull(testpoints3d);
|
|||
|
||||
|
||||
module visualize_hull(points) {
|
||||
hull = convex_hull(points);
|
||||
hull = hull(points);
|
||||
|
||||
%if (len(hull) > 0 && is_list(hull[0]) && len(hull[0]) > 0)
|
||||
polyhedron(points=points, faces = hull);
|
|
@ -1,6 +1,4 @@
|
|||
include <BOSL2/constants.scad>
|
||||
include <BOSL2/math.scad>
|
||||
|
||||
include <BOSL2/std.scad>
|
||||
|
||||
// Simple Calculations
|
||||
|
||||
|
@ -63,6 +61,37 @@ module test_constrain() {
|
|||
test_constrain();
|
||||
|
||||
|
||||
module test_min_index() {
|
||||
vals = rands(-100,100,100);
|
||||
minval = min(vals);
|
||||
minidx = min_index(vals);
|
||||
assert(vals[minidx] == minval);
|
||||
assert(min_index([3,4,5,6]) == 0);
|
||||
assert(min_index([4,3,5,6]) == 1);
|
||||
assert(min_index([4,5,3,6]) == 2);
|
||||
assert(min_index([4,5,6,3]) == 3);
|
||||
assert(min_index([6,5,4,3]) == 3);
|
||||
assert(min_index([6,3,4,5]) == 1);
|
||||
assert(min_index([-56,72,-874,5]) == 2);
|
||||
}
|
||||
test_min_index();
|
||||
|
||||
|
||||
module test_max_index() {
|
||||
vals = rands(-100,100,100);
|
||||
maxval = max(vals);
|
||||
maxidx = max_index(vals);
|
||||
assert(vals[maxidx] == maxval);
|
||||
assert(max_index([3,4,5,6]) == 3);
|
||||
assert(max_index([3,4,6,5]) == 2);
|
||||
assert(max_index([3,6,4,5]) == 1);
|
||||
assert(max_index([6,3,4,5]) == 0);
|
||||
assert(max_index([5,6,4,3]) == 1);
|
||||
assert(max_index([-56,72,-874,5]) == 1);
|
||||
}
|
||||
test_max_index();
|
||||
|
||||
|
||||
module test_posmod() {
|
||||
assert(posmod(-5,3) == 1);
|
||||
assert(posmod(-4,3) == 2);
|
||||
|
@ -86,6 +115,9 @@ module test_modrange() {
|
|||
test_modrange();
|
||||
|
||||
|
||||
// TODO: Tests for gaussian_rand()
|
||||
// TODO: Tests for log_rand()
|
||||
|
||||
module test_segs() {
|
||||
assert(segs(50,$fn=8) == 8);
|
||||
assert(segs(50,$fa=2,$fs=2) == 158);
|
||||
|
@ -292,358 +324,5 @@ test_count_true();
|
|||
|
||||
|
||||
|
||||
// List/Array Ops
|
||||
|
||||
module test_cdr() {
|
||||
assert(cdr([]) == []);
|
||||
assert(cdr([88]) == []);
|
||||
assert(cdr([1,2,3]) == [2,3]);
|
||||
assert(cdr(["a","b","c"]) == ["b","c"]);
|
||||
}
|
||||
test_cdr();
|
||||
|
||||
|
||||
module test_replist() {
|
||||
assert(replist(1, 4) == [1,1,1,1]);
|
||||
assert(replist(8, [2,3]) == [[8,8,8], [8,8,8]]);
|
||||
assert(replist(0, [2,2,3]) == [[[0,0,0],[0,0,0]], [[0,0,0],[0,0,0]]]);
|
||||
assert(replist([1,2,3],3) == [[1,2,3], [1,2,3], [1,2,3]]);
|
||||
}
|
||||
test_replist();
|
||||
|
||||
|
||||
module test_in_list() {
|
||||
assert(in_list("bar", ["foo", "bar", "baz"]));
|
||||
assert(!in_list("bee", ["foo", "bar", "baz"]));
|
||||
assert(in_list("bar", [[2,"foo"], [4,"bar"], [3,"baz"]], idx=1));
|
||||
}
|
||||
test_in_list();
|
||||
|
||||
|
||||
module test_slice() {
|
||||
assert(slice([3,4,5,6,7,8,9], 3, 5) == [6,7]);
|
||||
assert(slice([3,4,5,6,7,8,9], 2, -1) == [5,6,7,8,9]);
|
||||
assert(slice([3,4,5,6,7,8,9], 1, 1) == []);
|
||||
assert(slice([3,4,5,6,7,8,9], 6, -1) == [9]);
|
||||
assert(slice([3,4,5,6,7,8,9], 2, -2) == [5,6,7,8]);
|
||||
}
|
||||
test_slice();
|
||||
|
||||
|
||||
module test_select() {
|
||||
l = [3,4,5,6,7,8,9];
|
||||
assert(select(l, 5, 6) == [8,9]);
|
||||
assert(select(l, 5, 8) == [8,9,3,4]);
|
||||
assert(select(l, 5, 2) == [8,9,3,4,5]);
|
||||
assert(select(l, -3, -1) == [7,8,9]);
|
||||
assert(select(l, 3, 3) == [6]);
|
||||
assert(select(l, 4) == 7);
|
||||
assert(select(l, -2) == 8);
|
||||
assert(select(l, [1:3]) == [4,5,6]);
|
||||
assert(select(l, [1,3]) == [4,6]);
|
||||
}
|
||||
test_select();
|
||||
|
||||
|
||||
module test_reverse() {
|
||||
assert(reverse([3,4,5,6]) == [6,5,4,3]);
|
||||
}
|
||||
test_reverse();
|
||||
|
||||
|
||||
module test_array_subindex() {
|
||||
v = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]];
|
||||
assert(array_subindex(v,2) == [3, 7, 11, 15]);
|
||||
assert(array_subindex(v,[2,1]) == [[3, 2], [7, 6], [11, 10], [15, 14]]);
|
||||
assert(array_subindex(v,[1:3]) == [[2, 3, 4], [6, 7, 8], [10, 11, 12], [14, 15, 16]]);
|
||||
}
|
||||
test_array_subindex();
|
||||
|
||||
|
||||
module test_list_range() {
|
||||
assert(list_range(4) == [0,1,2,3]);
|
||||
assert(list_range(n=4, step=2) == [0,2,4,6]);
|
||||
assert(list_range(n=4, s=3, step=3) == [3,6,9,12]);
|
||||
assert(list_range(n=4, s=3, e=9, step=3) == [3,6,9]);
|
||||
assert(list_range(e=3) == [0,1,2,3]);
|
||||
assert(list_range(e=6, step=2) == [0,2,4,6]);
|
||||
assert(list_range(s=3, e=5) == [3,4,5]);
|
||||
assert(list_range(s=3, e=8, step=2) == [3,5,7]);
|
||||
assert(list_range(s=4, e=8, step=2) == [4,6,8]);
|
||||
assert(list_range(n=4, s=[3,4], step=[2,3]) == [[3,4], [5,7], [7,10], [9,13]]);
|
||||
}
|
||||
test_list_range();
|
||||
|
||||
|
||||
module test_array_shortest() {
|
||||
assert(array_shortest(["foobar", "bazquxx", "abcd"]) == 4);
|
||||
}
|
||||
test_array_shortest();
|
||||
|
||||
|
||||
module test_array_longest() {
|
||||
assert(array_longest(["foobar", "bazquxx", "abcd"]) == 7);
|
||||
}
|
||||
test_array_longest();
|
||||
|
||||
|
||||
module test_array_pad() {
|
||||
assert(array_pad([4,5,6], 5, 8) == [4,5,6,8,8]);
|
||||
assert(array_pad([4,5,6,7,8], 5, 8) == [4,5,6,7,8]);
|
||||
assert(array_pad([4,5,6,7,8,9], 5, 8) == [4,5,6,7,8,9]);
|
||||
}
|
||||
test_array_pad();
|
||||
|
||||
|
||||
module test_array_trim() {
|
||||
assert(array_trim([4,5,6], 5) == [4,5,6]);
|
||||
assert(array_trim([4,5,6,7,8], 5) == [4,5,6,7,8]);
|
||||
assert(array_trim([3,4,5,6,7,8,9], 5) == [3,4,5,6,7]);
|
||||
}
|
||||
test_array_trim();
|
||||
|
||||
|
||||
module test_array_fit() {
|
||||
assert(array_fit([4,5,6], 5, 8) == [4,5,6,8,8]);
|
||||
assert(array_fit([4,5,6,7,8], 5, 8) == [4,5,6,7,8]);
|
||||
assert(array_fit([3,4,5,6,7,8,9], 5, 8) == [3,4,5,6,7]);
|
||||
}
|
||||
test_array_fit();
|
||||
|
||||
|
||||
module test_enumerate() {
|
||||
assert(enumerate(["a","b","c"]) == [[0,"a"], [1,"b"], [2,"c"]]);
|
||||
assert(enumerate([[88,"a"],[76,"b"],[21,"c"]], idx=1) == [[0,"a"], [1,"b"], [2,"c"]]);
|
||||
assert(enumerate([["cat","a",12],["dog","b",10],["log","c",14]], idx=[1:2]) == [[0,"a",12], [1,"b",10], [2,"c",14]]);
|
||||
}
|
||||
test_enumerate();
|
||||
|
||||
|
||||
module test_array_zip() {
|
||||
v1 = [1,2,3,4];
|
||||
v2 = [5,6,7];
|
||||
v3 = [8,9,10,11];
|
||||
assert(array_zip(v1,v3) == [[1,8],[2,9],[3,10],[4,11]]);
|
||||
assert(array_zip([v1,v3]) == [[1,8],[2,9],[3,10],[4,11]]);
|
||||
assert(array_zip([v1,v2],fit="short") == [[1,5],[2,6],[3,7]]);
|
||||
assert(array_zip([v1,v2],fit="long") == [[1,5],[2,6],[3,7],[4,undef]]);
|
||||
assert(array_zip([v1,v2],fit="long", fill=0) == [[1,5],[2,6],[3,7],[4,0]]);
|
||||
assert(array_zip([v1,v2,v3],fit="long") == [[1,5,8],[2,6,9],[3,7,10],[4,undef,11]]);
|
||||
}
|
||||
test_array_zip();
|
||||
|
||||
|
||||
module test_array_group() {
|
||||
v = [1,2,3,4,5,6];
|
||||
assert(array_group(v,2) == [[1,2], [3,4], [5,6]]);
|
||||
assert(array_group(v,3) == [[1,2,3], [4,5,6]]);
|
||||
assert(array_group(v,4,0) == [[1,2,3,4], [5,6,0,0]]);
|
||||
}
|
||||
test_array_group();
|
||||
|
||||
|
||||
module test_flatten() {
|
||||
assert(flatten([[1,2,3], [4,5,[6,7,8]]]) == [1,2,3,4,5,[6,7,8]]);
|
||||
}
|
||||
test_flatten();
|
||||
|
||||
|
||||
module test_sort() {
|
||||
assert(sort([7,3,9,4,3,1,8]) == [1,3,3,4,7,8,9]);
|
||||
assert(sort(["cat", "oat", "sat", "bat", "vat", "rat", "pat", "mat", "fat", "hat", "eat"]) == ["bat", "cat", "eat", "fat", "hat", "mat", "oat", "pat", "rat", "sat", "vat"]);
|
||||
assert(sort(enumerate([[2,3,4],[1,2,3],[2,4,3]]),idx=1)==[[1,[1,2,3]], [0,[2,3,4]], [2,[2,4,3]]]);
|
||||
}
|
||||
test_sort();
|
||||
|
||||
|
||||
module test_sortidx() {
|
||||
lst1 = ["d","b","e","c"];
|
||||
assert(sortidx(lst1) == [1,3,0,2]);
|
||||
lst2 = [
|
||||
["foo", 88, [0,0,1], false],
|
||||
["bar", 90, [0,1,0], true],
|
||||
["baz", 89, [1,0,0], false],
|
||||
["qux", 23, [1,1,1], true]
|
||||
];
|
||||
assert(sortidx(lst2, idx=1) == [3,0,2,1]);
|
||||
assert(sortidx(lst2, idx=0) == [1,2,0,3]);
|
||||
assert(sortidx(lst2, idx=[1,3]) == [3,0,2,1]);
|
||||
lst3 = [[-4, 0, 0], [0, 0, -4], [0, -4, 0], [-4, 0, 0], [0, -4, 0], [0, 0, 4], [0, 0, -4], [0, 4, 0], [4, 0, 0], [0, 0, 4], [0, 4, 0], [4, 0, 0]];
|
||||
assert(sortidx(lst3)==[0,3,2,4,1,6,5,9,7,10,8,11]);
|
||||
}
|
||||
test_sortidx();
|
||||
|
||||
|
||||
module test_unique() {
|
||||
assert(unique([]) == []);
|
||||
assert(unique([8]) == [8]);
|
||||
assert(unique([7,3,9,4,3,1,8]) == [1,3,4,7,8,9]);
|
||||
}
|
||||
test_unique();
|
||||
|
||||
|
||||
module test_array_dim() {
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) == [2,2,3]);
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 0) == 2);
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 2) == 3);
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9]]]) == [2,undef,3]);
|
||||
}
|
||||
test_array_dim();
|
||||
|
||||
|
||||
module test_vmul() {
|
||||
assert(vmul([3,4,5], [8,7,6]) == [24,28,30]);
|
||||
assert(vmul([1,2,3], [4,5,6]) == [4,10,18]);
|
||||
}
|
||||
test_vmul();
|
||||
|
||||
|
||||
module test_vdiv() {
|
||||
assert(vdiv([24,28,30], [8,7,6]) == [3, 4, 5]);
|
||||
}
|
||||
test_vdiv();
|
||||
|
||||
|
||||
module test_vabs() {
|
||||
assert(vabs([2,4,8]) == [2,4,8]);
|
||||
assert(vabs([-2,-4,-8]) == [2,4,8]);
|
||||
assert(vabs([-2,4,8]) == [2,4,8]);
|
||||
assert(vabs([2,-4,8]) == [2,4,8]);
|
||||
assert(vabs([2,4,-8]) == [2,4,8]);
|
||||
}
|
||||
test_vabs();
|
||||
|
||||
|
||||
module test_normalize() {
|
||||
assert(normalize([10,0,0]) == [1,0,0]);
|
||||
assert(normalize([0,10,0]) == [0,1,0]);
|
||||
assert(normalize([0,0,10]) == [0,0,1]);
|
||||
assert(abs(norm(normalize([10,10,10]))-1) < EPSILON);
|
||||
assert(abs(norm(normalize([-10,-10,-10]))-1) < EPSILON);
|
||||
assert(abs(norm(normalize([-10,0,0]))-1) < EPSILON);
|
||||
assert(abs(norm(normalize([0,-10,0]))-1) < EPSILON);
|
||||
assert(abs(norm(normalize([0,0,-10]))-1) < EPSILON);
|
||||
}
|
||||
test_normalize();
|
||||
|
||||
|
||||
module test_vector_angle() {
|
||||
vecs = [[10,0,0], [-10,0,0], [0,10,0], [0,-10,0], [0,0,10], [0,0,-10]];
|
||||
for (a=vecs, b=vecs) {
|
||||
if(a==b) {
|
||||
assert(vector_angle(a,b)==0);
|
||||
} else if(a==-b) {
|
||||
assert(vector_angle(a,b)==180);
|
||||
} else {
|
||||
assert(vector_angle(a,b)==90);
|
||||
}
|
||||
}
|
||||
assert(abs(vector_angle([10,10,0],[10,0,0])-45) < EPSILON);
|
||||
}
|
||||
test_vector_angle();
|
||||
|
||||
|
||||
module test_vector_axis() {
|
||||
assert(norm(vector_axis([10,0,0],[10,10,0]) - [0,0,1]) < EPSILON);
|
||||
assert(norm(vector_axis([10,0,0],[0,10,0]) - [0,0,1]) < EPSILON);
|
||||
assert(norm(vector_axis([0,10,0],[10,0,0]) - [0,0,-1]) < EPSILON);
|
||||
assert(norm(vector_axis([0,0,10],[10,0,0]) - [0,1,0]) < EPSILON);
|
||||
assert(norm(vector_axis([10,0,0],[0,0,10]) - [0,-1,0]) < EPSILON);
|
||||
assert(norm(vector_axis([10,0,10],[0,-10,0]) - [sin(45),0,-sin(45)]) < EPSILON);
|
||||
}
|
||||
test_vector_axis();
|
||||
|
||||
|
||||
module test_point2d() {
|
||||
assert(point2d([1,2,3])==[1,2]);
|
||||
assert(point2d([2,3])==[2,3]);
|
||||
assert(point2d([1])==[1,0]);
|
||||
}
|
||||
test_point2d();
|
||||
|
||||
|
||||
module test_path2d() {
|
||||
assert(path2d([[1], [1,2], [1,2,3], [1,2,3,4], [1,2,3,4,5]])==[[1,0],[1,2],[1,2],[1,2],[1,2]]);
|
||||
}
|
||||
test_path2d();
|
||||
|
||||
|
||||
module test_point3d() {
|
||||
assert(point3d([1,2,3,4,5])==[1,2,3]);
|
||||
assert(point3d([1,2,3,4])==[1,2,3]);
|
||||
assert(point3d([1,2,3])==[1,2,3]);
|
||||
assert(point3d([2,3])==[2,3,0]);
|
||||
assert(point3d([1])==[1,0,0]);
|
||||
}
|
||||
test_point3d();
|
||||
|
||||
|
||||
module test_path3d() {
|
||||
assert(path3d([[1], [1,2], [1,2,3], [1,2,3,4], [1,2,3,4,5]])==[[1,0,0],[1,2,0],[1,2,3],[1,2,3],[1,2,3]]);
|
||||
}
|
||||
test_path3d();
|
||||
|
||||
|
||||
module test_translate_points() {
|
||||
pts = [[0,0,1], [0,1,0], [1,0,0], [0,0,-1], [0,-1,0], [-1,0,0]];
|
||||
assert(translate_points(pts, v=[1,2,3]) == [[1,2,4], [1,3,3], [2,2,3], [1,2,2], [1,1,3], [0,2,3]]);
|
||||
assert(translate_points(pts, v=[-1,-2,-3]) == [[-1,-2,-2], [-1,-1,-3], [0,-2,-3], [-1,-2,-4], [-1,-3,-3], [-2,-2,-3]]);
|
||||
}
|
||||
test_translate_points();
|
||||
|
||||
|
||||
module test_scale_points() {
|
||||
pts = [[0,0,1], [0,1,0], [1,0,0], [0,0,-1], [0,-1,0], [-1,0,0]];
|
||||
assert(scale_points(pts, v=[2,3,4]) == [[0,0,4], [0,3,0], [2,0,0], [0,0,-4], [0,-3,0], [-2,0,0]]);
|
||||
assert(scale_points(pts, v=[-2,-3,-4]) == [[0,0,-4], [0,-3,0], [-2,0,0], [0,0,4], [0,3,0], [2,0,0]]);
|
||||
assert(scale_points(pts, v=[1,1,1]) == [[0,0,1], [0,1,0], [1,0,0], [0,0,-1], [0,-1,0], [-1,0,0]]);
|
||||
assert(scale_points(pts, v=[-1,-1,-1]) == [[0,0,-1], [0,-1,0], [-1,0,0], [0,0,1], [0,1,0], [1,0,0]]);
|
||||
}
|
||||
test_scale_points();
|
||||
|
||||
|
||||
module test_rotate_points2d() {
|
||||
pts = [[0,1], [1,0], [0,-1], [-1,0]];
|
||||
s = sin(45);
|
||||
assert(rotate_points2d(pts,45) == [[-s,s],[s,s],[s,-s],[-s,-s]]);
|
||||
assert(rotate_points2d(pts,90) == [[-1,0],[0,1],[1,0],[0,-1]]);
|
||||
assert(rotate_points2d(pts,90,cp=[1,0]) == [[0,-1],[1,0],[2,-1],[1,-2]]);
|
||||
}
|
||||
test_rotate_points2d();
|
||||
|
||||
|
||||
module test_rotate_points3d() {
|
||||
pts = [[0,0,1], [0,1,0], [1,0,0], [0,0,-1], [0,-1,0], [-1,0,0]];
|
||||
assert(rotate_points3d(pts, [90,0,0]) == [[0,-1,0], [0,0,1], [1,0,0], [0,1,0], [0,0,-1], [-1,0,0]]);
|
||||
assert(rotate_points3d(pts, [0,90,0]) == [[1,0,0], [0,1,0], [0,0,-1], [-1,0,0], [0,-1,0], [0,0,1]]);
|
||||
assert(rotate_points3d(pts, [0,0,90]) == [[0,0,1], [-1,0,0], [0,1,0], [0,0,-1], [1,0,0], [0,-1,0]]);
|
||||
assert(rotate_points3d(pts, [0,0,90],cp=[2,0,0]) == [[2,-2,1], [1,-2,0], [2,-1,0], [2,-2,-1], [3,-2,0], [2,-3,0]]);
|
||||
assert(rotate_points3d(pts, 90, axis=V_UP) == [[0,0,1], [-1,0,0], [0,1,0], [0,0,-1], [1,0,0], [0,-1,0]]);
|
||||
assert(rotate_points3d(pts, 90, axis=V_DOWN) == [[0,0,1], [1,0,0], [0,-1,0], [0,0,-1], [-1,0,0], [0,1,0]]);
|
||||
assert(rotate_points3d(pts, 90, axis=V_RIGHT) == [[0,-1,0], [0,0,1], [1,0,0], [0,1,0], [0,0,-1], [-1,0,0]]);
|
||||
assert(rotate_points3d(pts, from=V_UP, to=V_BACK) == [[0,1,0], [0,0,-1], [1,0,0], [0,-1,0], [0,0,1], [-1,0,0]]);
|
||||
assert(rotate_points3d(pts, 90, from=V_UP, to=V_BACK), [[0,1,0], [-1,0,0], [0,0,-1], [0,-1,0], [1,0,0], [0,0,1]]);
|
||||
assert(rotate_points3d(pts, from=V_UP, to=V_UP*2) == [[0,0,1], [0,1,0], [1,0,0], [0,0,-1], [0,-1,0], [-1,0,0]]);
|
||||
assert(rotate_points3d(pts, from=V_UP, to=V_DOWN*2) == [[0,0,-1], [0,1,0], [-1,0,0], [0,0,1], [0,-1,0], [1,0,0]]);
|
||||
}
|
||||
test_rotate_points3d();
|
||||
|
||||
|
||||
module test_simplify_path()
|
||||
{
|
||||
path = [[-20,10],[-10,0],[-5,0],[0,0],[5,0],[10,0], [10,10]];
|
||||
assert(simplify_path(path) == [[-20,10],[-10,0],[10,0], [10,10]]);
|
||||
}
|
||||
test_simplify_path();
|
||||
|
||||
|
||||
module test_simplify_path_indexed()
|
||||
{
|
||||
points = [[-20,10],[-10,0],[-5,0],[0,0],[5,0],[10,0], [10,10]];
|
||||
path = list_range(len(points));
|
||||
assert(simplify_path_indexed(points, path) == [0,1,5,6]);
|
||||
}
|
||||
test_simplify_path_indexed();
|
||||
|
||||
|
||||
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||
|
|
67
tests/test_vectors.scad
Normal file
67
tests/test_vectors.scad
Normal file
|
@ -0,0 +1,67 @@
|
|||
include <BOSL2/std.scad>
|
||||
|
||||
|
||||
module test_vmul() {
|
||||
assert(vmul([3,4,5], [8,7,6]) == [24,28,30]);
|
||||
assert(vmul([1,2,3], [4,5,6]) == [4,10,18]);
|
||||
}
|
||||
test_vmul();
|
||||
|
||||
|
||||
module test_vdiv() {
|
||||
assert(vdiv([24,28,30], [8,7,6]) == [3, 4, 5]);
|
||||
}
|
||||
test_vdiv();
|
||||
|
||||
|
||||
module test_vabs() {
|
||||
assert(vabs([2,4,8]) == [2,4,8]);
|
||||
assert(vabs([-2,-4,-8]) == [2,4,8]);
|
||||
assert(vabs([-2,4,8]) == [2,4,8]);
|
||||
assert(vabs([2,-4,8]) == [2,4,8]);
|
||||
assert(vabs([2,4,-8]) == [2,4,8]);
|
||||
}
|
||||
test_vabs();
|
||||
|
||||
|
||||
module test_normalize() {
|
||||
assert(normalize([10,0,0]) == [1,0,0]);
|
||||
assert(normalize([0,10,0]) == [0,1,0]);
|
||||
assert(normalize([0,0,10]) == [0,0,1]);
|
||||
assert(abs(norm(normalize([10,10,10]))-1) < EPSILON);
|
||||
assert(abs(norm(normalize([-10,-10,-10]))-1) < EPSILON);
|
||||
assert(abs(norm(normalize([-10,0,0]))-1) < EPSILON);
|
||||
assert(abs(norm(normalize([0,-10,0]))-1) < EPSILON);
|
||||
assert(abs(norm(normalize([0,0,-10]))-1) < EPSILON);
|
||||
}
|
||||
test_normalize();
|
||||
|
||||
|
||||
module test_vector_angle() {
|
||||
vecs = [[10,0,0], [-10,0,0], [0,10,0], [0,-10,0], [0,0,10], [0,0,-10]];
|
||||
for (a=vecs, b=vecs) {
|
||||
if(a==b) {
|
||||
assert(vector_angle(a,b)==0);
|
||||
} else if(a==-b) {
|
||||
assert(vector_angle(a,b)==180);
|
||||
} else {
|
||||
assert(vector_angle(a,b)==90);
|
||||
}
|
||||
}
|
||||
assert(abs(vector_angle([10,10,0],[10,0,0])-45) < EPSILON);
|
||||
}
|
||||
test_vector_angle();
|
||||
|
||||
|
||||
module test_vector_axis() {
|
||||
assert(norm(vector_axis([10,0,0],[10,10,0]) - [0,0,1]) < EPSILON);
|
||||
assert(norm(vector_axis([10,0,0],[0,10,0]) - [0,0,1]) < EPSILON);
|
||||
assert(norm(vector_axis([0,10,0],[10,0,0]) - [0,0,-1]) < EPSILON);
|
||||
assert(norm(vector_axis([0,0,10],[10,0,0]) - [0,1,0]) < EPSILON);
|
||||
assert(norm(vector_axis([10,0,0],[0,0,10]) - [0,-1,0]) < EPSILON);
|
||||
assert(norm(vector_axis([10,0,10],[0,-10,0]) - [sin(45),0,-sin(45)]) < EPSILON);
|
||||
}
|
||||
test_vector_axis();
|
||||
|
||||
|
||||
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
Loading…
Reference in a new issue