Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions attachments.scad
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,13 @@ _ANCHOR_TYPES = ["intersect","hull"];
// is a list of edge set descriptors to include in the edge set, and the `except` argument is a list of
// edge set descriptors to remove from the edge set.
// The default value for `edges` is `"ALL"`, the set of all edges.
// The default value for `except` is the empty set, meaning no edges are removed.
// The default value for `except` is the empty set, meaning no edges are removed.
// If either argument is just a single edge set
// descriptor it can be passed directly rather than in a singleton list.
// Each edge set descriptor must be one of:
// - A 3-vector with entries in {-1,0,1} pointing toward an edge, indicating that single edge.
// - A 3-vector with entries in {-1,0,1} pointing toward a face, indicating all edges surrounding that face.
// - A 3-vector with entries in {-1,0,1} pointing toward a corner, indicating all edges touching that corner.
// - A 3-vector with entries in {-1,0,1} pointing toward an edge of a centered cube, indicating that single edge.
// - A 3-vector with entries in {-1,0,1} pointing toward a face of a centered cube, indicating all edges surrounding that face.
// - A 3-vector with entries in {-1,0,1} pointing toward a corner of a centered cube, indicating all edges touching that corner.
// - The string `"X"`, indicating all X axis aligned edges.
// - The string `"Y"`, indicating all Y axis aligned edges.
// - The string `"Z"`, indicating all Z axis aligned edges.
Expand All @@ -231,7 +231,8 @@ _ANCHOR_TYPES = ["intersect","hull"];
// ```
// .
// You can specify edge descriptors directly by giving a vector, or you can use sums of the
// named direction vectors described above. Below we show all of the edge sets you can
// named direction vectors described above.
// Below we show all of the edge sets you can
// describe with sums of the direction vectors, and then we show some examples of combining
// edge set descriptors.
// Figure(3D,Big,VPD=300,NoScales): Vectors pointing toward an edge select that single edge
Expand Down Expand Up @@ -325,9 +326,9 @@ _ANCHOR_TYPES = ["intersect","hull"];
// If either argument is just a single corner set
// descriptor it can be passed directly rather than in a singleton list.
// Each corner set descriptor must be one of:
// - A vector pointing toward a corner, indicating that corner.
// - A vector pointing toward an edge indicating both corners at the ends of that edge.
// - A vector pointing toward a face, indicating all the corners of that face.
// - A 3-vector with entries in {-1,0,1} pointing toward a corner of a centered cube, indicating that corner.
// - A 3-vector with entries in {-1,0,1} pointing toward an edge of a centered cube indicating both corners at the ends of that edge.
// - A 3-vector with entries in {-1,0,1} pointing toward a face of a centered cube, indicating all the corners of that face.
// - The string `"ALL"`, indicating all corners.
// - The string `"NONE"`, indicating no corners at all.
// - A length 8 vector where each entry corresponds to a corner and is 1 if the corner is included and 0 if it is excluded. The corner ordering is
Expand Down
22 changes: 3 additions & 19 deletions lists.scad
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ _BOSL2_LISTS = is_undef(_BOSL2_STD) && (is_undef(BOSL2_NO_STD_WARNING) || !BOSL2
// bool = is_homogeneous(list, [depth]);
// Description:
// Returns true when the list has elements of same type up to the depth `depth`.
// Booleans and numbers are not distinguinshed as of distinct types.
// Arguments:
// l = the list to check
// depth = the lowest level the check is done. Default: 10
Expand All @@ -38,7 +37,7 @@ _BOSL2_LISTS = is_undef(_BOSL2_STD) && (is_undef(BOSL2_NO_STD_WARNING) || !BOSL2
// b = is_homogeneous([[1,["a"]], [2,[true]]]); // Returns false
// c = is_homogeneous([[1,["a"]], [2,[true]]], 1); // Returns true
// d = is_homogeneous([[1,["a"]], [2,[true]]], 2); // Returns false
// e = is_homogeneous([[1,["a"]], [true,["b"]]]); // Returns true
// e = is_homogeneous([[1,["a"]], [true,["b"]]]); // Returns false
function is_homogeneous(l, depth=10) =
!is_list(l) || l==[] ? false :
let( l0=l[0] )
Expand Down Expand Up @@ -91,21 +90,6 @@ function max_length(list) =
max([for (v = list) len(v)]);




// Internal. Not exposed.
function _list_shape_recurse(v) =
!is_list(v[0])
? len( [for(entry=v) if(!is_list(entry)) 0] ) == 0 ? [] : [undef]
: let(
firstlen = is_list(v[0]) ? len(v[0]): undef,
first = len( [for(entry = v) if(! is_list(entry) || (len(entry) != firstlen)) 0 ] ) == 0 ? firstlen : undef,
leveldown = flatten(v)
)
is_list(leveldown[0])
? concat([first],_list_shape_recurse(leveldown))
: [first];

function _list_shape_recurse(v) =
let( alen = [for(vi=v) is_list(vi) ? len(vi): -1] )
v==[] || max(alen)==-1 ? [] :
Expand Down Expand Up @@ -257,8 +241,8 @@ function select(list, start, end) =
// c = slice([3,4,5,6,7,8,9], 1, 1); // Returns [4]
// d = slice([3,4,5,6,7,8,9], 5); // Returns [8,9]
// e = slice([3,4,5,6,7,8,9], 2, -2); // Returns [5,6,7,8]
// f = slice([3,4,5,6,7,8,9], 4, 3; // Returns []
// g = slice([3,4,5], 1, 5; // Returns [4,5]
// f = slice([3,4,5,6,7,8,9], 4, 3); // Returns []
// g = slice([3,4,5], 1, 5); // Returns [4,5]
// h = slice([3,4,5], 5, 7); // Returns []
function slice(list,start=0,end=-1) =
assert(is_list(list))
Expand Down
29 changes: 14 additions & 15 deletions math.scad
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,11 @@ function slerp(v1, v2, u) =
theta = acos(max(-1, min(1, a*b))),
err = assert(abs(theta-180)>_EPSILON, "\nNo solution when vectors v1 and v2 are 180° apart."),
sin_theta = sin(theta)
) sin_theta < _EPSILON ? unit(a+b) // fallback
: is_finite(u) ? (sin_theta < _EPSILON ? unit(a+b)
: (a * sin((1 - u) * theta) + b * sin(u * theta)) / sin_theta)
: [for(t=u) sin_theta < _EPSILON ? unit(a+b)
: (a * sin((1 - t) * theta) + b * sin(t * theta)) / sin_theta];
)
is_finite(u) ? (sin_theta < _EPSILON ? unit(a+b)
: (a * sin((1 - u) * theta) + b * sin(u * theta)) / sin_theta)
: [for(t=u) sin_theta < _EPSILON ? unit(a+b)
: (a * sin((1 - t) * theta) + b * sin(t * theta)) / sin_theta];


