mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-28 15:59:45 +00:00
Added 3 examples to roundcorners.
Added doc text for list_increasing and list_decreasing. Added str_match, str_matches, starts_width, ends_width. Fixed substr to use tail recursion.
This commit is contained in:
parent
2886cd907b
commit
60be226e85
3 changed files with 150 additions and 8 deletions
10
arrays.scad
10
arrays.scad
|
@ -240,12 +240,18 @@ function list_insert(list, pos, elements) =
|
|||
);
|
||||
|
||||
|
||||
// True if the list is (non-strictly) increasing
|
||||
// Function: list_increasing()
|
||||
// Usage:
|
||||
// list_increasing(list)
|
||||
// Description: returns true if the list is (non-strictly) increasing
|
||||
function list_increasing(list,ind=0) = ind < len(list)-1 && list[ind]<=list[ind+1] ? list_increasing(list,ind+1) :
|
||||
(ind>=len(list)-1 ? true : false);
|
||||
|
||||
|
||||
// True if the list is (non-strictly) decreasing
|
||||
// Function: list_decreasing()
|
||||
// Usage:
|
||||
// list_increasing(list)
|
||||
// Description: returns true if the list is (non-strictly) decreasing
|
||||
function list_decreasing(list,ind=0) = ind < len(list)-1 && list[ind]>=list[ind+1] ? list_increasing(list,ind+1) :
|
||||
(ind>=len(list)-1 ? true : false);
|
||||
|
||||
|
|
|
@ -121,7 +121,43 @@ include <BOSL2/beziers.scad>
|
|||
// translate([0,60,0])polygon(round_corners([[0,0],[50,0],[50,50],[0,50]],all=[5,.7],
|
||||
// curve="smooth", type="cut"));
|
||||
// }
|
||||
|
||||
// Example(Med2D): Rounding a path that is not closed in a three different ways.
|
||||
// $fs=.25;
|
||||
// $fa=1;
|
||||
// zigzagx = [-10, 0, 10, 20, 29, 38, 46, 52, 59, 66, 72, 78, 83, 88, 92, 96, 99, 102, 112];
|
||||
// zigzagy = concat([0], flatten(replist([-10,10],8)), [-10,0]);
|
||||
// zig = zip(zigzagx,zigzagy);
|
||||
// stroke(zig,width=1); // Original shape
|
||||
// fwd(20) // Smooth all corners with a cut of 4 and curvature parameter 0.6
|
||||
// stroke(round_corners(zig,all=[4,0.6],closed=false, curve="smooth", type="cut"),width=1);
|
||||
//
|
||||
// fwd(40) // Smooth all corners with circular arcs and a cut of 4
|
||||
// stroke(round_corners(zig,all=[4,0.6],closed=false, curve="circle", type="cut"),width=1);
|
||||
// // Smooth all corners with a circular arc and radius 1.5 (close to maximum possible)
|
||||
// fwd(60) // Note how the different points are cut back by different amounts
|
||||
// stroke(round_corners(zig,all=1.5,closed=false, curve="circle", type="radius"),width=1);
|
||||
// Example(spin): Rounding some random 3d paths
|
||||
// $fn=36;
|
||||
// list1= [[2.88736, 4.03497, 6.37209], [5.68221, 9.37103, 0.783548], [7.80846, 4.39414, 1.84377],
|
||||
// [0.941085, 5.30548, 4.46753], [1.86054, 9.81574, 6.49753], [6.93818, 7.21163, 5.79453]];
|
||||
// list2= [[1.07907, 4.74091, 6.90039], [8.77585, 4.42248, 6.65185], [5.94714, 9.17137, 6.15642],
|
||||
// [0.66266, 6.9563, 5.88423], [6.56454, 8.86334, 9.95311], [5.42015, 4.91874, 3.86696]];
|
||||
// extrude_2dpath_along_3dpath(regular_ngon(n=36,or=.1),round_corners(list1,closed=false, curve="smooth", type="cut", all=.65));
|
||||
// right(6)
|
||||
// extrude_2dpath_along_3dpath(regular_ngon(n=36,or=.1),round_corners(list2,closed=false, curve="circle", type="cut", all=.75));
|
||||
// Example(spin): Rounding a spiral with increased rounding along the length
|
||||
// $fn=36;
|
||||
// // Construct a square spiral path in 3d
|
||||
// square = [[0,0],[1,0],[1,1],[0,1]];
|
||||
// spiral = flatten(replist(concat(square,reverse(square)),5));
|
||||
// z= list_range(40)*.2+[for(i=[0:9]) each [i,i,i,i]];
|
||||
// // Make rounding parameters, which get larger up the spiral
|
||||
// // and set the smoothing parameter to 1.
|
||||
// rvect = zip([for(i=[0:9]) each [i,i,i,i]]/20,replist(1,40));
|
||||
// rounding = [for(i=rvect) [i]]; // Needed because zip removes a list level
|
||||
// path3d = zip([spiral,z,rounding]);
|
||||
// rpath = round_corners(path3d, curve="smooth", type="joint",closed=false);
|
||||
// extrude_2dpath_along_3dpath( regular_ngon(n=36, or=.1), rpath);
|
||||
function round_corners(path, curve, type, all=undef, closed=true) =
|
||||
let(
|
||||
default_curvature = 0.5, // default curvature for "smooth" curves
|
||||
|
|
110
strings.scad
110
strings.scad
|
@ -15,12 +15,15 @@
|
|||
// substr("abcdefg",2); // Returns "cdefg"
|
||||
// substr("abcdefg",len=3); // Returns "abc"
|
||||
// substr("abcdefg",[2,4]); // Returns "cde"
|
||||
// substr("abcdefg",len=-2)); // Returns ""
|
||||
function substr(str, pos=0, len=undef, substr="") =
|
||||
is_list(pos) ? substr(str, pos[0], pos[1]-pos[0]+1) :
|
||||
// substr("abcdefg",len=-2); // Returns ""
|
||||
function substr(str, pos=0, len=undef) =
|
||||
is_list(pos) ? _substr(str, pos[0], pos[1]-pos[0]+1) :
|
||||
len == undef ? _substr(str, pos, len(str)-pos) :
|
||||
_substr(str,pos,len);
|
||||
|
||||
function _substr(str,pos,len,substr="") =
|
||||
len <= 0 || pos>=len(str) ? substr :
|
||||
len == undef ? substr(str, pos, len(str)-pos, substr) :
|
||||
substr(str, pos+1, len-1, str(substr, str[pos]));
|
||||
_substr(str, pos+1, len-1, str(substr, str[pos]));
|
||||
|
||||
// Function suffix()
|
||||
// Usage:
|
||||
|
@ -198,3 +201,100 @@ function str_split_recurse(str,sep,i,result) =
|
|||
|
||||
function _remove_empty_strs(list) =
|
||||
list_remove(list, search([""], list,0)[0]);
|
||||
|
||||
|
||||
// _str_cmp(str,sindex,pattern)
|
||||
// returns true if the string pattern matches the string
|
||||
// starting at index position sindex in the string.
|
||||
//
|
||||
// This is carefully optimized for speed. Precomputing the length
|
||||
// cuts run time in half when the string is long. Two other string
|
||||
// comparison methods were slower.
|
||||
function _str_cmp(str,sindex,pattern) =
|
||||
len(str)-sindex <len(pattern)? false :
|
||||
_str_cmp_recurse(str,sindex,pattern,len(pattern));
|
||||
|
||||
function _str_cmp_recurse(str,sindex,pattern,plen,pindex=0,) =
|
||||
pindex < plen && pattern[pindex]==str[sindex] ? _str_cmp_recurse(str,sindex+1,pattern,plen,pindex+1): (pindex==plen);
|
||||
|
||||
// Function: str_match()
|
||||
// Usage:
|
||||
// str_match(str,pattern)
|
||||
// Description:
|
||||
// Searches input string `str` for the string `pattern` and returns the index of the first or last match in `str`.
|
||||
// If `pattern` is empty then it returns 0. If `pattern` doesn't match it returns undef.
|
||||
// Arguments:
|
||||
// str = string to search
|
||||
// pattern = string pattern to search for
|
||||
// last = set to true to return the last match. Default: false
|
||||
// Example:
|
||||
// str_match("abc123def123abc","123"); // Returns 3
|
||||
// str_match("abc123def123abc","b"); // Returns 1
|
||||
// str_match("abc123def123abc","1234"); // Returns undef
|
||||
// str_match("abc",""); // Returns 0
|
||||
// str_match("abc123def123abc","123",last=true); // Returns 9
|
||||
// str_match("abc123def123abc","b",last=true); // Returns 13
|
||||
// str_match("abc123def123abc","1234",last=true); // Returns undef
|
||||
// str_match("abc","",last=true); // Returns 2
|
||||
function str_match(str,pattern,last=false) =
|
||||
pattern=="" ? (last?len(str)-1:0) :
|
||||
last ? _str_match_last(str,pattern,len(str)-len(pattern)) :
|
||||
_str_match(str,pattern,len(str)-len(pattern));
|
||||
|
||||
function _str_match(str,pattern,max_sindex,sindex=0) =
|
||||
sindex<=max_sindex && !_str_cmp(str,sindex, pattern) ? _str_match(str,pattern,max_sindex,sindex+1) :
|
||||
(sindex <= max_sindex ? sindex : undef);
|
||||
|
||||
function _str_match_last(str,pattern,sindex) =
|
||||
sindex>=0 && !_str_cmp(str,sindex, pattern) ? _str_match_last(str,pattern,sindex-1) :
|
||||
(sindex >=0 ? sindex : undef);
|
||||
// Function: str_matches()
|
||||
// Usage:
|
||||
// str_matches(str,pattern)
|
||||
// Description:
|
||||
// Returns the indices of all matches where the string `pattern` appears in the input string `str`.
|
||||
// If `pattern` is empty then it matches every character of `str`.
|
||||
// Arguments:
|
||||
// str = string to search
|
||||
// pattern = string pattern to search for
|
||||
// Example:
|
||||
// str_matches("abc123def123abc","123"); // Returns [3,9]
|
||||
// str_matches("abc123def123abc","b"); // Returns [1,13]
|
||||
// str_matches("abc123def123abc","1234"); // Returns []
|
||||
// str_matches("abc",""); // Returns [0,1,2]
|
||||
function str_matches(str,pattern) =
|
||||
pattern == "" ? list_range(len(str)) :
|
||||
[for(i=[0:1:len(str)-len(pattern)]) if (_str_cmp(str,i,pattern)) i];
|
||||
|
||||
|
||||
// Function: starts_with()
|
||||
// Usage:
|
||||
// starts_with(str,pattern)
|
||||
// Description:
|
||||
// Returns true if the input string `str` starts with the specified string pattern, `pattern`.
|
||||
// Otherwise returns false.
|
||||
// Arguments:
|
||||
// str = string to search
|
||||
// pattern = string pattern to search for
|
||||
// Example:
|
||||
// starts_with("abcdef","abc"); // Returns true
|
||||
// starts_with("abcdef","def"); // Returns false
|
||||
// starts_with("abcdef",""); // Returns true
|
||||
function starts_with(str,pattern) = _str_cmp(str,0,pattern);
|
||||
|
||||
|
||||
// Function: ends_with()
|
||||
// Usage:
|
||||
// ends_with(str,pattern)
|
||||
// Description:
|
||||
// Returns true if the input string `str` ends with the specified string pattern, `pattern`.
|
||||
// Otherwise returns false.
|
||||
// Arguments:
|
||||
// str = string to search
|
||||
// pattern = string pattern to search for
|
||||
// Example:
|
||||
// ends_with("abcdef","def"); // Returns true
|
||||
// ends_with("abcdef","de"); // Returns false
|
||||
// ends_with("abcdef",""); // Returns true
|
||||
function ends_with(str,pattern) = _str_cmp(str,len(str)-len(pattern),pattern);
|
||||
|
||||
|
|
Loading…
Reference in a new issue