mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
c9408a66fa
19 changed files with 109 additions and 229 deletions
30
arrays.scad
30
arrays.scad
|
@ -1126,25 +1126,25 @@ function add_scalar(v,s) =
|
|||
|
||||
|
||||
// Function: subindex()
|
||||
// Usage:
|
||||
// subindex(M, idx)
|
||||
// Description:
|
||||
// For each array item, return the indexed subitem.
|
||||
// Returns a list of the values of each vector at the specfied
|
||||
// index list or range. If the index list or range has
|
||||
// only one entry the output list is flattened.
|
||||
// Extracts the entries listed in idx from each entry in M. For a matrix this means
|
||||
// selecting a specified set of columsn. If idx is a number the return is a vector, otherwise
|
||||
// it is a list of lists (the submatrix).
|
||||
// Arguments:
|
||||
// v = The given list of lists.
|
||||
// M = The given list of lists.
|
||||
// idx = The index, list of indices, or range of indices to fetch.
|
||||
// Example:
|
||||
// v = [[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]];
|
||||
// subindex(v,2); // Returns [3, 7, 11, 15]
|
||||
// subindex(v,[2,1]); // Returns [[3, 2], [7, 6], [11, 10], [15, 14]]
|
||||
// subindex(v,[1:3]); // Returns [[2, 3, 4], [6, 7, 8], [10, 11, 12], [14, 15, 16]]
|
||||
function subindex(v, idx) =
|
||||
[ for(val=v)
|
||||
let( value=[for(i=idx) val[i]] )
|
||||
len(value)==1 ? value[0] : value
|
||||
];
|
||||
|
||||
// M = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]];
|
||||
// subindex(M,2); // Returns [3, 7, 11, 15]
|
||||
// subindex(M,[2]); // Returns [[3], [7], [11], [15]]
|
||||
// subindex(M,[2,1]); // Returns [[3, 2], [7, 6], [11, 10], [15, 14]]
|
||||
// subindex(M,[1:3]); // Returns [[2, 3, 4], [6, 7, 8], [10, 11, 12], [14, 15, 16]]
|
||||
function subindex(M, idx) =
|
||||
is_num(idx)
|
||||
? [for(row=M) row[idx]]
|
||||
: [for(row=M) [for(i=idx) row[i]]];
|
||||
|
||||
// Function: zip()
|
||||
// Usage:
|
||||
|
|
|
@ -285,7 +285,7 @@ function attach_geom_size(geom) =
|
|||
) [2*maxxr,2*maxyr,l]
|
||||
) : type == "spheroid"? ( //r
|
||||
let( r=geom[1] )
|
||||
is_num(r)? [2,2,2]*r : vmul([2,2,2],r)
|
||||
is_num(r)? [2,2,2]*r : vmul([2,2,2],point3d(r))
|
||||
) : type == "vnf_extent" || type=="vnf_isect"? ( //vnf
|
||||
let(
|
||||
mm = pointlist_bounds(geom[1][0]),
|
||||
|
@ -298,7 +298,7 @@ function attach_geom_size(geom) =
|
|||
) [maxx, size.y]
|
||||
) : type == "circle"? ( //r
|
||||
let( r=geom[1] )
|
||||
is_num(r)? [2,2]*r : vmul([2,2],r)
|
||||
is_num(r)? [2,2]*r : vmul([2,2],point2d(r))
|
||||
) : type == "path_isect" || type == "path_extent"? ( //path
|
||||
let(
|
||||
mm = pointlist_bounds(geom[1]),
|
||||
|
@ -430,8 +430,8 @@ function find_anchor(anchor, geom) =
|
|||
) : type == "cyl"? ( //r1, r2, l, shift
|
||||
let(
|
||||
rr1=geom[1], rr2=geom[2], l=geom[3], shift=point2d(geom[4]),
|
||||
r1 = is_num(rr1)? [rr1,rr1] : rr1,
|
||||
r2 = is_num(rr2)? [rr2,rr2] : rr2,
|
||||
r1 = is_num(rr1)? [rr1,rr1] : point2d(rr1),
|
||||
r2 = is_num(rr2)? [rr2,rr2] : point2d(rr2),
|
||||
u = (anchor.z+1)/2,
|
||||
axy = unit(point2d(anchor),[0,0]),
|
||||
bot = point3d(vmul(r1,axy), -l/2),
|
||||
|
@ -447,9 +447,9 @@ function find_anchor(anchor, geom) =
|
|||
) : type == "spheroid"? ( //r
|
||||
let(
|
||||
rr = geom[1],
|
||||
r = is_num(rr)? [rr,rr,rr] : rr,
|
||||
r = is_num(rr)? [rr,rr,rr] : point3d(rr),
|
||||
anchor = unit(point3d(anchor),CENTER),
|
||||
pos = point3d(cp) + vmul(r,anchor) + offset,
|
||||
pos = point3d(cp) + vmul(r,anchor) + point3d(offset),
|
||||
vec = unit(vmul(r,anchor),UP)
|
||||
) [anchor, pos, vec, oang]
|
||||
) : type == "vnf_isect"? ( //vnf
|
||||
|
@ -519,10 +519,10 @@ function find_anchor(anchor, geom) =
|
|||
) : type == "circle"? ( //r
|
||||
let(
|
||||
rr = geom[1],
|
||||
r = is_num(rr)? [rr,rr] : rr,
|
||||
pos = point2d(cp) + vmul(r,anchor) + offset,
|
||||
r = is_num(rr)? [rr,rr] : point2d(rr),
|
||||
anchor = unit(point2d(anchor),[0,0]),
|
||||
vec = unit(vmul([r.y,r.x],anchor),[0,1])
|
||||
pos = point2d(cp) + vmul(r,anchor) + point2d(offset),
|
||||
vec = unit(vmul(r,anchor),[0,1])
|
||||
) [anchor, pos, vec, 0]
|
||||
) : type == "path_isect"? ( //path
|
||||
let(
|
||||
|
@ -970,7 +970,8 @@ module edge_profile(edges=EDGES_ALL, except=[], convexity=10) {
|
|||
$attach_anchor = anch;
|
||||
$attach_norot = true;
|
||||
$tags = "mask";
|
||||
length = sum(vmul($parent_size, [for (x=vec) x?0:1]))+0.1;
|
||||
psize = point3d($parent_size);
|
||||
length = [for (i=[0:2]) if(!vec[i]) psize[i]][0]+0.1;
|
||||
rotang =
|
||||
vec.z<0? [90,0,180+vang(point2d(vec))] :
|
||||
vec.z==0 && sign(vec.x)==sign(vec.y)? 135+vang(point2d(vec)) :
|
||||
|
|
15
common.scad
15
common.scad
|
@ -148,7 +148,7 @@ function _list_pattern(list) =
|
|||
// is_consistent([[3,[3,4,[5]]], [5,[2,9,[9]]]]); // Returns true
|
||||
// is_consistent([[3,[3,4,[5]]], [5,[2,9,9]]]); // Returns false
|
||||
function is_consistent(list) =
|
||||
is_list(list) && is_list_of(list, _list_pattern(list[0]));
|
||||
/*is_list(list) &&*/ is_list_of(list, _list_pattern(list[0]));
|
||||
|
||||
|
||||
//Internal function
|
||||
|
@ -346,6 +346,19 @@ function segs(r) =
|
|||
|
||||
|
||||
|
||||
// Module: no_children()
|
||||
// Usage:
|
||||
// no_children($children);
|
||||
// Description:
|
||||
// Assert that the calling module does not support children. Prints an error message to this effect and fails if children are present,
|
||||
// as indicated by its argument.
|
||||
// Arguments:
|
||||
// $children = number of children the module has.
|
||||
module no_children(count) {
|
||||
assert(count==0, str("Module ",parent_module(1),"() does not support child modules"));
|
||||
}
|
||||
|
||||
|
||||
// Section: Testing Helpers
|
||||
|
||||
|
||||
|
|
|
@ -949,7 +949,7 @@ module ovoid_spread(r=undef, d=undef, n=100, cone_ang=90, scale=[1,1,1], perp=tr
|
|||
for ($idx = idx(theta_phis)) {
|
||||
tp = theta_phis[$idx];
|
||||
xyz = spherical_to_xyz(r, tp[0], tp[1]);
|
||||
$pos = vmul(xyz,scale);
|
||||
$pos = vmul(xyz,point3d(scale,1));
|
||||
$theta = tp[0];
|
||||
$phi = tp[1];
|
||||
$rad = r;
|
||||
|
|
126
errors.scad
126
errors.scad
|
@ -1,126 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
// LibFile: errors.scad
|
||||
// Functions and modules to facilitate error reporting.
|
||||
// To use, include this line at the top of your file:
|
||||
// ```
|
||||
// use <BOSL2/std.scad>
|
||||
// ```
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
// Section: Warnings and Errors
|
||||
|
||||
|
||||
// Module: no_children()
|
||||
// Usage:
|
||||
// no_children($children);
|
||||
// Description:
|
||||
// Assert that the calling module does not support children. Prints an error message to this effect and fails if children are present,
|
||||
// as indicated by its argument.
|
||||
// Arguments:
|
||||
// $children = number of children the module has.
|
||||
module no_children(count) {
|
||||
assert(count==0, str("Module ",parent_module(1),"() does not support child modules"));
|
||||
}
|
||||
|
||||
|
||||
// Function&Module: echo_error()
|
||||
// Usage:
|
||||
// echo_error(msg, [pfx]);
|
||||
// Description:
|
||||
// Emulates printing of an error message. The text will be shaded red.
|
||||
// You can also use this as a function call from a function.
|
||||
// Arguments:
|
||||
// msg = The message to print.
|
||||
// pfx = The prefix to print before `msg`. Default: `ERROR`
|
||||
module echo_error(msg, pfx="ERROR") {
|
||||
echo(str("<p style=\"background-color: #ffb0b0\"><b>", pfx, ":</b> ", msg, "</p>"));
|
||||
}
|
||||
|
||||
function echo_error(msg, pfx="ERROR") =
|
||||
echo(str("<p style=\"background-color: #ffb0b0\"><b>", pfx, ":</b> ", msg, "</p>"));
|
||||
|
||||
|
||||
// Function&Module: echo_warning()
|
||||
// Usage:
|
||||
// echo_warning(msg, [pfx]);
|
||||
// Description:
|
||||
// Emulates printing of a warning message. The text will be shaded yellow.
|
||||
// You can also use this as a function call from a function.
|
||||
// Arguments:
|
||||
// msg = The message to print.
|
||||
// pfx = The prefix to print before `msg`. Default: `WARNING`
|
||||
module echo_warning(msg, pfx="WARNING") {
|
||||
echo(str("<p style=\"background-color: #ffffb0\"><b>", pfx, ":</b> ", msg, "</p>"));
|
||||
}
|
||||
|
||||
function echo_warning(msg, pfx="WARNING") =
|
||||
echo(str("<p style=\"background-color: #ffffb0\"><b>", pfx, ":</b> ", msg, "</p>"));
|
||||
|
||||
|
||||
// Function&Module: deprecate()
|
||||
// Usage:
|
||||
// deprecate(name, [suggest]);
|
||||
// Description:
|
||||
// Show module deprecation warnings.
|
||||
// You can also use this as a function call from a function.
|
||||
// Arguments:
|
||||
// name = The name of the module that is deprecated.
|
||||
// suggest = If given, the module to recommend using instead.
|
||||
module deprecate(name, suggest=undef) {
|
||||
echo_warning(pfx="DEPRECATED",
|
||||
str(
|
||||
"`<code>", name, "</code>` is deprecated and should not be used.",
|
||||
is_undef(suggest)? "" : str(
|
||||
" You should use `<code>", suggest, "</code>` instead."
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function deprecate(name, suggest=undef) =
|
||||
echo_warning(pfx="DEPRECATED",
|
||||
str(
|
||||
"`<code>", name, "</code>` is deprecated and should not be used.",
|
||||
is_undef(suggest)? "" : str(
|
||||
" You should use `<code>", suggest, "</code>` instead."
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// Function&Module: deprecate_argument()
|
||||
// Usage:
|
||||
// deprecate(name, arg, [suggest]);
|
||||
// Description:
|
||||
// Show argument deprecation warnings.
|
||||
// You can also use this as a function call from a function.
|
||||
// Arguments:
|
||||
// name = The name of the module/function the deprecated argument is used in.
|
||||
// arg = The name of the deprecated argument.
|
||||
// suggest = If given, the argument to recommend using instead.
|
||||
module deprecate_argument(name, arg, suggest=undef) {
|
||||
echo_warning(pfx="DEPRECATED ARG", str(
|
||||
"In `<code>", name, "</code>`, ",
|
||||
"the argument `<code>", arg, "</code>` ",
|
||||
"is deprecated and should not be used.",
|
||||
is_undef(suggest)? "" : str(
|
||||
" You should use `<code>", suggest, "</code>` instead."
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
function deprecate_argument(name, arg, suggest=undef) =
|
||||
echo_warning(pfx="DEPRECATED ARG", str(
|
||||
"In `<code>", name, "</code>`, ",
|
||||
"the argument `<code>", arg, "</code>` ",
|
||||
"is deprecated and should not be used.",
|
||||
is_undef(suggest)? "" : str(
|
||||
" You should use `<code>", suggest, "</code>` instead."
|
||||
)
|
||||
));
|
||||
|
||||
|
||||
|
||||
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
94
math.scad
94
math.scad
|
@ -36,7 +36,7 @@ NAN = acos(2); // The value `nan`, useful for comparisons.
|
|||
function sqr(x) =
|
||||
is_list(x) ? [for(val=x) sqr(val)] :
|
||||
is_finite(x) ? x*x :
|
||||
assert(is_finite(x) || is_vector(x), "Input is not neither a number nor a list of numbers.");
|
||||
assert(is_finite(x) || is_vector(x), "Input is not a number nor a list of numbers.");
|
||||
|
||||
|
||||
// Function: log2()
|
||||
|
@ -641,17 +641,6 @@ function mean(v) =
|
|||
sum(v)/len(v);
|
||||
|
||||
|
||||
// Function: median()
|
||||
// Usage:
|
||||
// x = median(v);
|
||||
// Description:
|
||||
// Given a list of numbers or vectors, finds the median value or midpoint.
|
||||
// If passed a list of vectors, returns the vector of the median of each component.
|
||||
function median(v) =
|
||||
is_vector(v) ? (min(v)+max(v))/2 :
|
||||
is_matrix(v) ? [for(ti=transpose(v)) (min(ti)+max(ti))/2 ]
|
||||
: assert(false , "Invalid input.");
|
||||
|
||||
// Function: convolve()
|
||||
// Usage:
|
||||
// x = convolve(p,q);
|
||||
|
@ -773,26 +762,26 @@ function _qr_factor(A,Q, column, m, n) =
|
|||
// You can supply a compatible matrix b and it will produce the solution for every column of b. Note that if you want to
|
||||
// solve Rx=b1 and Rx=b2 you must set b to transpose([b1,b2]) and then take the transpose of the result. If the matrix
|
||||
// is singular (e.g. has a zero on the diagonal) then it returns [].
|
||||
function back_substitute(R, b, x=[],transpose = false) =
|
||||
function back_substitute(R, b, transpose = false) =
|
||||
assert(is_matrix(R, square=true))
|
||||
let(n=len(R))
|
||||
assert(is_vector(b,n) || is_matrix(b,n),str("R and b are not compatible in back_substitute ",n, len(b)))
|
||||
!is_vector(b) ? transpose([for(i=[0:len(b[0])-1]) back_substitute(R,subindex(b,i),transpose=transpose)]) :
|
||||
transpose?
|
||||
reverse(back_substitute(
|
||||
[for(i=[0:n-1]) [for(j=[0:n-1]) R[n-1-j][n-1-i]]],
|
||||
reverse(b), x, false
|
||||
)) :
|
||||
len(x) == n ? x :
|
||||
let(
|
||||
ind = n - len(x) - 1
|
||||
)
|
||||
R[ind][ind] == 0 ? [] :
|
||||
let(
|
||||
newvalue =
|
||||
len(x)==0? b[ind]/R[ind][ind] :
|
||||
(b[ind]-select(R[ind],ind+1,-1) * x)/R[ind][ind]
|
||||
) back_substitute(R, b, concat([newvalue],x));
|
||||
transpose
|
||||
? reverse(_back_substitute([for(i=[0:n-1]) [for(j=[0:n-1]) R[n-1-j][n-1-i]]],
|
||||
reverse(b)))
|
||||
: _back_substitute(R,b);
|
||||
|
||||
function _back_substitute(R, b, x=[]) =
|
||||
let(n=len(R))
|
||||
len(x) == n ? x
|
||||
: let(ind = n - len(x) - 1)
|
||||
R[ind][ind] == 0 ? []
|
||||
: let(
|
||||
newvalue = len(x)==0
|
||||
? b[ind]/R[ind][ind]
|
||||
: (b[ind]-select(R[ind],ind+1,-1) * x)/R[ind][ind]
|
||||
)
|
||||
_back_substitute(R, b, concat([newvalue],x));
|
||||
|
||||
|
||||
// Function: det2()
|
||||
|
@ -1110,19 +1099,21 @@ function _deriv_nonuniform(data, h, closed) =
|
|||
// closed = boolean to indicate if the data set should be wrapped around from the end to the start.
|
||||
function deriv2(data, h=1, closed=false) =
|
||||
assert( is_consistent(data) , "Input list is not consistent or not numerical.")
|
||||
assert( len(data)>=3, "Input list has less than 3 elements.")
|
||||
assert( is_finite(h), "The sampling `h` must be a number." )
|
||||
let( L = len(data) )
|
||||
closed? [
|
||||
assert( L>=3, "Input list has less than 3 elements.")
|
||||
closed
|
||||
? [
|
||||
for(i=[0:1:L-1])
|
||||
(data[(i+1)%L]-2*data[i]+data[(L+i-1)%L])/h/h
|
||||
] :
|
||||
]
|
||||
:
|
||||
let(
|
||||
first = L<3? undef :
|
||||
first =
|
||||
L==3? data[0] - 2*data[1] + data[2] :
|
||||
L==4? 2*data[0] - 5*data[1] + 4*data[2] - data[3] :
|
||||
(35*data[0] - 104*data[1] + 114*data[2] - 56*data[3] + 11*data[4])/12,
|
||||
last = L<3? undef :
|
||||
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] :
|
||||
(35*data[L-1] - 104*data[L-2] + 114*data[L-3] - 56*data[L-4] + 11*data[L-5])/12
|
||||
|
@ -1203,12 +1194,12 @@ function C_div(z1,z2) =
|
|||
// where a_n is the z^n coefficient. Polynomial coefficients are real.
|
||||
// The result is a number if `z` is a number and a complex number otherwise.
|
||||
function polynomial(p,z,k,total) =
|
||||
is_undef(k)
|
||||
? assert( is_vector(p) , "Input polynomial coefficients must be a vector." )
|
||||
assert( is_finite(z) || is_vector(z,2), "The value of `z` must be a real or a complex number." )
|
||||
polynomial( _poly_trim(p), z, 0, is_num(z) ? 0 : [0,0])
|
||||
: k==len(p) ? total
|
||||
: polynomial(p,z,k+1, is_num(z) ? total*z+p[k] : C_times(total,z)+[p[k],0]);
|
||||
is_undef(k)
|
||||
? assert( is_vector(p) , "Input polynomial coefficients must be a vector." )
|
||||
assert( is_finite(z) || is_vector(z,2), "The value of `z` must be a real or a complex number." )
|
||||
polynomial( _poly_trim(p), z, 0, is_num(z) ? 0 : [0,0])
|
||||
: k==len(p) ? total
|
||||
: polynomial(p,z,k+1, is_num(z) ? total*z+p[k] : C_times(total,z)+[p[k],0]);
|
||||
|
||||
// Function: poly_mult()
|
||||
// Usage:
|
||||
|
@ -1218,13 +1209,22 @@ function polynomial(p,z,k,total) =
|
|||
// Given a list of polynomials represented as real coefficient lists, with the highest degree coefficient first,
|
||||
// computes the coefficient list of the product polynomial.
|
||||
function poly_mult(p,q) =
|
||||
is_undef(q) ?
|
||||
len(p)==2 ? poly_mult(p[0],p[1])
|
||||
: poly_mult(p[0], poly_mult(select(p,1,-1)))
|
||||
:
|
||||
assert( is_vector(p) && is_vector(q),"Invalid arguments to poly_mult")
|
||||
_poly_trim(convolve(p,q));
|
||||
|
||||
is_undef(q) ?
|
||||
assert( is_list(p)
|
||||
&& []==[for(pi=p) if( !is_vector(pi) && pi!=[]) 0],
|
||||
"Invalid arguments to poly_mult")
|
||||
len(p)==2 ? poly_mult(p[0],p[1])
|
||||
: poly_mult(p[0], poly_mult(select(p,1,-1)))
|
||||
:
|
||||
_poly_trim(
|
||||
[
|
||||
for(n = [len(p)+len(q)-2:-1:0])
|
||||
sum( [for(i=[0:1:len(p)-1])
|
||||
let(j = len(p)+len(q)- 2 - n - i)
|
||||
if (j>=0 && j<len(q)) p[i]*q[j]
|
||||
])
|
||||
]);
|
||||
|
||||
|
||||
// Function: poly_div()
|
||||
// Usage:
|
||||
|
|
|
@ -31,9 +31,13 @@ _partition_cutpaths = [
|
|||
|
||||
function _partition_cutpath(l, h, cutsize, cutpath, gap) =
|
||||
let(
|
||||
check = assert(is_finite(l))
|
||||
assert(is_finite(h))
|
||||
assert(is_finite(gap))
|
||||
assert(is_finite(cutsize) || is_vector(cutsize,2))
|
||||
assert(is_string(cutpath) || is_path(cutpath,2)),
|
||||
cutsize = is_vector(cutsize)? cutsize : [cutsize*2, cutsize],
|
||||
cutpath = is_path(cutpath)? cutpath : (
|
||||
assert(is_string(cutpath), "cutpath must be a 2D path or a string.")
|
||||
let(idx = search([cutpath], _partition_cutpaths))
|
||||
idx==[[]]? assert(in_list(cutpath,_partition_cutpaths,idx=0)) :
|
||||
_partition_cutpaths[idx.x][1]
|
||||
|
@ -79,7 +83,7 @@ function _partition_cutpath(l, h, cutsize, cutpath, gap) =
|
|||
// partition_mask(w=20, cutpath="jigsaw");
|
||||
module partition_mask(l=100, w=100, h=100, cutsize=10, cutpath=undef, gap=0, inverse=false, spin=0, orient=UP)
|
||||
{
|
||||
cutsize = is_vector(cutsize)? cutsize : [cutsize*2, cutsize];
|
||||
cutsize = is_vector(cutsize)? point2d(cutsize) : [cutsize*2, cutsize];
|
||||
path = _partition_cutpath(l, h, cutsize, cutpath, gap);
|
||||
fullpath = concat(path, [[l/2,w*(inverse?-1:1)], [-l/2,w*(inverse?-1:1)]]);
|
||||
rot(from=UP,to=orient) {
|
||||
|
|
|
@ -710,7 +710,7 @@ function regular_polyhedron_info(
|
|||
info == "center" ? translation :
|
||||
info == "type" ? entry[class] :
|
||||
info == "name" ? entry[pname] :
|
||||
echo_warning(str("Unknown info type '",info,"' requested"));
|
||||
assert(false, str("Unknown info type '",info,"' requested"));
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -339,7 +339,7 @@ function region_faces(region, transform, reverse=false, vnf=EMPTY_VNF) =
|
|||
// linear_sweep(orgn,height=20,convexity=16) show_anchors();
|
||||
module linear_sweep(region, height=1, center, twist=0, scale=1, slices, maxseg, style="default", convexity, anchor_isect=false, anchor, spin=0, orient=UP) {
|
||||
region = is_path(region)? [region] : region;
|
||||
cp = median(flatten(region));
|
||||
cp = mean(pointlist_bounds(flatten(region)));
|
||||
anchor = get_anchor(anchor, center, "origin", "origin");
|
||||
vnf = linear_sweep(
|
||||
region, height=height,
|
||||
|
|
|
@ -19,7 +19,7 @@ done
|
|||
if [[ "$FILES" != "" ]]; then
|
||||
PREVIEW_LIBS="$FILES"
|
||||
else
|
||||
PREVIEW_LIBS="affine arrays attachments beziers bottlecaps common constants coords cubetruss debug distributors edges errors geometry hingesnaps hull involute_gears joiners knurling linear_bearings masks math metric_screws mutators nema_steppers partitions paths phillips_drive polyhedra primitives quaternions queues regions rounding screws shapes shapes2d skin sliders stacks strings structs threading torx_drive transforms triangulation vectors version vnf walls wiring"
|
||||
PREVIEW_LIBS="affine arrays attachments beziers bottlecaps common constants coords cubetruss debug distributors edges geometry hingesnaps hull involute_gears joiners knurling linear_bearings masks math metric_screws mutators nema_steppers partitions paths phillips_drive polyhedra primitives quaternions queues regions rounding screws shapes shapes2d skin sliders stacks strings structs threading torx_drive transforms triangulation vectors version vnf walls wiring"
|
||||
fi
|
||||
|
||||
dir="$(basename $PWD)"
|
||||
|
|
|
@ -785,7 +785,7 @@ function rect(size=1, center, rounding=0, chamfer=0, anchor, spin=0) =
|
|||
assert(is_num(rounding) || len(rounding)==4)
|
||||
let(
|
||||
size = is_num(size)? [size,size] : point2d(size),
|
||||
anchor = get_anchor(anchor, center, FRONT+LEFT, FRONT+LEFT),
|
||||
anchor = point2d(get_anchor(anchor, center, FRONT+LEFT, FRONT+LEFT)),
|
||||
complex = rounding!=0 || chamfer!=0
|
||||
)
|
||||
(rounding==0 && chamfer==0)? let(
|
||||
|
|
|
@ -1202,7 +1202,7 @@ function path_sweep(shape, path, method="incremental", normal, closed=false, twi
|
|||
let (pathnormal = path_normals(path, tangents, closed))
|
||||
assert(all_defined(pathnormal),"Natural normal vanishes on your curve, select a different method")
|
||||
let( testnormals = [for(i=[0:len(pathnormal)-1-(closed?1:2)]) pathnormal[i]*select(pathnormal,i+2)],
|
||||
dummy = min(testnormals) < .5 ? echo_warning("abrupt change in normal direction. Consider a different method") :0
|
||||
dummy = min(testnormals) < .5 ? echo("WARNING: ***** Abrupt change in normal direction. Consider a different method *****") :0
|
||||
)
|
||||
[for(i=[0:L-(closed?0:1)]) let(
|
||||
rotation = affine_frame_map(x=pathnormal[i%L], z=tangents[i%L])
|
||||
|
@ -1216,7 +1216,7 @@ function path_sweep(shape, path, method="incremental", normal, closed=false, twi
|
|||
end = reindex_polygon(start, apply(transform_list[L],path3d(shape)))
|
||||
)
|
||||
all([for(i=idx(start)) approx(start[i],end[i])]),
|
||||
dummy = ends_match ? 0 :echo_warning("The points do not match when closing the model")
|
||||
dummy = ends_match ? 0 : echo("WARNING: ***** The points do not match when closing the model *****")
|
||||
)
|
||||
transforms ? transform_list : sweep(shape, transform_list, closed=false, caps=fullcaps);
|
||||
|
||||
|
|
1
std.scad
1
std.scad
|
@ -14,7 +14,6 @@ include <version.scad>
|
|||
include <constants.scad>
|
||||
include <edges.scad>
|
||||
include <common.scad>
|
||||
include <errors.scad>
|
||||
include <arrays.scad>
|
||||
include <strings.scad>
|
||||
include <vnf.scad>
|
||||
|
|
|
@ -350,6 +350,7 @@ test_add_scalar();
|
|||
module test_subindex() {
|
||||
v = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]];
|
||||
assert(subindex(v,2) == [3, 7, 11, 15]);
|
||||
assert(subindex(v,[2]) == [[3], [7], [11], [15]]);
|
||||
assert(subindex(v,[2,1]) == [[3, 2], [7, 6], [11, 10], [15, 14]]);
|
||||
assert(subindex(v,[1:3]) == [[2, 3, 4], [6, 7, 8], [10, 11, 12], [14, 15, 16]]);
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
include <../std.scad>
|
||||
|
||||
|
||||
// Can't test echo output as yet. Include these for coverage calculations.
|
||||
module test_echo_error() {}
|
||||
module test_echo_warning() {}
|
||||
module test_deprecate() {}
|
||||
module test_deprecate_argument() {}
|
||||
|
||||
|
||||
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
|
@ -391,11 +391,13 @@ module test_mean() {
|
|||
}
|
||||
test_mean();
|
||||
|
||||
/*
|
||||
module test_median() {
|
||||
assert_equal(median([2,3,7]), 4.5);
|
||||
assert_equal(median([[1,2,3], [3,4,5], [8,9,10]]), [4.5,5.5,6.5]);
|
||||
}
|
||||
test_median();
|
||||
*/
|
||||
|
||||
|
||||
module test_convolve() {
|
||||
|
|
|
@ -558,12 +558,12 @@ function scale(v=1, p=undef) =
|
|||
len(v)==2? affine2d_scale(v) : affine3d_scale(point3d(v))
|
||||
) : (
|
||||
assert(is_list(p))
|
||||
is_num(p.x)? vmul(p,v) :
|
||||
is_vector(p)? ( len(p)==2? vmul(p,point2d(v)) : vmul(p,point3d(v,1)) ) :
|
||||
is_vnf(p)? let(inv=product([for (x=v) x<0? -1 : 1])) [
|
||||
scale(v=v,p=p.x),
|
||||
inv>=0? p.y : [for (l=p.y) reverse(l)]
|
||||
scale(v=v, p=p[0]),
|
||||
inv>=0? p[1] : [for (l=p[1]) reverse(l)]
|
||||
] :
|
||||
[for (l=p) is_vector(l)? vmul(l,v) : scale(v=v, p=l)]
|
||||
[ for (pp=p) scale(v=v, p=pp) ]
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -64,13 +64,10 @@ function vang(v) =
|
|||
// Example:
|
||||
// vmul([3,4,5], [8,7,6]); // Returns [24, 28, 30]
|
||||
function vmul(v1, v2) =
|
||||
// this thighter check can be done yet because it would break other codes in the library
|
||||
// assert( is_vector(v1) && is_vector(v2,len(v1)), "Incompatible vectors")
|
||||
assert( is_vector(v1) && is_vector(v2), "Invalid vector(s)")
|
||||
assert( is_vector(v1) && is_vector(v2,len(v1)), "Incompatible vectors")
|
||||
[for (i = [0:1:len(v1)-1]) v1[i]*v2[i]];
|
||||
|
||||
|
||||
|
||||
// Function: vdiv()
|
||||
// Description:
|
||||
// Element-wise vector division. Divides each element of vector `v1` by
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
BOSL_VERSION = [2,0,401];
|
||||
BOSL_VERSION = [2,0,402];
|
||||
|
||||
|
||||
// Section: BOSL Library Version Functions
|
||||
|
|
Loading…
Reference in a new issue