// Function: slerpn()
Expand Down Expand Up @@ -385,7 +385,7 @@ function binomial_coefficient(n,k) =
// Function: gcd()
// Synopsis: Returns the Greatest Common Divisor/Factor of two integers.
// Topics: Math
// See Also: hypot(), sqr(), log2(), factorial(), binomial(), gcd(), lcm()
// See Also: hypot(), sqr(), log2(), factorial(), binomial(), lcm()
// Usage:
// x = gcd(a,b)
// Description:
Expand All @@ -411,7 +411,7 @@ function _lcmlist(a) =
// Function: lcm()
// Synopsis: Returns the Least Common Multiple of two or more integers.
// Topics: Math
// See Also: hypot(), sqr(), log2(), factorial(), binomial(), gcd(), lcm()
// See Also: hypot(), sqr(), log2(), factorial(), binomial(), gcd()
// Usage:
// div = lcm(a, b);
// divs = lcm(list);
Expand Down Expand Up @@ -805,7 +805,6 @@ function fit_to_range(M, minval, maxval) =
let(
is_vec = is_vector(M),
dum = assert(is_vec || (is_list(M) && is_vector(M[0])), "\nParameter M must be a vector or list of vectors."),
rowlen = len(is_vec ? M : M[0]),
v = is_vec ? M : flatten(M),
a = min(v),
b = max(v)
Expand Down Expand Up @@ -849,7 +848,7 @@ function _sum(v,_total,_i=0) = _i>=len(v) ? _total : _sum(v,_total+v[_i], _i+1);
// Function: mean()
// Synopsis: Returns the mean value of a list of values.
// Topics: Math, Statistics
// See Also: sum(), mean(), median(), product()
// See Also: sum(), median(), product()
// Usage:
// x = mean(v);
// Description:
Expand All @@ -869,7 +868,7 @@ function mean(v) =
// Function: median()
// Synopsis: Returns the median value of a list of values.
// Topics: Math, Statistics
// See Also: sum(), mean(), median(), product()
// See Also: sum(), mean(), product()
// Usage:
// middle = median(v)
// Description:
Expand Down Expand Up @@ -949,7 +948,7 @@ function cumsum(v) =
// Example:
// product([2,3,4]); // returns 24.
// product([[1,2,3], [3,4,5], [5,6,7]]); // returns [15, 48, 105]
function product(list,right=true) =
function product(list) =
list==[] ? [] :
is_matrix(list) ?
[for (a = list[0],
Expand Down Expand Up @@ -1374,7 +1373,7 @@ function deriv2(data, h=1, closed=false) =
(35*data[0] - 104*data[1] + 114*data[2] - 56*data[3] + 11*data[4])/12,
last =
L==3? data[L-1] - 2*data[L-2] + data[L-3] :
L==4? -2*data[L-1] + 5*data[L-2] - 4*data[L-3] + data[L-4] :
L==4? 2*data[L-1] - 5*data[L-2] + 4*data[L-3] - data[L-4] :
(35*data[L-1] - 104*data[L-2] + 114*data[L-3] - 56*data[L-4] + 11*data[L-5])/12
) [
first/h/h,
Expand Down Expand Up @@ -1497,7 +1496,7 @@ function _c_mul(z1,z2) =
// z1 = First complex number, given as a 2D vector [REAL, IMAGINARY]
// z2 = Second complex number, given as a 2D vector [REAL, IMAGINARY]
function c_div(z1,z2) =
assert( is_vector(z1,2) && is_vector(z2), "\nComplex numbers should be represented by 2D vectors.")
assert( is_vector(z1,2) && is_vector(z2,2), "\nComplex numbers should be represented by 2D vectors.")
assert( !approx(z2,0), "\nThe divisor `z2` cannot be zero.")
let(den = z2.x*z2.x + z2.y*z2.y)
[(z1.x*z2.x + z1.y*z2.y)/den, (z1.y*z2.x - z1.x*z2.y)/den];
Expand Down Expand Up @@ -1634,8 +1633,8 @@ function polynomial(p,z,k,total) =
// Topics: Math
// See Also: quadratic_roots(), polynomial(), poly_mult(), poly_div(), poly_add(), poly_roots()
// Usage:
// x = polymult(p,q)
// x = polymult([p1,p2,p3,...])
// x = poly_mult(p,q)
// x = poly_mult([p1,p2,p3,...])
// Description:
// Given a list of polynomials represented as real algebraic coefficient lists, with the highest degree coefficient first,
// computes the coefficient list of the product polynomial.
Expand Down
25 changes: 12 additions & 13 deletions vectors.scad
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ _BOSL2_VECTORS = is_undef(_BOSL2_STD) && (is_undef(BOSL2_NO_STD_WARNING) || !BOS
// is_vector([3,4,5,6]); // Returns true
// is_vector([3,4,undef,5]); // Returns false
// is_vector([3,4,5],3); // Returns true
// is_vector([3,4,5],4); // Returns true
// is_vector([3,4,5],4); // Returns false
// is_vector([]); // Returns false
// is_vector([0,4,0],3,zero=false); // Returns true
// is_vector([0,0,0],zero=false); // Returns false
// is_vector([0,0,1e-12],zero=false); // Returns false
// is_vector([0,1,0],all_nonzero=false); // Returns false
// is_vector([1,1,1],all_nonzero=false); // Returns true
// is_vector([0,1,0],all_nonzero=true); // Returns false
// is_vector([1,1,1],all_nonzero=true); // Returns true
// is_vector([],zero=false); // Returns false
function is_vector(v, length, zero, all_nonzero=false, eps=_EPSILON) =
is_list(v) && len(v)>0 && []==[for(vi=v) if(!is_finite(vi)) 0]
Expand Down Expand Up @@ -440,21 +440,21 @@ function furthest_point(pt, points) =
// query = list of points to find matches for.
// r = the search radius.
// target = list of the points to search for matches or a search tree.
// Example: A set of four queries to find points within 1 unit of the query. The circles show the search region and all have radius 1.
// Example(2D,Med): A set of four queries to find points within 1 unit of the query. The circles show the search region and all have radius 1.
// $fn=32;
// k = 2000;
// points = list_to_matrix(rands(0,10,k*2,seed=13333),2);
// queries = [for(i=[3,7],j=[3,7]) [i,j]];
// search_ind = vector_search(queries, points, 1);
// search_ind = vector_search(queries, 1, points);
// move_copies(points) circle(r=.08);
// for(i=idx(queries)){
// color("blue")stroke(move(queries[i],circle(r=1)), closed=true, width=.08);
// color("red") move_copies(select(points, search_ind[i])) circle(r=.08);
// }
// Example: when a series of searches with different radius are needed, its is faster to pre-compute the tree
// Example(2D,Med): when a series of searches with different radius are needed, its is faster to pre-compute the tree
// $fn=32;
// k = 2000;
// points = list_to_matrix(rands(0,10,k*2),2,seed=13333);
// points = list_to_matrix(rands(0,10,k*2,seed=13333),2);
// queries1 = [for(i=[3,7]) [i,i]];
// queries2 = [for(i=[3,7]) [10-i,i]];
// r1 = 1;
Expand Down Expand Up @@ -517,14 +517,13 @@ function _bt_search(query, r, points, tree) =
[ if(norm(query-points[tree[0]])<=r) tree[0] ],
_bt_search(query, r, points, tree[2]),
_bt_search(query, r, points, tree[3]) ) ;


// Function: vector_search_tree()
// Synopsis: Makes a distance search tree for a list of points.
// Topics: Search, Points, Closest
// See Also: vector_nearest(), vector_search()
// Usage:
// tree = vector_search_tree(points,leafsize);
// tree = vector_search_tree(points,[leafsize],[treemin]);
// Description:
// Construct a search tree for the given list of points to be used as input
// to the function `vector_search()`. The use of a tree speeds up the
Expand All @@ -544,7 +543,7 @@ function _bt_search(query, r, points, tree) =
// points = list of points to store in the search tree.
// leafsize = the size of the tree leaves. Default: 25
// treemin = the minimum size of the point list for which a tree search is done. Default: 400
// Example: A set of four queries to find points within 1 unit of the query. The circles show the search region and all have radius 1.
// Example(2D,Med): A set of four queries to find points within 1 unit of the query. The circles show the search region and all have radius 1.
// $fn=32;
// k = 2000;
// points = random_points(k, scale=10, dim=2,seed=13333);
Expand Down Expand Up @@ -596,7 +595,7 @@ function _bt_tree(points, ind, leafsize=25) =
// query = point to search for
// k = number of neighbors to return
// target = a list of points or a search tree to search in
// Example: Four queries to find the 15 nearest points. The circles show the radius defined by the most distant query result. Note they are different for each query.
// Example(2D,Med): Four queries to find the 15 nearest points. The circles show the radius defined by the most distant query result. Note they are different for each query.
// $fn=32;
// k = 1000;
// points = list_to_matrix(rands(0,10,k*2,seed=13333),2);
Expand Down Expand Up @@ -730,8 +729,8 @@ function fit_to_box(pts, x, y, z) =
assert(is_path(pts) || is_vnf(pts), "\npts must be a valid 2D or 3D path, or a VNF structure.")
assert(any_defined([x,y,z]), "\nAt least one [min,max] range x, y, or z must be defined.")
assert(is_undef(x) || is_vector(x,2), "\nx must be a 2-vector [min,max].")
assert(is_undef(y) || is_vector(y,2), "\nx must be a 2-vector [min,max].")
assert(is_undef(z) || is_vector(z,2), "\nx must be a 2-vector [min,max].")
assert(is_undef(y) || is_vector(y,2), "\ny must be a 2-vector [min,max].")
assert(is_undef(z) || is_vector(z,2), "\nz must be a 2-vector [min,max].")
let(
isvnf = is_vnf(pts),
p = isvnf ? pts[0] : pts,
Expand Down
2 changes: 1 addition & 1 deletion version.scad
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ _BOSL2_VERSION = is_undef(_BOSL2_STD) && (is_undef(BOSL2_NO_STD_WARNING) || !BOS



BOSL_VERSION = [2,0,747];
BOSL_VERSION = [2,0,748];



Expand Down
Loading