mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-19 11:21:42 +02:00
move comparison functions out of math.scad and arrays.scad into comparisons.scad
rename arrays.scad to lists.scad
This commit is contained in:
223
math.scad
223
math.scad
@@ -866,158 +866,6 @@ function convolve(p,q) =
|
||||
|
||||
|
||||
|
||||
// Section: Comparisons and Logic
|
||||
|
||||
// Function: all_zero()
|
||||
// Usage:
|
||||
// x = all_zero(x, [eps]);
|
||||
// Description:
|
||||
// Returns true if the finite number passed to it is approximately zero, to within `eps`.
|
||||
// If passed a list, recursively checks if all items in the list are approximately zero.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
// eps = The maximum allowed variance. Default: `EPSILON` (1e-9)
|
||||
// Example:
|
||||
// a = all_zero(0); // Returns: true.
|
||||
// b = all_zero(1e-3); // Returns: false.
|
||||
// c = all_zero([0,0,0]); // Returns: true.
|
||||
// d = all_zero([0,0,1e-3]); // Returns: false.
|
||||
function all_zero(x, eps=EPSILON) =
|
||||
is_finite(x)? approx(x,eps) :
|
||||
is_list(x)? (x != [] && [for (xx=x) if(!all_zero(xx,eps=eps)) 1] == []) :
|
||||
false;
|
||||
|
||||
|
||||
// Function: all_nonzero()
|
||||
// Usage:
|
||||
// test = all_nonzero(x, [eps]);
|
||||
// Description:
|
||||
// Returns true if the finite number passed to it is not almost zero, to within `eps`.
|
||||
// If passed a list, recursively checks if all items in the list are not almost zero.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
// eps = The maximum allowed variance. Default: `EPSILON` (1e-9)
|
||||
// Example:
|
||||
// a = all_nonzero(0); // Returns: false.
|
||||
// b = all_nonzero(1e-3); // Returns: true.
|
||||
// c = all_nonzero([0,0,0]); // Returns: false.
|
||||
// d = all_nonzero([0,0,1e-3]); // Returns: false.
|
||||
// e = all_nonzero([1e-3,1e-3,1e-3]); // Returns: true.
|
||||
function all_nonzero(x, eps=EPSILON) =
|
||||
is_finite(x)? !approx(x,eps) :
|
||||
is_list(x)? (x != [] && [for (xx=x) if(!all_nonzero(xx,eps=eps)) 1] == []) :
|
||||
false;
|
||||
|
||||
|
||||
// Function: all_positive()
|
||||
// Usage:
|
||||
// test = all_positive(x);
|
||||
// Description:
|
||||
// Returns true if the finite number passed to it is greater than zero.
|
||||
// If passed a list, recursively checks if all items in the list are positive.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
// Example:
|
||||
// a = all_positive(-2); // Returns: false.
|
||||
// b = all_positive(0); // Returns: false.
|
||||
// c = all_positive(2); // Returns: true.
|
||||
// d = all_positive([0,0,0]); // Returns: false.
|
||||
// e = all_positive([0,1,2]); // Returns: false.
|
||||
// f = all_positive([3,1,2]); // Returns: true.
|
||||
// g = all_positive([3,-1,2]); // Returns: false.
|
||||
function all_positive(x) =
|
||||
is_num(x)? x>0 :
|
||||
is_list(x)? (x != [] && [for (xx=x) if(!all_positive(xx)) 1] == []) :
|
||||
false;
|
||||
|
||||
|
||||
// Function: all_negative()
|
||||
// Usage:
|
||||
// test = all_negative(x);
|
||||
// Description:
|
||||
// Returns true if the finite number passed to it is less than zero.
|
||||
// If passed a list, recursively checks if all items in the list are negative.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
// Example:
|
||||
// a = all_negative(-2); // Returns: true.
|
||||
// b = all_negative(0); // Returns: false.
|
||||
// c = all_negative(2); // Returns: false.
|
||||
// d = all_negative([0,0,0]); // Returns: false.
|
||||
// e = all_negative([0,1,2]); // Returns: false.
|
||||
// f = all_negative([3,1,2]); // Returns: false.
|
||||
// g = all_negative([3,-1,2]); // Returns: false.
|
||||
// h = all_negative([-3,-1,-2]); // Returns: true.
|
||||
function all_negative(x) =
|
||||
is_num(x)? x<0 :
|
||||
is_list(x)? (x != [] && [for (xx=x) if(!all_negative(xx)) 1] == []) :
|
||||
false;
|
||||
|
||||
|
||||
// Function: all_nonpositive()
|
||||
// Usage:
|
||||
// all_nonpositive(x);
|
||||
// Description:
|
||||
// Returns true if the finite number passed to it is less than or equal to zero.
|
||||
// If passed a list, recursively checks if all items in the list are nonpositive.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
// Example:
|
||||
// a = all_nonpositive(-2); // Returns: true.
|
||||
// b = all_nonpositive(0); // Returns: true.
|
||||
// c = all_nonpositive(2); // Returns: false.
|
||||
// d = all_nonpositive([0,0,0]); // Returns: true.
|
||||
// e = all_nonpositive([0,1,2]); // Returns: false.
|
||||
// f = all_nonpositive([3,1,2]); // Returns: false.
|
||||
// g = all_nonpositive([3,-1,2]); // Returns: false.
|
||||
// h = all_nonpositive([-3,-1,-2]); // Returns: true.
|
||||
function all_nonpositive(x) =
|
||||
is_num(x)? x<=0 :
|
||||
is_list(x)? (x != [] && [for (xx=x) if(!all_nonpositive(xx)) 1] == []) :
|
||||
false;
|
||||
|
||||
|
||||
// Function: all_nonnegative()
|
||||
// Usage:
|
||||
// all_nonnegative(x);
|
||||
// Description:
|
||||
// Returns true if the finite number passed to it is greater than or equal to zero.
|
||||
// If passed a list, recursively checks if all items in the list are nonnegative.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
// Example:
|
||||
// a = all_nonnegative(-2); // Returns: false.
|
||||
// b = all_nonnegative(0); // Returns: true.
|
||||
// c = all_nonnegative(2); // Returns: true.
|
||||
// d = all_nonnegative([0,0,0]); // Returns: true.
|
||||
// e = all_nonnegative([0,1,2]); // Returns: true.
|
||||
// f = all_nonnegative([0,-1,-2]); // Returns: false.
|
||||
// g = all_nonnegative([3,1,2]); // Returns: true.
|
||||
// h = all_nonnegative([3,-1,2]); // Returns: false.
|
||||
// i = all_nonnegative([-3,-1,-2]); // Returns: false.
|
||||
function all_nonnegative(x) =
|
||||
is_num(x)? x>=0 :
|
||||
is_list(x)? (x != [] && [for (xx=x) if(!all_nonnegative(xx)) 1] == []) :
|
||||
false;
|
||||
|
||||
|
||||
// Function all_equal()
|
||||
// Usage:
|
||||
// b = all_equal(vec, [eps]);
|
||||
// Description:
|
||||
// Returns true if all of the entries in vec are equal to each other, or approximately equal to each other if eps is set.
|
||||
// Arguments:
|
||||
// vec = vector to check
|
||||
// eps = Set to tolerance for approximate equality. Default: 0
|
||||
function all_equal(vec,eps=0) =
|
||||
eps==0 ? [for(v=vec) if (v!=vec[0]) v] == []
|
||||
: [for(v=vec) if (!approx(v,vec[0])) v] == [];
|
||||
|
||||
|
||||
// Function: all_integer()
|
||||
@@ -1044,76 +892,6 @@ function all_integer(x) =
|
||||
false;
|
||||
|
||||
|
||||
// Function: approx()
|
||||
// Usage:
|
||||
// test = approx(a, b, [eps])
|
||||
// Description:
|
||||
// Compares two numbers or vectors, and returns true if they are closer than `eps` to each other.
|
||||
// Arguments:
|
||||
// a = First value.
|
||||
// b = Second value.
|
||||
// eps = The maximum allowed difference between `a` and `b` that will return true.
|
||||
// Example:
|
||||
// test1 = approx(-0.3333333333,-1/3); // Returns: true
|
||||
// test2 = approx(0.3333333333,1/3); // Returns: true
|
||||
// test3 = approx(0.3333,1/3); // Returns: false
|
||||
// test4 = approx(0.3333,1/3,eps=1e-3); // Returns: true
|
||||
// test5 = approx(PI,3.1415926536); // Returns: true
|
||||
function approx(a,b,eps=EPSILON) =
|
||||
(a==b && is_bool(a) == is_bool(b)) ||
|
||||
(is_num(a) && is_num(b) && abs(a-b) <= eps) ||
|
||||
(is_list(a) && is_list(b) && len(a) == len(b) && [] == [for (i=idx(a)) if (!approx(a[i],b[i],eps=eps)) 1]);
|
||||
|
||||
|
||||
function _type_num(x) =
|
||||
is_undef(x)? 0 :
|
||||
is_bool(x)? 1 :
|
||||
is_num(x)? 2 :
|
||||
is_nan(x)? 3 :
|
||||
is_string(x)? 4 :
|
||||
is_list(x)? 5 : 6;
|
||||
|
||||
|
||||
// Function: compare_vals()
|
||||
// Usage:
|
||||
// test = compare_vals(a, b);
|
||||
// Description:
|
||||
// Compares two values. Lists are compared recursively.
|
||||
// Returns <0 if a<b. Returns >0 if a>b. Returns 0 if a==b.
|
||||
// If types are not the same, then undef < bool < nan < num < str < list < range.
|
||||
// Arguments:
|
||||
// a = First value to compare.
|
||||
// b = Second value to compare.
|
||||
function compare_vals(a, b) =
|
||||
(a==b)? 0 :
|
||||
let(t1=_type_num(a), t2=_type_num(b)) (t1!=t2)? (t1-t2) :
|
||||
is_list(a)? compare_lists(a,b) :
|
||||
is_nan(a)? 0 :
|
||||
(a<b)? -1 : (a>b)? 1 : 0;
|
||||
|
||||
|
||||
// Function: compare_lists()
|
||||
// Usage:
|
||||
// test = compare_lists(a, b)
|
||||
// Description:
|
||||
// Compare contents of two lists using `compare_vals()`.
|
||||
// Returns <0 if `a`<`b`.
|
||||
// Returns 0 if `a`==`b`.
|
||||
// Returns >0 if `a`>`b`.
|
||||
// Arguments:
|
||||
// a = First list to compare.
|
||||
// b = Second list to compare.
|
||||
function compare_lists(a, b) =
|
||||
a==b? 0 :
|
||||
let(
|
||||
cmps = [
|
||||
for (i = [0:1:min(len(a),len(b))-1])
|
||||
let( cmp = compare_vals(a[i],b[i]) )
|
||||
if (cmp!=0) cmp
|
||||
]
|
||||
)
|
||||
cmps==[]? (len(a)-len(b)) : cmps[0];
|
||||
|
||||
|
||||
// Function: any()
|
||||
// Usage:
|
||||
@@ -1230,7 +1008,6 @@ function _count_true_bool(l, nmax, i=0, out=0) =
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Section: Calculus
|
||||
|
||||
// Function: deriv()
|
||||
|
Reference in New Issue
Block a user