mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
commit
34873b2915
16 changed files with 956 additions and 882 deletions
|
@ -19,7 +19,7 @@ include <rounding.scad>
|
|||
|
||||
// Module: pco1810_neck()
|
||||
// Usage:
|
||||
// pco1810_neck([wall])
|
||||
// pco1810_neck([wall]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates an approximation of a standard PCO-1810 threaded beverage bottle neck.
|
||||
// Arguments:
|
||||
|
@ -140,7 +140,7 @@ function pco1810_neck(wall=2, anchor="support-ring", spin=0, orient=UP) =
|
|||
|
||||
// Module: pco1810_cap()
|
||||
// Usage:
|
||||
// pco1810_cap([wall], [texture]);
|
||||
// pco1810_cap([wall], [texture]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a basic cap for a PCO1810 threaded beverage bottle.
|
||||
// Arguments:
|
||||
|
@ -211,7 +211,7 @@ function pco1810_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP) =
|
|||
|
||||
// Module: pco1881_neck()
|
||||
// Usage:
|
||||
// pco1881_neck([wall])
|
||||
// pco1881_neck([wall]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates an approximation of a standard PCO-1881 threaded beverage bottle neck.
|
||||
// Arguments:
|
||||
|
@ -332,12 +332,13 @@ function pco1881_neck(wall=2, anchor="support-ring", spin=0, orient=UP) =
|
|||
|
||||
// Module: pco1881_cap()
|
||||
// Usage:
|
||||
// pco1881_cap(wall, [texture]);
|
||||
// pco1881_cap(wall, [texture]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a basic cap for a PCO1881 threaded beverage bottle.
|
||||
// Arguments:
|
||||
// wall = Wall thickness in mm.
|
||||
// texture = The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none"
|
||||
// ---
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -394,11 +395,12 @@ function pco1881_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP) =
|
|||
|
||||
// Module: generic_bottle_neck()
|
||||
// Usage:
|
||||
// generic_bottle_neck([wall], ...)
|
||||
// generic_bottle_neck([wall], ...) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a bottle neck given specifications.
|
||||
// Arguments:
|
||||
// wall = distance between ID and any wall that may be below the support
|
||||
// ---
|
||||
// neck_d = Outer diameter of neck without threads
|
||||
// id = Inner diameter of neck
|
||||
// thread_od = Outer diameter of thread
|
||||
|
@ -406,7 +408,6 @@ function pco1881_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP) =
|
|||
// support_d = Outer diameter of support ring. Set to 0 for no support.
|
||||
// pitch = Thread pitch
|
||||
// round_supp = True to round the lower edge of the support ring
|
||||
// ---
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -519,7 +520,7 @@ function generic_bottle_neck(
|
|||
|
||||
// Module: generic_bottle_cap()
|
||||
// Usage:
|
||||
// generic_bottle_cap(wall, [texture], ...);
|
||||
// generic_bottle_cap(wall, [texture], ...) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a basic threaded cap given specifications.
|
||||
// Arguments:
|
||||
|
@ -608,7 +609,7 @@ function generic_bottle_cap(
|
|||
|
||||
// Module: bottle_adapter_neck_to_cap()
|
||||
// Usage:
|
||||
// bottle_adapter_neck_to_cap(wall, [texture]);
|
||||
// bottle_adapter_neck_to_cap(wall, [texture], ...) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a threaded neck to cap adapter
|
||||
// Arguments:
|
||||
|
@ -834,10 +835,11 @@ function bottle_adapter_cap_to_cap(
|
|||
|
||||
// Module: bottle_adapter_neck_to_neck()
|
||||
// Usage:
|
||||
// bottle_adapter_neck_to_neck();
|
||||
// bottle_adapter_neck_to_neck(...);
|
||||
// Description:
|
||||
// Creates a threaded neck to neck adapter.
|
||||
// Arguments:
|
||||
// ---
|
||||
// d = Distance between bottoms of necks
|
||||
// neck_od1 = Outer diameter of top neck w/o threads
|
||||
// neck_id1 = Inner diameter of top neck
|
||||
|
@ -868,6 +870,7 @@ module bottle_adapter_neck_to_neck(
|
|||
support_od2, pitch2,
|
||||
taper_lead_in = 0, wall
|
||||
) {
|
||||
no_children($children);
|
||||
neck_od2 = (neck_od2 == undef) ? neck_od1 : neck_od2;
|
||||
neck_id2 = (neck_id2 == undef) ? neck_id1 : neck_id2;
|
||||
thread_od2 = (thread_od2 == undef) ? thread_od1 : thread_od2;
|
||||
|
@ -956,7 +959,7 @@ function bottle_adapter_neck_to_neck(
|
|||
|
||||
// Module: sp_neck()
|
||||
// Usage:
|
||||
// sp_neck(diam, type, wall|id, [style], [bead], [anchor], [spin], [orient])
|
||||
// sp_neck(diam, type, wall|id=, [style=], [bead=]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Make a SPI (Society of Plastics Industry) threaded bottle neck. You must
|
||||
// supply the nominal outer diameter of the threads and the thread type, one of
|
||||
|
@ -1150,6 +1153,9 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
|
|||
// true_diam = sp_diameter(diam,type)
|
||||
// Description:
|
||||
// Returns the actual base diameter (root of the threads) for a SPI plastic bottle neck given the nominal diameter and type number (400, 410, 415).
|
||||
// Arguments:
|
||||
// diam = nominal diameter
|
||||
// type = closure type number (400, 410 or 415)
|
||||
function sp_diameter(diam,type) =
|
||||
let(
|
||||
table = struct_val(_sp_specs,type)
|
||||
|
|
|
@ -47,8 +47,8 @@ function approx(a,b,eps=EPSILON) =
|
|||
// 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 returns true if all its entries are approximately zero.
|
||||
// Returns true if its argument is approximately zero, to within `eps`.
|
||||
// If passed a list returns true if all its entries are approximately equal to zero.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
|
@ -67,8 +67,8 @@ function all_zero(x, eps=EPSILON) =
|
|||
// Usage:
|
||||
// test = all_nonzero(x, [eps]);
|
||||
// Description:
|
||||
// Returns true if the finite number passed to it is different from zero by `eps`.
|
||||
// If passed a list returns true if all the entries of the list are different from zero by `eps`.
|
||||
// Returns true if its argument is finite and different from zero by `eps`.
|
||||
// If passed a list returns true if all the entries of the list are finite numbers that are different from zero by `eps`.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
|
@ -88,8 +88,8 @@ function all_nonzero(x, eps=EPSILON) =
|
|||
// Usage:
|
||||
// test = all_positive(x,[eps]);
|
||||
// Description:
|
||||
// Returns true if the finite number passed to it is greater than zero.
|
||||
// If passed a list returns true if all the entries are positive.
|
||||
// Returns true if the argument is finite and greater than zero, within epsilon tolerance if desired.
|
||||
// If passed a list returns true if all the entries are finite positive numbers.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
|
@ -103,7 +103,7 @@ function all_nonzero(x, eps=EPSILON) =
|
|||
// f = all_positive([3,1,2]); // Returns: true.
|
||||
// g = all_positive([3,-1,2]); // Returns: false.
|
||||
function all_positive(x,eps=0) =
|
||||
is_num(x)? x>eps :
|
||||
is_finite(x)? x>eps :
|
||||
is_vector(x) && [for (xx=x) if(xx<=0) 1] == [];
|
||||
|
||||
|
||||
|
@ -111,8 +111,8 @@ function all_positive(x,eps=0) =
|
|||
// Usage:
|
||||
// test = all_negative(x, [eps]);
|
||||
// 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.
|
||||
// Returns true if the argument is finite and less than zero, within epsilon tolerance if desired.
|
||||
// If passed a list, returns true if all the elements are finite negative numbers.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
|
@ -127,7 +127,7 @@ function all_positive(x,eps=0) =
|
|||
// g = all_negative([3,-1,2]); // Returns: false.
|
||||
// h = all_negative([-3,-1,-2]); // Returns: true.
|
||||
function all_negative(x, eps=0) =
|
||||
is_num(x)? x<-eps :
|
||||
is_finite(x)? x<-eps :
|
||||
is_vector(x) && [for (xx=x) if(xx>=-eps) 1] == [];
|
||||
|
||||
|
||||
|
@ -135,8 +135,8 @@ function all_negative(x, eps=0) =
|
|||
// Usage:
|
||||
// all_nonpositive(x, [eps]);
|
||||
// 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.
|
||||
// Returns true if its argument is finite and less than or equal to zero.
|
||||
// If passed a list, returns true if all the elements are finite non-positive numbers.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
|
@ -160,7 +160,7 @@ function all_nonpositive(x,eps=0) =
|
|||
// all_nonnegative(x, [eps]);
|
||||
// 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.
|
||||
// If passed a list, returns true if all the elements are finite non-negative numbers.
|
||||
// Otherwise, returns false.
|
||||
// Arguments:
|
||||
// x = The value to check.
|
||||
|
@ -196,7 +196,7 @@ function all_equal(vec,eps=0) =
|
|||
|
||||
// Function: is_increasing()
|
||||
// Usage:
|
||||
// bool = is_increasing(list);
|
||||
// bool = is_increasing(list, [strict]);
|
||||
// Topics: List Handling
|
||||
// See Also: max_index(), min_index(), is_decreasing()
|
||||
// Description:
|
||||
|
@ -205,7 +205,7 @@ function all_equal(vec,eps=0) =
|
|||
// evaluated character by character.
|
||||
// Arguments:
|
||||
// list = list (or string) to check
|
||||
// strict = set to true to test that list is strictly increasing
|
||||
// strict = set to true to test that list is strictly increasing. Default: false
|
||||
// Example:
|
||||
// a = is_increasing([1,2,3,4]); // Returns: true
|
||||
// b = is_increasing([1,3,2,4]); // Returns: false
|
||||
|
@ -220,7 +220,7 @@ function is_increasing(list,strict=false) =
|
|||
|
||||
// Function: is_decreasing()
|
||||
// Usage:
|
||||
// bool = is_decreasing(list);
|
||||
// bool = is_decreasing(list, [strict]);
|
||||
// Topics: List Handling
|
||||
// See Also: max_index(), min_index(), is_increasing()
|
||||
// Description:
|
||||
|
@ -229,7 +229,7 @@ function is_increasing(list,strict=false) =
|
|||
// evaluated character by character.
|
||||
// Arguments:
|
||||
// list = list (or string) to check
|
||||
// strict = set to true to test that list is strictly decreasing
|
||||
// strict = set to true to test that list is strictly decreasing. Default: false
|
||||
// Example:
|
||||
// a = is_decreasing([1,2,3,4]); // Returns: false
|
||||
// b = is_decreasing([4,2,3,1]); // Returns: false
|
||||
|
@ -256,7 +256,7 @@ function _type_num(x) =
|
|||
// 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.
|
||||
// Returns a negative value if a<b. Returns a positive value 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.
|
||||
|
@ -274,9 +274,9 @@ function compare_vals(a, b) =
|
|||
// test = compare_lists(a, b)
|
||||
// Description:
|
||||
// Compare contents of two lists using `compare_vals()`.
|
||||
// Returns <0 if `a`<`b`.
|
||||
// Returns a negative number if `a`<`b`.
|
||||
// Returns 0 if `a`==`b`.
|
||||
// Returns >0 if `a`>`b`.
|
||||
// Returns a positive number if `a`>`b`.
|
||||
// Arguments:
|
||||
// a = First list to compare.
|
||||
// b = Second list to compare.
|
||||
|
@ -312,7 +312,7 @@ function compare_lists(a, b) =
|
|||
// a = min_index([5,3,9,6,2,7,8,2,1]); // Returns: 8
|
||||
// b = min_index([5,3,9,6,2,7,8,2,7],all=true); // Returns: [4,7]
|
||||
function min_index(vals, all=false) =
|
||||
assert( is_vector(vals) && len(vals)>0 , "Invalid or empty list of numbers.")
|
||||
assert( is_vector(vals), "Invalid or list of numbers.")
|
||||
all ? search(min(vals),vals,0) : search(min(vals), vals)[0];
|
||||
|
||||
|
||||
|
@ -336,11 +336,6 @@ function max_index(vals, all=false) =
|
|||
all ? search(max(vals),vals,0) : search(max(vals), vals)[0];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Section: Dealing with duplicate list entries
|
||||
|
||||
|
||||
|
@ -351,14 +346,20 @@ function max_index(vals, all=false) =
|
|||
// idx = find_approx(val, list, [start=], [eps=]);
|
||||
// indices = find_approx(val, list, all=true, [start=], [eps=]);
|
||||
// Description:
|
||||
// Finds the first item in `list` that matches `val`, returning the index. Returns `undef` if there is no match.
|
||||
// Finds the first item in `list` that matches `val` to within `eps` tolerance, returning the index. Returns `undef` if there is no match.
|
||||
// If `all=true` then returns all the items that agree within `eps` and returns the empty list if no such items exist.
|
||||
// Arguments:
|
||||
// val = The value to search for.
|
||||
// list = The list to search through.
|
||||
// list = The list to search.
|
||||
// ---
|
||||
// start = The index to start searching from. Default: 0
|
||||
// all = If true, returns a list of all matching item indices.
|
||||
// eps = The maximum allowed floating point rounding error for numeric comparisons.
|
||||
// all = If true, returns a list of all matching item indices. Default: false
|
||||
// eps = The maximum allowed floating point rounding error for numeric comparisons. Default: EPSILON (1e-9)
|
||||
// Example:
|
||||
// find_approx(3,[4,5,3.01,2,2.99], eps=0.1); // Returns 2
|
||||
// find_approx(9,[4,5,3.01,2,2.99], eps=0.1); // Returns undef
|
||||
// find_approx(3,[4,5,3.01,2,2.99], all=true, eps=0.1); // Returns [2,4]
|
||||
// find_approx(9,[4,5,3.01,2,2.99], all=true, eps=0.1); // Returns []
|
||||
function find_approx(val, list, start=0, all=false, eps=EPSILON) =
|
||||
all ? [for (i=[start:1:len(list)-1]) if (approx(val, list[i], eps=eps)) i]
|
||||
: __find_approx(val, list, eps=eps, i=start);
|
||||
|
@ -373,7 +374,7 @@ function __find_approx(val, list, eps, i=0) =
|
|||
|
||||
// Function: deduplicate()
|
||||
// Usage:
|
||||
// list = deduplicate(list, [close], [eps]);
|
||||
// list = deduplicate(list, [closed], [eps]);
|
||||
// Topics: List Handling
|
||||
// See Also: deduplicate_indexed()
|
||||
// Description:
|
||||
|
@ -459,7 +460,7 @@ function deduplicate_indexed(list, indices, closed=false, eps=EPSILON) =
|
|||
// Given a string or a list returns the sorted string or the sorted list with all repeated items removed.
|
||||
// The sorting order of non homogeneous lists is the function `sort` order.
|
||||
// Arguments:
|
||||
// list = The list to uniquify.
|
||||
// list = The list to process.
|
||||
// Example:
|
||||
// sorted = unique([5,2,8,3,1,3,8,7,5]); // Returns: [1,2,3,5,7,8]
|
||||
// sorted = unique("axdbxxc"); // Returns: "abcdx"
|
||||
|
@ -494,7 +495,7 @@ function _unique_sort(l) =
|
|||
|
||||
// Function: unique_count()
|
||||
// Usage:
|
||||
// counts = unique_count(list);
|
||||
// sorted_counts = unique_count(list);
|
||||
// Topics: List Handling
|
||||
// See Also: shuffle(), sort(), sortidx(), unique()
|
||||
// Description:
|
||||
|
@ -724,7 +725,7 @@ function sort(list, idx=undef) =
|
|||
// idxs2 = sortidx(lst, idx=0); // Returns: [1,2,0,3]
|
||||
// idxs3 = sortidx(lst, idx=[1,3]); // Returns: [3,0,2,1]
|
||||
function sortidx(list, idx=undef) =
|
||||
assert(is_list(list)||is_string(list), "Invalid input." )
|
||||
assert(is_list(list)||is_string(list), "Invalid list." )
|
||||
!is_list(list) || len(list)<=1 ? list :
|
||||
is_homogeneous(list,1)
|
||||
? let(
|
||||
|
@ -751,26 +752,31 @@ function sortidx(list, idx=undef) =
|
|||
|
||||
// Function: group_sort()
|
||||
// Usage:
|
||||
// ulist = group_sort(list);
|
||||
// ulist = group_sort(list,[idx]);
|
||||
// Topics: List Handling
|
||||
// See Also: shuffle(), sort(), sortidx(), unique(), unique_count()
|
||||
// Description:
|
||||
// Given a list of values, returns the sorted list with all repeated items grouped in a list.
|
||||
// When the list entries are themselves lists, the sorting may be done based on the `idx` entry
|
||||
// of those entries, that should be numbers.
|
||||
// The result is always a list of lists.
|
||||
// Given a list of numbers, sorts the list into a sequence of lists, where each list contains any repeated values.
|
||||
// If there are no repeated values the output will be a list of singleton lists.
|
||||
// If you apply {{flatten()}} to the output, the result will be a simple sorted list.
|
||||
// .
|
||||
// When the input is a list of lists, the sorting is done based on index `idx` of the entries in `list`.
|
||||
// In this case, `list[i][idx]` must be a number for every `i`, and the entries in `list` are grouped
|
||||
// together in the output if they match at index `idx`. This function can be used to group together
|
||||
// items that are tagged with the same index.
|
||||
// Arguments:
|
||||
// list = The list to sort.
|
||||
// idx = If given, do the comparison based just on the specified index. Default: zero.
|
||||
// idx = If input is a list of lists, index to sort on. Default: 0.
|
||||
// Example:
|
||||
// sorted = group_sort([5,2,8,3,1,3,8,7,5]); // Returns: [[1],[2],[3,3],[5,5],[7],[8,8]]
|
||||
// sorted2 = group_sort([[5,"a"],[2,"b"], [5,"c"], [3,"d"], [2,"e"] ], idx=0); // Returns: [[[2,"b"],[2,"e"]], [[5,"a"],[5,"c"]], [[3,"d"]] ]
|
||||
// // Next example returns: [ [[2,"b"],[2,"e"]], [[3,"d"]], [[5,"a"],[5,"c"]] ]
|
||||
// sorted2 = group_sort([[5,"a"],[2,"b"], [5,"c"], [3,"d"], [2,"e"] ], idx=0);
|
||||
function group_sort(list, idx) =
|
||||
assert(is_list(list), "Input should be a list." )
|
||||
assert(is_undef(idx) || (is_finite(idx) && idx>=0) , "Invalid index." )
|
||||
assert(is_undef(idx) || (is_int(idx) && idx>=0) , "Invalid index." )
|
||||
len(list)<=1 ? [list] :
|
||||
is_vector(list)? _group_sort(list) :
|
||||
let( idx = is_undef(idx) ? 0 : idx )
|
||||
is_vector(list)? assert(is_undef(idx),"Cannot give idx with a vector input") _group_sort(list) :
|
||||
let( idx = default(idx,0) )
|
||||
assert( [for(entry=list) if(!is_list(entry) || len(entry)<idx || !is_num(entry[idx]) ) 1]==[],
|
||||
"Some entry of the list is a list shorter than `idx` or the indexed entry of it is not a number.")
|
||||
_group_sort_by_index(list,idx);
|
||||
|
@ -827,7 +833,7 @@ function group_data(groups, values) =
|
|||
// k = number of items to return
|
||||
function list_smallest(list, k) =
|
||||
assert(is_list(list))
|
||||
assert(is_finite(k) && k>=0, "k must be nonnegative")
|
||||
assert(is_int(k) && k>=0, "k must be nonnegative")
|
||||
let(
|
||||
v = list[rand_int(0,len(list)-1,1)[0]],
|
||||
smaller = [for(li=list) if(li<v) li ],
|
||||
|
|
23
gears.scad
23
gears.scad
|
@ -28,8 +28,8 @@
|
|||
|
||||
// Function&Module: spur_gear()
|
||||
// Usage: As a Module
|
||||
// spur_gear(pitch, teeth, thickness, [shaft_diam=], [hide], [pressure_angle], [clearance], [backlash], [helical], [slices], [interior]);
|
||||
// spur_gear(mod=, teeth=, thickness=, [shaft_diam=], ...);
|
||||
// spur_gear(pitch, teeth, thickness, [shaft_diam], [hide=], [pressure_angle=], [clearance=], [backlash=], [helical=], [slices=], [interior=]) [ATTACHMENTS];
|
||||
// spur_gear(mod=, teeth=, thickness=, [shaft_diam=], ...) [ATTACHMENTS];
|
||||
// Usage: As a Function
|
||||
// vnf = spur_gear(pitch, teeth, thickness, [shaft_diam], ...);
|
||||
// vnf = spur_gear(mod=, teeth=, thickness=, [shaft_diam], ...);
|
||||
|
@ -193,9 +193,11 @@ module spur_gear(
|
|||
|
||||
// Function&Module: spur_gear2d()
|
||||
// Usage: As Module
|
||||
// spur_gear2d(pitch|mod, teeth, [hide], [pressure_angle], [clearance], [backlash], [interior]);
|
||||
// spur_gear2d(pitch, teeth, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]) [ATTACHMENTS];
|
||||
// spur_gear2d(mod=, teeth=, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]) [ATTACHMENTS];
|
||||
// Usage: As Function
|
||||
// poly = spur_gear2d(pitch|mod, teeth, [hide], [pressure_angle], [clearance], [backlash], [interior]);
|
||||
// poly = spur_gear2d(pitch, teeth, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]);
|
||||
// poly = spur_gear2d(mod=, teeth=, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]);
|
||||
// Topics: Gears
|
||||
// See Also: spur_gear()
|
||||
// Description:
|
||||
|
@ -291,8 +293,8 @@ module spur_gear2d(
|
|||
|
||||
// Function&Module: rack()
|
||||
// Usage: As a Module
|
||||
// rack(pitch, teeth, thickness, height, [pressure_angle=], [backlash=]);
|
||||
// rack(mod=, teeth=, thickness=, height=, [pressure_angle=], [backlash]=);
|
||||
// rack(pitch, teeth, thickness, height, [pressure_angle=], [backlash=]) [ATTACHMENTS];
|
||||
// rack(mod=, teeth=, thickness=, height=, [pressure_angle=], [backlash]=) [ATTACHMENTS];
|
||||
// Usage: As a Function
|
||||
// vnf = rack(pitch, teeth, thickness, height, [pressure_angle=], [backlash=]);
|
||||
// vnf = rack(mod=, teeth=, thickness=, height=, [pressure_angle=], [backlash=]);
|
||||
|
@ -438,10 +440,12 @@ function rack(
|
|||
|
||||
|
||||
// Function&Module: rack2d()
|
||||
// Usage: As a Function
|
||||
// path = rack2d(pitch|mod, teeth, height, [pressure_angle], [backlash]);
|
||||
// Usage: As a Module
|
||||
// rack2d(pitch|mod, teeth, height, [pressure_angle], [backlash]);
|
||||
// path = rack2d(pitch, teeth, height, [pressure_angle=], [backlash=]) [ATTACHMENTS];
|
||||
// path = rack2d(mod=, teeth=, height=, [pressure_angle=], [backlash=]) [ATTACHMENTS];
|
||||
// Usage: As a Function
|
||||
// path = rack2d(pitch, teeth, height, [pressure_angle=], [backlash=]);
|
||||
// path = rack2d(mod=, teeth=, height=, [pressure_angle=], [backlash=]);
|
||||
// Topics: Gears
|
||||
// See Also: spur_gear2d()
|
||||
// Description:
|
||||
|
@ -453,6 +457,7 @@ function rack(
|
|||
// pitch = The circular pitch, or distance between teeth around the pitch circle, in mm.
|
||||
// teeth = Total number of teeth along the rack
|
||||
// height = Height of rack in mm, from tooth top to back of rack.
|
||||
// ---
|
||||
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees.
|
||||
// backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle
|
||||
// mod = The metric module/modulus of the gear.
|
||||
|
|
|
@ -1358,6 +1358,9 @@ function sphere_line_intersection(r, cp, line, bounded=false, d, eps=EPSILON) =
|
|||
function polygon_area(poly, signed=false) =
|
||||
assert(is_path(poly), "Invalid polygon." )
|
||||
len(poly)<3 ? 0 :
|
||||
len(poly)==3 ?
|
||||
let( total= len(poly[0])==2 ? 0.5*cross(poly[2]-poly[0],poly[2]-poly[1]) : 0.5*norm(cross(poly[2]-poly[0],poly[2]-poly[1])))
|
||||
signed ? total : abs(total) :
|
||||
len(poly[0])==2
|
||||
? let( total = sum([for(i=[1:1:len(poly)-2]) cross(poly[i]-poly[0],poly[i+1]-poly[0]) ])/2 )
|
||||
signed ? total : abs(total)
|
||||
|
|
212
hingesnaps.scad
212
hingesnaps.scad
|
@ -10,112 +10,11 @@
|
|||
|
||||
// Section: Hinges and Snaps
|
||||
|
||||
// Module: folding_hinge_mask()
|
||||
// Usage:
|
||||
// folding_hinge_mask(l, thick, [layerheight], [foldangle], [hingegap], [anchor], [spin], [orient]);
|
||||
// Description:
|
||||
// Creates a mask to be differenced away from a plate to create a foldable hinge.
|
||||
// Center the mask at the bottom of the plate you want to make a hinge in.
|
||||
// The mask will leave hinge material two `layerheight`s thick on the bottom of the hinge.
|
||||
// Arguments:
|
||||
// l = Length of the hinge in mm.
|
||||
// thick = Thickness in mm of the material to make the hinge in.
|
||||
// layerheight = The expected printing layer height in mm.
|
||||
// foldangle = The interior angle in degrees of the joint to be created with the hinge. Default: 90
|
||||
// hingegap = Size in mm of the gap at the bottom of the hinge, to make room for folding.
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// Example:
|
||||
// folding_hinge_mask(l=100, thick=3, foldangle=60);
|
||||
module folding_hinge_mask(l, thick, layerheight=0.2, foldangle=90, hingegap=undef, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
hingegap = default(hingegap, layerheight)+2*$slop;
|
||||
size = [l, hingegap, 2*thick];
|
||||
size2 = [l, hingegap+2*thick*tan(foldangle/2)];
|
||||
attachable(anchor,spin,orient, size=size, size2=size2) {
|
||||
up(layerheight*2) prismoid([l,hingegap], [l, hingegap+2*thick/tan(foldangle/2)], h=thick, anchor=BOT);
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Module: snap_lock()
|
||||
// Usage:
|
||||
// snap_lock(thick, [snaplen], [snapdiam], [layerheight], [foldangle], [hingegap], [anchor], [spin], [orient]);
|
||||
// Description:
|
||||
// Creates the central snaplock part.
|
||||
// Arguments:
|
||||
// thick = Thickness in mm of the material to make the hinge in.
|
||||
// snaplen = Length of locking snaps.
|
||||
// snapdiam = Diameter/width of locking snaps.
|
||||
// layerheight = The expected printing layer height in mm.
|
||||
// foldangle = The interior angle in degrees of the joint to be created with the hinge. Default: 90
|
||||
// hingegap = Size in mm of the gap at the bottom of the hinge, to make room for folding.
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// Example:
|
||||
// snap_lock(thick=3, foldangle=60);
|
||||
module snap_lock(thick, snaplen=5, snapdiam=5, layerheight=0.2, foldangle=90, hingegap=undef, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
hingegap = default(hingegap, layerheight)+2*$slop;
|
||||
snap_x = (snapdiam/2) / tan(foldangle/2) + (thick-2*layerheight)/tan(foldangle/2) + hingegap/2;
|
||||
size = [snaplen, snapdiam, 2*thick];
|
||||
attachable(anchor,spin,orient, size=size) {
|
||||
back(snap_x) {
|
||||
cube([snaplen, snapdiam, snapdiam/2+thick], anchor=BOT) {
|
||||
attach(TOP) xcyl(l=snaplen, d=snapdiam, $fn=16);
|
||||
attach(TOP) xcopies(snaplen-snapdiam/4/3) xscale(0.333) sphere(d=snapdiam*0.8, $fn=12);
|
||||
}
|
||||
}
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Module: snap_socket()
|
||||
// Usage:
|
||||
// snap_socket(thick, [snaplen], [snapdiam], [layerheight], [foldangle], [hingegap], [anchor], [spin], [orient]);
|
||||
// Description:
|
||||
// Creates the outside snaplock socketed part.
|
||||
// Arguments:
|
||||
// thick = Thickness in mm of the material to make the hinge in.
|
||||
// snaplen = Length of locking snaps.
|
||||
// snapdiam = Diameter/width of locking snaps.
|
||||
// layerheight = The expected printing layer height in mm.
|
||||
// foldangle = The interior angle in degrees of the joint to be created with the hinge. Default: 90
|
||||
// hingegap = Size in mm of the gap at the bottom of the hinge, to make room for folding.
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// Example:
|
||||
// snap_socket(thick=3, foldangle=60);
|
||||
module snap_socket(thick, snaplen=5, snapdiam=5, layerheight=0.2, foldangle=90, hingegap=undef, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
hingegap = default(hingegap, layerheight)+2*$slop;
|
||||
snap_x = (snapdiam/2) / tan(foldangle/2) + (thick-2*layerheight)/tan(foldangle/2) + hingegap/2;
|
||||
size = [snaplen, snapdiam, 2*thick];
|
||||
attachable(anchor,spin,orient, size=size) {
|
||||
fwd(snap_x) {
|
||||
zrot_copies([0,180], r=snaplen+$slop) {
|
||||
diff("divot")
|
||||
cube([snaplen, snapdiam, snapdiam/2+thick], anchor=BOT) {
|
||||
attach(TOP) xcyl(l=snaplen, d=snapdiam, $fn=16);
|
||||
attach(TOP) left((snaplen+snapdiam/4/3)/2) xscale(0.333) sphere(d=snapdiam*0.8, $fn=12, $tags="divot");
|
||||
}
|
||||
}
|
||||
}
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Module: apply_folding_hinges_and_snaps()
|
||||
// Usage:
|
||||
// apply_folding_hinges_and_snaps(thick, [foldangle], [hinges], [snaps], [sockets], [snaplen], [snapdiam], [hingegap], [layerheight]) ...
|
||||
// apply_folding_hinges_and_snaps(thick, [foldangle=], [hinges=], [snaps=], [sockets=], [snaplen=], [snapdiam=], [hingegap=], [layerheight=]) CHILDREN;
|
||||
// Description:
|
||||
// Adds snaplocks and removes hinges from children objects at the given positions.
|
||||
// Adds snaplocks and create hinges in children at the given positions.
|
||||
// Arguments:
|
||||
// thick = Thickness in mm of the material to make the hinge in.
|
||||
// foldangle = The interior angle in degrees of the joint to be created with the hinge. Default: 90
|
||||
|
@ -190,4 +89,111 @@ module apply_folding_hinges_and_snaps(thick, foldangle=90, hinges=[], snaps=[],
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Module: folding_hinge_mask()
|
||||
// Usage:
|
||||
// folding_hinge_mask(l, thick, [layerheight=], [foldangle=], [hingegap=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a mask to be differenced away from a plate to create a foldable hinge.
|
||||
// Center the mask at the bottom of the plate you want to make a hinge in.
|
||||
// The mask will leave hinge material two `layerheight`s thick on the bottom of the hinge.
|
||||
// Arguments:
|
||||
// l = Length of the hinge in mm.
|
||||
// thick = Thickness in mm of the material to make the hinge in.
|
||||
// ---
|
||||
// layerheight = The expected printing layer height in mm.
|
||||
// foldangle = The interior angle in degrees of the joint to be created with the hinge. Default: 90
|
||||
// hingegap = Size in mm of the gap at the bottom of the hinge, to make room for folding.
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// Example:
|
||||
// folding_hinge_mask(l=100, thick=3, foldangle=60);
|
||||
module folding_hinge_mask(l, thick, layerheight=0.2, foldangle=90, hingegap=undef, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
hingegap = default(hingegap, layerheight)+2*$slop;
|
||||
size = [l, hingegap, 2*thick];
|
||||
size2 = [l, hingegap+2*thick*tan(foldangle/2)];
|
||||
attachable(anchor,spin,orient, size=size, size2=size2) {
|
||||
up(layerheight*2) prismoid([l,hingegap], [l, hingegap+2*thick/tan(foldangle/2)], h=thick, anchor=BOT);
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Module: snap_lock()
|
||||
// Usage:
|
||||
// snap_lock(thick, [snaplen=], [snapdiam=], [layerheight=], [foldangle=], [hingegap=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates the central snaplock part.
|
||||
// Arguments:
|
||||
// thick = Thickness in mm of the material to make the hinge in.
|
||||
// ---
|
||||
// snaplen = Length of locking snaps.
|
||||
// snapdiam = Diameter/width of locking snaps.
|
||||
// layerheight = The expected printing layer height in mm.
|
||||
// foldangle = The interior angle in degrees of the joint to be created with the hinge. Default: 90
|
||||
// hingegap = Size in mm of the gap at the bottom of the hinge, to make room for folding.
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// Example:
|
||||
// snap_lock(thick=3, foldangle=60);
|
||||
module snap_lock(thick, snaplen=5, snapdiam=5, layerheight=0.2, foldangle=90, hingegap=undef, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
hingegap = default(hingegap, layerheight)+2*$slop;
|
||||
snap_x = (snapdiam/2) / tan(foldangle/2) + (thick-2*layerheight)/tan(foldangle/2) + hingegap/2;
|
||||
size = [snaplen, snapdiam, 2*thick];
|
||||
attachable(anchor,spin,orient, size=size) {
|
||||
back(snap_x) {
|
||||
cube([snaplen, snapdiam, snapdiam/2+thick], anchor=BOT) {
|
||||
attach(TOP) xcyl(l=snaplen, d=snapdiam, $fn=16);
|
||||
attach(TOP) xcopies(snaplen-snapdiam/4/3) xscale(0.333) sphere(d=snapdiam*0.8, $fn=12);
|
||||
}
|
||||
}
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Module: snap_socket()
|
||||
// Usage:
|
||||
// snap_socket(thick, [snaplen=], [snapdiam=], [layerheight=], [foldangle=], [hingegap=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates the outside snaplock socketed part.
|
||||
// Arguments:
|
||||
// thick = Thickness in mm of the material to make the hinge in.
|
||||
// ---
|
||||
// snaplen = Length of locking snaps.
|
||||
// snapdiam = Diameter/width of locking snaps.
|
||||
// layerheight = The expected printing layer height in mm.
|
||||
// foldangle = The interior angle in degrees of the joint to be created with the hinge. Default: 90
|
||||
// hingegap = Size in mm of the gap at the bottom of the hinge, to make room for folding.
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// Example:
|
||||
// snap_socket(thick=3, foldangle=60);
|
||||
module snap_socket(thick, snaplen=5, snapdiam=5, layerheight=0.2, foldangle=90, hingegap=undef, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
hingegap = default(hingegap, layerheight)+2*$slop;
|
||||
snap_x = (snapdiam/2) / tan(foldangle/2) + (thick-2*layerheight)/tan(foldangle/2) + hingegap/2;
|
||||
size = [snaplen, snapdiam, 2*thick];
|
||||
attachable(anchor,spin,orient, size=size) {
|
||||
fwd(snap_x) {
|
||||
zrot_copies([0,180], r=snaplen+$slop) {
|
||||
diff("divot")
|
||||
cube([snaplen, snapdiam, snapdiam/2+thick], anchor=BOT) {
|
||||
attach(TOP) xcyl(l=snaplen, d=snapdiam, $fn=16);
|
||||
attach(TOP) left((snaplen+snapdiam/4/3)/2) xscale(0.333) sphere(d=snapdiam*0.8, $fn=12, $tags="divot");
|
||||
}
|
||||
}
|
||||
}
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||
|
|
|
@ -14,22 +14,22 @@
|
|||
|
||||
// Module: knurled_cylinder()
|
||||
// Usage:
|
||||
// knurled_cylinder(l, r|d, [overage], [count], [profile], [helix]);
|
||||
// knurled_cylinder(l, r1|d1, r2|d2, [overage], [count], [profile], [helix]);
|
||||
// knurled_cylinder(l|h|height, r|d=, [count=], [profile=], [helix=]);
|
||||
// knurled_cylinder(l|h|height, r1=|d1=, r2=|d2=, [count=], [profile=], [helix=]);
|
||||
// Description:
|
||||
// Creates a mask to difference from a cylinder to give it a knurled surface.
|
||||
// Creates a knurled cylinder. The knurling is made from small bumps (pyramids) arranged on the surface.
|
||||
// The
|
||||
// Arguments:
|
||||
// l = The length of the axis of the mask. Default: 10
|
||||
// overage = Extra backing to the mask. Default: 5
|
||||
// r = The radius of the cylinder to knurl. Default: 10
|
||||
// l / h / height = The length/height of the cylinder
|
||||
// r = The radius of the cylinder to knurl.
|
||||
// r1 = The radius of the bottom of the conical cylinder to knurl.
|
||||
// r2 = The radius of the top of the conical cylinder to knurl.
|
||||
// d = The diameter of the cylinder to knurl.
|
||||
// d1 = The diameter of the bottom of the conical cylinder to knurl.
|
||||
// d2 = The diameter of the top of the conical cylinder to knurl.
|
||||
// count = The number of grooves to have around the surface of the cylinder. Default: 30
|
||||
// profile = The angle of the bottom of the groove, in degrees. Default 120
|
||||
// helix = The helical angle of the grooves, in degrees. Default: 30
|
||||
// count = The number of bumps filling one revolution of the cylinder. Default: 30
|
||||
// profile = The lower angle between the pyramid-shaped bumps. Smaller angles make the bumps sharper and can lead to bad models if count is small. Default 120
|
||||
// helix = The helical angle of the bumps, in degrees. Close to zero produces vertical ribbing. Close to 90 degrees produces very thin bumps and is not recommended. Default: 30
|
||||
// chamfer = The size of the chamfers on the ends of the cylinder. Default: none.
|
||||
// chamfer1 = The size of the chamfer on the bottom end of the cylinder. Default: none.
|
||||
// chamfer2 = The size of the chamfer on the top end of the cylinder. Default: none.
|
||||
|
@ -48,8 +48,11 @@
|
|||
// knurled_cylinder(l=30, r=20, count=30, profile=120, helix=30);
|
||||
// knurled_cylinder(l=30, r=20, count=30, profile=90, helix=30);
|
||||
// knurled_cylinder(l=30, r=20, count=20, profile=120, helix=30);
|
||||
// knurled_cylinder(l=30, r=20, count=20, profile=120, helix=0.01);
|
||||
// knurled_cylinder(l=30, r=20, count=20, profile=140, helix=60);
|
||||
// knurled_cylinder(l=30, r1=20, r2=12, count=40, profile=90, helix=55);
|
||||
module knurled_cylinder(
|
||||
l=20,
|
||||
l,
|
||||
r=undef, r1=undef, r2=undef,
|
||||
d=undef, d1=undef, d2=undef,
|
||||
count=30, profile=120, helix=30,
|
||||
|
@ -57,8 +60,12 @@ module knurled_cylinder(
|
|||
chamfang=undef, chamfang1=undef, chamfang2=undef,
|
||||
from_end=false,
|
||||
rounding=undef, rounding1=undef, rounding2=undef,
|
||||
anchor=CENTER, spin=0, orient=UP
|
||||
anchor=CENTER, spin=0, orient=UP,
|
||||
height, h
|
||||
) {
|
||||
assert(is_finite(helix) && helix>0 && helix<90, "Must give helix angle between 0 and 90");
|
||||
assert(is_finite(profile) && profile>0 && profile<180, "Must give profile between 0 and 180");
|
||||
l = one_defined([l,h,height],"l,h,height");
|
||||
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=10);
|
||||
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=10);
|
||||
inset = r1 * sin(180/count) / tan(profile/2);
|
||||
|
@ -73,8 +80,11 @@ module knurled_cylinder(
|
|||
vertices = concat(
|
||||
[
|
||||
for (layer = [0:1:layers], pt=path)
|
||||
(layer%2)? [pt.x, pt.y, layer*knob_h-layers*knob_h/2] :
|
||||
rot(180/count, p=[pt.x, pt.y, layer*knob_h-layers*knob_h/2])
|
||||
let(scale_factor = lerp(1,r2/r1,layer/layers))
|
||||
scale([scale_factor,scale_factor,1],
|
||||
(layer%2)? [pt.x, pt.y, layer*knob_h-layers*knob_h/2] :
|
||||
rot(180/count, p=[pt.x, pt.y, layer*knob_h-layers*knob_h/2])
|
||||
)
|
||||
], [
|
||||
[0,0,-layers*knob_h/2],
|
||||
[0,0, layers*knob_h/2]
|
||||
|
@ -127,22 +137,23 @@ module knurled_cylinder(
|
|||
|
||||
// Module: knurled_cylinder_mask()
|
||||
// Usage:
|
||||
// knurled_cylinder_mask(l, r|d, [overage], [count], [profile], [helix]);
|
||||
// knurled_cylinder_mask(l, r1|d1, r2|d2, [overage], [count], [profile], [helix]);
|
||||
// knurled_cylinder_mask(l|h|height, r|d=, [overage], [count], [profile], [helix]) [ATTACHMENTS];
|
||||
// knurled_cylinder_mask(l|h|height, r=1|d1=, r2=|d2=, [overage=], [count=], [profile=], [helix=],...) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a mask to difference from a cylinder to give it a knurled surface.
|
||||
// Arguments:
|
||||
// l = The length of the axis of the mask. Default: 10
|
||||
// l = The length of the axis of the mask.
|
||||
// r = The radius of the cylinder to knurl.
|
||||
// overage = Extra backing to the mask. Default: 5
|
||||
// r = The radius of the cylinder to knurl. Default: 10
|
||||
// ---
|
||||
// r1 = The radius of the bottom of the conical cylinder to knurl.
|
||||
// r2 = The radius of the top of the conical cylinder to knurl.
|
||||
// d = The diameter of the cylinder to knurl.
|
||||
// d1 = The diameter of the bottom of the conical cylinder to knurl.
|
||||
// d2 = The diameter of the top of the conical cylinder to knurl.
|
||||
// count = The number of grooves to have around the surface of the cylinder. Default: 30
|
||||
// profile = The angle of the bottom of the groove, in degrees. Default 120
|
||||
// helix = The helical angle of the grooves, in degrees. Default: 30
|
||||
// count = The number of bumps filling one revolution of the cylinder. Default: 30
|
||||
// profile = The lower angle between the pyramid-shaped bumps. Smaller angles make the bumps sharper and can lead to bad models if count is small. Default 120
|
||||
// helix = The helical angle of the bumps, in degrees. Close to zero produces vertical ribbing. Close to 90 degrees produces very thin bumps and is not recommended. Default: 30
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -150,18 +161,19 @@ module knurled_cylinder(
|
|||
// knurled_cylinder_mask(l=30, r=20, overage=5, profile=120, helix=30);
|
||||
// knurled_cylinder_mask(l=30, r=20, overage=10, profile=120, helix=30);
|
||||
module knurled_cylinder_mask(
|
||||
l=10, overage=5,
|
||||
r=undef, r1=undef, r2=undef,
|
||||
l, r, overage=5,
|
||||
r1=undef, r2=undef,
|
||||
d=undef, d1=undef, d2=undef,
|
||||
count=30, profile=120, helix=30,
|
||||
anchor=CENTER, spin=0, orient=UP
|
||||
anchor=CENTER, spin=0, orient=UP, height,h
|
||||
) {
|
||||
l = one_defined([l,h,height],"l,h,height");
|
||||
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=10);
|
||||
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=10);
|
||||
attachable(anchor,spin,orient, r1=r1, r2=r2, l=l) {
|
||||
difference() {
|
||||
cylinder(r1=r1+overage, r2=r2+overage, h=l, center=true);
|
||||
knurled_cylinder(r1=r1, r2=r2, l=l+0.01);
|
||||
knurled_cylinder(r1=r1, r2=r2, l=l+0.01, profile=profile, helix=helix,count=count);
|
||||
}
|
||||
children();
|
||||
}
|
||||
|
|
63
masks2d.scad
63
masks2d.scad
|
@ -15,12 +15,10 @@
|
|||
// Section: 2D Masking Shapes
|
||||
|
||||
// Function&Module: mask2d_roundover()
|
||||
// Usage: As Module
|
||||
// mask2d_roundover(r|d, [inset], [excess]);
|
||||
// Usage: With Attachments
|
||||
// mask2d_roundover(r|d, [inset], [excess]) { attachments }
|
||||
// Usage: As Module
|
||||
// path = mask2d_roundover(r|d, [inset], [excess]);
|
||||
// Usage: As module
|
||||
// mask2d_roundover(r|d=, [inset], [excess]) [ATTACHMENTS];
|
||||
// Usage: As function
|
||||
// path = mask2d_roundover(r|d=, [inset], [excess]);
|
||||
// Topics: Shapes (2D), Paths (2D), Path Generators, Attachable, Masks (2D)
|
||||
// See Also: corner_profile(), edge_profile(), face_profile()
|
||||
// Description:
|
||||
|
@ -72,12 +70,10 @@ function mask2d_roundover(r, inset=0, excess=0.01, d, anchor=CENTER,spin=0) =
|
|||
|
||||
|
||||
// Function&Module: mask2d_cove()
|
||||
// Usage: As Module
|
||||
// mask2d_cove(r|d, [inset], [excess]);
|
||||
// Usage: With Attachments
|
||||
// mask2d_cove(r|d, [inset], [excess]) { attachments }
|
||||
// Usage: As Function
|
||||
// path = mask2d_cove(r|d, [inset], [excess]);
|
||||
// Usage: As module
|
||||
// mask2d_cove(r|d=, [inset], [excess]) [ATTACHMENTS];
|
||||
// Usage: As function
|
||||
// path = mask2d_cove(r|d=, [inset], [excess]);
|
||||
// Topics: Shapes (2D), Paths (2D), Path Generators, Attachable, Masks (2D)
|
||||
// See Also: corner_profile(), edge_profile(), face_profile()
|
||||
// Description:
|
||||
|
@ -130,21 +126,21 @@ function mask2d_cove(r, inset=0, excess=0.01, d, anchor=CENTER,spin=0) =
|
|||
|
||||
// Function&Module: mask2d_chamfer()
|
||||
// Usage: As Module
|
||||
// mask2d_chamfer(edge, [angle], [inset], [excess]);
|
||||
// mask2d_chamfer(y, [angle], [inset], [excess]);
|
||||
// mask2d_chamfer(x, [angle], [inset], [excess]);
|
||||
// Usage: With Attachments
|
||||
// mask2d_chamfer(edge, [angle], [inset], [excess]) { attachments }
|
||||
// mask2d_chamfer(edge, [angle], [inset], [excess]) [ATTACHMENTS];
|
||||
// mask2d_chamfer(y=, [angle=], [inset=], [excess=]) [ATTACHMENTS];
|
||||
// mask2d_chamfer(x=, [angle=], [inset=], [excess=]) [ATTACHMENTS];
|
||||
// Usage: As Function
|
||||
// path = mask2d_chamfer(edge, [angle], [inset], [excess]);
|
||||
// path = mask2d_chamfer(y, [angle], [inset], [excess]);
|
||||
// path = mask2d_chamfer(x, [angle], [inset], [excess]);
|
||||
// path = mask2d_chamfer(y=, [angle=], [inset=], [excess=]);
|
||||
// path = mask2d_chamfer(x=, [angle=], [inset=], [excess=]);
|
||||
// Topics: Shapes (2D), Paths (2D), Path Generators, Attachable, Masks (2D)
|
||||
// See Also: corner_profile(), edge_profile(), face_profile()
|
||||
// Description:
|
||||
// Creates a 2D chamfer mask shape that is useful for extruding into a 3D mask for a 90° edge.
|
||||
// This 2D mask is designed to be differenced away from the edge of a shape that is in the first (X+Y+) quadrant.
|
||||
// If called as a function, this just returns a 2D path of the outline of the mask shape.
|
||||
// The edge parameter specifies the length of the chamfer's slanted edge. Alternatively you can give x or y to
|
||||
// specify the width or height. Only one of x, y, or width is permitted.
|
||||
// Arguments:
|
||||
// edge = The length of the edge of the chamfer.
|
||||
// angle = The angle of the chamfer edge, away from vertical. Default: 45.
|
||||
|
@ -177,16 +173,15 @@ module mask2d_chamfer(edge, angle=45, inset=0, excess=0.01, x, y, anchor=CENTER,
|
|||
}
|
||||
|
||||
function mask2d_chamfer(edge, angle=45, inset=0, excess=0.01, x, y, anchor=CENTER,spin=0) =
|
||||
assert(num_defined([x,y,edge])==1)
|
||||
assert(is_num(first_defined([x,y,edge])))
|
||||
let(dummy=one_defined([x,y,edge],["x","y","edge"]))
|
||||
assert(is_num(angle))
|
||||
assert(is_undef(excess)||is_num(excess))
|
||||
assert(is_num(inset)||(is_vector(inset)&&len(inset)==2))
|
||||
let(
|
||||
inset = is_list(inset)? inset : [inset,inset],
|
||||
excess = default(excess,$overlap),
|
||||
x = !is_undef(x)? x :
|
||||
!is_undef(y)? adj_ang_to_opp(adj=y,ang=angle) :
|
||||
x = is_def(x)? x :
|
||||
is_def(y)? adj_ang_to_opp(adj=y,ang=angle) :
|
||||
hyp_ang_to_opp(hyp=edge,ang=angle),
|
||||
y = opp_ang_to_adj(opp=x,ang=angle),
|
||||
path = [
|
||||
|
@ -201,9 +196,7 @@ function mask2d_chamfer(edge, angle=45, inset=0, excess=0.01, x, y, anchor=CENTE
|
|||
|
||||
// Function&Module: mask2d_rabbet()
|
||||
// Usage: As Module
|
||||
// mask2d_rabbet(size, [excess]);
|
||||
// Usage: With Attachments
|
||||
// mask2d_rabbet(size, [excess]) { attachments }
|
||||
// mask2d_rabbet(size, [excess]) [ATTACHMENTS];
|
||||
// Usage: As Function
|
||||
// path = mask2d_rabbet(size, [excess]);
|
||||
// Topics: Shapes (2D), Paths (2D), Path Generators, Attachable, Masks (2D)
|
||||
|
@ -252,11 +245,9 @@ function mask2d_rabbet(size, excess=0.01, anchor=CENTER,spin=0) =
|
|||
|
||||
// Function&Module: mask2d_dovetail()
|
||||
// Usage: As Module
|
||||
// mask2d_dovetail(edge, [angle], [inset], [shelf], [excess], ...);
|
||||
// mask2d_dovetail(x=, [angle=], [inset=], [shelf=], [excess=], ...);
|
||||
// mask2d_dovetail(y=, [angle=], [inset=], [shelf=], [excess=], ...);
|
||||
// Usage: With Attachments
|
||||
// mask2d_dovetail(edge, [angle], [inset], [shelf], ...) { attachments }
|
||||
// mask2d_dovetail(edge, [angle], [inset], [shelf], [excess], ...) [ATTACHMENTS];
|
||||
// mask2d_dovetail(x=, [angle=], [inset=], [shelf=], [excess=], ...) [ATTACHMENTS];
|
||||
// mask2d_dovetail(y=, [angle=], [inset=], [shelf=], [excess=], ...) [ATTACHMENTS];
|
||||
// Usage: As Function
|
||||
// path = mask2d_dovetail(edge, [angle], [inset], [shelf], [excess]);
|
||||
// Topics: Shapes (2D), Paths (2D), Path Generators, Attachable, Masks (2D)
|
||||
|
@ -323,11 +314,9 @@ function mask2d_dovetail(edge, angle=30, inset=0, shelf=0, excess=0.01, x, y, an
|
|||
|
||||
// Function&Module: mask2d_teardrop()
|
||||
// Usage: As Module
|
||||
// mask2d_teardrop(r|d, [angle], [excess]);
|
||||
// Usage: With Attachments
|
||||
// mask2d_teardrop(r|d, [angle], [excess]) { attachments }
|
||||
// mask2d_teardrop(r|d=, [angle], [excess]) [ATTACHMENTS];
|
||||
// Usage: As Function
|
||||
// path = mask2d_teardrop(r|d, [angle], [excess]);
|
||||
// path = mask2d_teardrop(r|d=, [angle], [excess]);
|
||||
// Topics: Shapes (2D), Paths (2D), Path Generators, Attachable, Masks (2D)
|
||||
// See Also: corner_profile(), edge_profile(), face_profile()
|
||||
// Description:
|
||||
|
@ -379,9 +368,7 @@ module mask2d_teardrop(r, angle=45, excess=0.01, d, anchor=CENTER, spin=0) {
|
|||
|
||||
// Function&Module: mask2d_ogee()
|
||||
// Usage: As Module
|
||||
// mask2d_ogee(pattern, [excess], ...);
|
||||
// Usage: With Attachments
|
||||
// mask2d_ogee(pattern, [excess], ...) { attachments }
|
||||
// mask2d_ogee(pattern, [excess], ...) [ATTAHCMENTS];
|
||||
// Usage: As Function
|
||||
// path = mask2d_ogee(pattern, [excess], ...);
|
||||
// Topics: Shapes (2D), Paths (2D), Path Generators, Attachable, Masks (2D)
|
||||
|
|
87
masks3d.scad
87
masks3d.scad
|
@ -15,7 +15,7 @@
|
|||
|
||||
// Module: chamfer_edge_mask()
|
||||
// Usage:
|
||||
// chamfer_edge_mask(l, chamfer, [excess]);
|
||||
// chamfer_edge_mask(l, chamfer, [excess]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a shape that can be used to chamfer a 90 degree edge.
|
||||
// Difference it from the object to be chamfered. The center of
|
||||
|
@ -24,6 +24,7 @@
|
|||
// l = Length of mask.
|
||||
// chamfer = Size of chamfer.
|
||||
// excess = The extra amount to add to the length of the mask so that it differences away from other shapes cleanly. Default: `0.1`
|
||||
// ---
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -40,6 +41,7 @@
|
|||
// edge_mask(TOP+RIGHT)
|
||||
// #chamfer_edge_mask(l=50, chamfer=10);
|
||||
// }
|
||||
function chamfer_edge_mask(l=1, chamfer=1, excess=0.1, anchor=CENTER, spin=0, orient=UP) = no_function("chamfer_edge_mask");
|
||||
module chamfer_edge_mask(l=1, chamfer=1, excess=0.1, anchor=CENTER, spin=0, orient=UP) {
|
||||
attachable(anchor,spin,orient, size=[chamfer*2, chamfer*2, l]) {
|
||||
cylinder(r=chamfer, h=l+excess, center=true, $fn=4);
|
||||
|
@ -50,7 +52,7 @@ module chamfer_edge_mask(l=1, chamfer=1, excess=0.1, anchor=CENTER, spin=0, orie
|
|||
|
||||
// Module: chamfer_corner_mask()
|
||||
// Usage:
|
||||
// chamfer_corner_mask(chamfer);
|
||||
// chamfer_corner_mask(chamfer) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a shape that can be used to chamfer a 90 degree corner.
|
||||
// Difference it from the object to be chamfered. The center of
|
||||
|
@ -77,6 +79,7 @@ module chamfer_edge_mask(l=1, chamfer=1, excess=0.1, anchor=CENTER, spin=0, orie
|
|||
// Example: Anchors
|
||||
// chamfer_corner_mask(chamfer=20)
|
||||
// show_anchors();
|
||||
function chamfer_corner_mask(chamfer=1, anchor=CENTER, spin=0, orient=UP) = no_function("chamfer_corner_mask");
|
||||
module chamfer_corner_mask(chamfer=1, anchor=CENTER, spin=0, orient=UP) {
|
||||
octahedron(chamfer*4, anchor=anchor, spin=spin, orient=orient) children();
|
||||
}
|
||||
|
@ -84,7 +87,7 @@ module chamfer_corner_mask(chamfer=1, anchor=CENTER, spin=0, orient=UP) {
|
|||
|
||||
// Module: chamfer_cylinder_mask()
|
||||
// Usage:
|
||||
// chamfer_cylinder_mask(r|d, chamfer, [ang], [from_end])
|
||||
// chamfer_cylinder_mask(r|d=, chamfer, [ang], [from_end]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Create a mask that can be used to bevel/chamfer the end of a cylindrical region.
|
||||
// Difference it from the end of the region to be chamfered. The center of the mask
|
||||
|
@ -92,8 +95,9 @@ module chamfer_corner_mask(chamfer=1, anchor=CENTER, spin=0, orient=UP) {
|
|||
// to be chamfered.
|
||||
// Arguments:
|
||||
// r = Radius of cylinder to chamfer.
|
||||
// chamfer = Size of the edge chamfered, inset from edge.
|
||||
// ---
|
||||
// d = Diameter of cylinder to chamfer. Use instead of r.
|
||||
// chamfer = Size of the edge chamfered, inset from edge. (Default: 0.25)
|
||||
// ang = Angle of chamfer in degrees from vertical. (Default: 45)
|
||||
// from_end = If true, chamfer size is measured from end of cylinder. If false, chamfer is measured outset from the radius of the cylinder. (Default: false)
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
|
@ -110,7 +114,8 @@ module chamfer_corner_mask(chamfer=1, anchor=CENTER, spin=0, orient=UP) {
|
|||
// up(50) chamfer_cylinder_mask(r=50, chamfer=10);
|
||||
// }
|
||||
// Example: Masking by Attachment
|
||||
module chamfer_cylinder_mask(r, d, chamfer=0.25, ang=45, from_end=false, anchor=CENTER, spin=0, orient=UP)
|
||||
function chamfer_cylinder_mask(r, chamfer, d, ang=45, from_end=false, anchor=CENTER, spin=0, orient=UP) = no_function("chamfer_cylinder_mask");
|
||||
module chamfer_cylinder_mask(r, chamfer, d, ang=45, from_end=false, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
ch = from_end? chamfer : opp_ang_to_adj(chamfer,ang);
|
||||
|
@ -129,15 +134,16 @@ module chamfer_cylinder_mask(r, d, chamfer=0.25, ang=45, from_end=false, anchor=
|
|||
|
||||
// Module: rounding_edge_mask()
|
||||
// Usage:
|
||||
// rounding_edge_mask(l|h, r|d)
|
||||
// rounding_edge_mask(l|h, r1|d1, r2|d2)
|
||||
// rounding_edge_mask(l|h, r|d, [excess=]) [ATTACHMENTS];
|
||||
// rounding_edge_mask(l|h, r1=|d1=, r2=|d2=, [excess=]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a shape that can be used to round a vertical 90 degree edge.
|
||||
// Difference it from the object to be rounded. The center of the mask
|
||||
// object should align exactly with the edge to be rounded.
|
||||
// Arguments:
|
||||
// l = Length of mask.
|
||||
// l/h = Length of mask.
|
||||
// r = Radius of the rounding.
|
||||
// ---
|
||||
// r1 = Bottom radius of rounding.
|
||||
// r2 = Top radius of rounding.
|
||||
// d = Diameter of the rounding.
|
||||
|
@ -172,6 +178,7 @@ module chamfer_cylinder_mask(r, d, chamfer=0.25, ang=45, from_end=false, anchor=
|
|||
// rounding_edge_mask(l=p.z, r=25);
|
||||
// }
|
||||
// }
|
||||
function rounding_edge_mask(l, r, r1, r2, d, d1, d2, excess=0.1, anchor=CENTER, spin=0, orient=UP, h=undef) = no_function("rounding_edge_mask");
|
||||
module rounding_edge_mask(l, r, r1, r2, d, d1, d2, excess=0.1, anchor=CENTER, spin=0, orient=UP, h=undef)
|
||||
{
|
||||
l = first_defined([l, h, 1]);
|
||||
|
@ -203,15 +210,15 @@ module rounding_edge_mask(l, r, r1, r2, d, d1, d2, excess=0.1, anchor=CENTER, sp
|
|||
|
||||
// Module: rounding_corner_mask()
|
||||
// Usage:
|
||||
// rounding_corner_mask(r|d, [excess=], [style=]);
|
||||
// rounding_corner_mask(r|d, [excess=], [style=]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a shape that you can use to round 90 degree corners.
|
||||
// Difference it from the object to be rounded. The center of the mask
|
||||
// object should align exactly with the corner to be rounded.
|
||||
// Arguments:
|
||||
// r = Radius of corner rounding.
|
||||
// d = Diameter of corner rounding.
|
||||
// ---
|
||||
// d = Diameter of corner rounding.
|
||||
// excess = Extra size for the mask. Defaults: 0.1
|
||||
// style = The style of the sphere cutout's construction. One of "orig", "aligned", "stagger", "octa", or "icosa". Default: "octa"
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
|
@ -235,6 +242,7 @@ module rounding_edge_mask(l, r, r1, r2, d, d1, d2, excess=0.1, anchor=CENTER, sp
|
|||
// corner_mask(TOP)
|
||||
// #rounding_corner_mask(r=20);
|
||||
// }
|
||||
function rounding_corner_mask(r, d, style="octa", excess=0.1, anchor=CENTER, spin=0, orient=UP) = no_function("rounding_corner_mask");
|
||||
module rounding_corner_mask(r, d, style="octa", excess=0.1, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
|
@ -252,8 +260,8 @@ module rounding_corner_mask(r, d, style="octa", excess=0.1, anchor=CENTER, spin=
|
|||
|
||||
// Module: rounding_angled_edge_mask()
|
||||
// Usage:
|
||||
// rounding_angled_edge_mask(h, r|d, [ang]);
|
||||
// rounding_angled_edge_mask(h, r1|d1, r2|d2, [ang]);
|
||||
// rounding_angled_edge_mask(h, r|d=, [ang=]) [ATTACHMENTS];
|
||||
// rounding_angled_edge_mask(h, r1=|d1=, r2=|d2=, [ang=]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a vertical mask that can be used to round the edge where two face meet, at any arbitrary
|
||||
// angle. Difference it from the object to be rounded. The center of the mask should align exactly
|
||||
|
@ -261,12 +269,13 @@ module rounding_corner_mask(r, d, style="octa", excess=0.1, anchor=CENTER, spin=
|
|||
// Arguments:
|
||||
// h = Height of vertical mask.
|
||||
// r = Radius of the rounding.
|
||||
// ---
|
||||
// r1 = Bottom radius of rounding.
|
||||
// r2 = Top radius of rounding.
|
||||
// d = Diameter of the rounding.
|
||||
// d1 = Bottom diameter of rounding.
|
||||
// d2 = Top diameter of rounding.
|
||||
// ang = Angle that the planes meet at.
|
||||
// ang = Angle that the planes meet at. Default: 90
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -280,7 +289,8 @@ module rounding_corner_mask(r, d, style="octa", excess=0.1, anchor=CENTER, spin=
|
|||
// pie_slice(ang=70, h=50, d=100, center=true);
|
||||
// #rounding_angled_edge_mask(h=51, r1=10, r2=25, ang=70, $fn=32);
|
||||
// }
|
||||
module rounding_angled_edge_mask(h=1.0, r, r1, r2, d, d1, d2, ang=90, anchor=CENTER, spin=0, orient=UP)
|
||||
function rounding_angled_edge_mask(h, r, r1, r2, d, d1, d2, ang=90, anchor=CENTER, spin=0, orient=UP) = no_function("rounding_angled_edge_mask");
|
||||
module rounding_angled_edge_mask(h, r, r1, r2, d, d1, d2, ang=90, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
function _mask_shape(r) = [
|
||||
for (i = [0:1:n]) let (a=90+ang+i*sweep/n) [r*cos(a)+x, r*sin(a)+r],
|
||||
|
@ -316,15 +326,16 @@ module rounding_angled_edge_mask(h=1.0, r, r1, r2, d, d1, d2, ang=90, anchor=CEN
|
|||
|
||||
// Module: rounding_angled_corner_mask()
|
||||
// Usage:
|
||||
// rounding_angled_corner_mask(r|d, ang);
|
||||
// rounding_angled_corner_mask(r|d=, [ang]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a shape that can be used to round the corner of an angle.
|
||||
// Difference it from the object to be rounded. The center of the mask
|
||||
// object should align exactly with the point of the corner to be rounded.
|
||||
// Arguments:
|
||||
// r = Radius of the rounding.
|
||||
// ---
|
||||
// d = Diameter of the rounding.
|
||||
// ang = Angle between planes that you need to round the corner of.
|
||||
// ang = Angle between planes that you need to round the corner of. Default: 90
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -334,6 +345,7 @@ module rounding_angled_edge_mask(h=1.0, r, r1, r2, d, d1, d2, ang=90, anchor=CEN
|
|||
// pie_slice(ang=ang, h=50, r=200, center=true);
|
||||
// up(50/2) #rounding_angled_corner_mask(r=20, ang=ang);
|
||||
// }
|
||||
function rounding_angled_corner_mask(r, ang=90, d, anchor=CENTER, spin=0, orient=UP) = no_function("rounding_angled_corner_mask");
|
||||
module rounding_angled_corner_mask(r, ang=90, d, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
|
@ -362,16 +374,17 @@ module rounding_angled_corner_mask(r, ang=90, d, anchor=CENTER, spin=0, orient=U
|
|||
|
||||
// Module: rounding_cylinder_mask()
|
||||
// Usage:
|
||||
// rounding_cylinder_mask(r|d, rounding);
|
||||
// rounding_cylinder_mask(r|d=, rounding);
|
||||
// Description:
|
||||
// Create a mask that can be used to round the end of a cylinder.
|
||||
// Difference it from the cylinder to be rounded. The center of the
|
||||
// mask object should align exactly with the center of the end of the
|
||||
// cylinder to be rounded.
|
||||
// Arguments:
|
||||
// r = Radius of cylinder. (Default: 1.0)
|
||||
// d = Diameter of cylinder. (Default: 1.0)
|
||||
// rounding = Radius of the edge rounding. (Default: 0.25)
|
||||
// r = Radius of cylinder.
|
||||
// rounding = Radius of the edge rounding.
|
||||
// ---
|
||||
// d = Diameter of cylinder.
|
||||
// Example:
|
||||
// difference() {
|
||||
// cylinder(r=50, h=50, center=false);
|
||||
|
@ -388,8 +401,10 @@ module rounding_angled_corner_mask(r, ang=90, d, anchor=CENTER, spin=0, orient=U
|
|||
// attach(TOP)
|
||||
// #rounding_cylinder_mask(d=30, rounding=5, $tags="mask");
|
||||
// }
|
||||
module rounding_cylinder_mask(r, rounding=0.25, d)
|
||||
function rounding_cylinder_mask(r, rounding, d) = no_function("rounding_cylinder_mask");
|
||||
module rounding_cylinder_mask(r, rounding, d)
|
||||
{
|
||||
no_children($children);
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
difference() {
|
||||
cyl(r=r+rounding, l=rounding*2, anchor=CENTER);
|
||||
|
@ -401,7 +416,7 @@ module rounding_cylinder_mask(r, rounding=0.25, d)
|
|||
|
||||
// Module: rounding_hole_mask()
|
||||
// Usage:
|
||||
// rounding_hole_mask(r|d, rounding, [excess]);
|
||||
// rounding_hole_mask(r|d, rounding, [excess]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Create a mask that can be used to round the edge of a circular hole.
|
||||
// Difference it from the hole to be rounded. The center of the
|
||||
|
@ -410,7 +425,7 @@ module rounding_cylinder_mask(r, rounding=0.25, d)
|
|||
// Arguments:
|
||||
// r = Radius of hole.
|
||||
// d = Diameter of hole to rounding.
|
||||
// rounding = Radius of the rounding. (Default: 0.25)
|
||||
// rounding = Radius of the rounding.
|
||||
// excess = The extra thickness of the mask. Default: `0.1`.
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
|
@ -429,7 +444,8 @@ module rounding_cylinder_mask(r, rounding=0.25, d)
|
|||
// cylinder(r=50, h=100.1, center=true);
|
||||
// up(50) rounding_hole_mask(r=50, rounding=10);
|
||||
// }
|
||||
module rounding_hole_mask(r, rounding=0.25, excess=0.1, d, anchor=CENTER, spin=0, orient=UP)
|
||||
function rounding_hole_mask(r, rounding, excess=0.1, d, anchor=CENTER, spin=0, orient=UP) = no_function("rounding_hole_mask");
|
||||
module rounding_hole_mask(r, rounding, excess=0.1, d, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
attachable(anchor,spin,orient, r=r+rounding, l=2*rounding) {
|
||||
|
@ -448,7 +464,7 @@ module rounding_hole_mask(r, rounding=0.25, excess=0.1, d, anchor=CENTER, spin=0
|
|||
|
||||
// Module: teardrop_edge_mask()
|
||||
// Usage:
|
||||
// teardrop_edge_mask(r|d, [angle], [excess]);
|
||||
// teardrop_edge_mask(r|d=, [angle], [excess]);
|
||||
// Description:
|
||||
// Makes an apropriate 3D corner rounding mask that keeps within `angle` degrees of vertical.
|
||||
// Arguments:
|
||||
|
@ -456,9 +472,6 @@ module rounding_hole_mask(r, rounding=0.25, excess=0.1, d, anchor=CENTER, spin=0
|
|||
// d = Diameter of the mask rounding.
|
||||
// angle = Maximum angle from vertical. Default: 45
|
||||
// excess = Excess mask size. Default: 0.1
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// Example(VPD=50,VPR=[55,0,120]):
|
||||
// teardrop_edge_mask(l=20, r=10, angle=40);
|
||||
// Example(VPD=300,VPR=[75,0,25]):
|
||||
|
@ -469,7 +482,10 @@ module rounding_hole_mask(r, rounding=0.25, excess=0.1, d, anchor=CENTER, spin=0
|
|||
// corner_mask(BOT)
|
||||
// teardrop_corner_mask(r=10, angle=40);
|
||||
// }
|
||||
module teardrop_edge_mask(l, r, angle, excess=0.1, d, anchor=CENTER, spin=0, orient=UP) {
|
||||
function teardrop_edge_mask(l, r, angle, excess=0.1, d) = no_function("teardrop_edge_mask");
|
||||
module teardrop_edge_mask(l, r, angle, excess=0.1, d)
|
||||
{
|
||||
no_children($children);
|
||||
assert(is_num(l));
|
||||
assert(is_num(angle));
|
||||
assert(is_num(excess));
|
||||
|
@ -484,17 +500,15 @@ module teardrop_edge_mask(l, r, angle, excess=0.1, d, anchor=CENTER, spin=0, ori
|
|||
|
||||
// Module: teardrop_corner_mask()
|
||||
// Usage:
|
||||
// teardrop_corner_mask(r|d, [angle], [excess]);
|
||||
// teardrop_corner_mask(r|d=, [angle], [excess]);
|
||||
// Description:
|
||||
// Makes an apropriate 3D corner rounding mask that keeps within `angle` degrees of vertical.
|
||||
// Arguments:
|
||||
// r = Radius of the mask rounding.
|
||||
// d = Diameter of the mask rounding.
|
||||
// angle = Maximum angle from vertical. Default: 45
|
||||
// excess = Excess mask size. Default: 0.1
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// ---
|
||||
// d = Diameter of the mask rounding.
|
||||
// Example:
|
||||
// teardrop_corner_mask(r=20, angle=40);
|
||||
// Example:
|
||||
|
@ -505,7 +519,10 @@ module teardrop_edge_mask(l, r, angle, excess=0.1, d, anchor=CENTER, spin=0, ori
|
|||
// corner_mask(BOT)
|
||||
// teardrop_corner_mask(r=10, angle=40);
|
||||
// }
|
||||
module teardrop_corner_mask(r, angle, excess=0.1, d, anchor=CENTER, spin=0, orient=UP) {
|
||||
function teardrop_corner_mask(r, angle, excess=0.1, d) = no_function("teardrop_corner_mask");
|
||||
module teardrop_corner_mask(r, angle, excess=0.1, d)
|
||||
{
|
||||
no_children($children);
|
||||
assert(is_num(angle));
|
||||
assert(is_num(excess));
|
||||
assert(angle>0 && angle<90);
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
|
||||
// Module: bounding_box()
|
||||
// Usage:
|
||||
// bounding_box() ...
|
||||
// bounding_box([excess],[planar]) CHILDREN;
|
||||
// Description:
|
||||
// Returns the smallest axis-aligned square (or cube) shape that contains all the 2D (or 3D)
|
||||
// children given. The module children() is supposed to be a 3d shape when planar=false and
|
||||
// a 2d shape when planar=true otherwise the system will issue a warning of mixing dimension
|
||||
// children given. The module children() must 3d when planar=false and
|
||||
// 2d when planar=true, or you will get a warning of mixing dimension
|
||||
// or scaling by 0.
|
||||
// Arguments:
|
||||
// excess = The amount that the bounding box should be larger than needed to bound the children, in each axis.
|
||||
|
@ -103,7 +103,7 @@ module bounding_box(excess=0, planar=false) {
|
|||
// Module: chain_hull()
|
||||
//
|
||||
// Usage:
|
||||
// chain_hull() ...
|
||||
// chain_hull() CHILDREN;
|
||||
//
|
||||
// Description:
|
||||
// Performs hull operations between consecutive pairs of children,
|
||||
|
@ -150,7 +150,7 @@ module chain_hull()
|
|||
|
||||
// Module: path_extrude2d()
|
||||
// Usage:
|
||||
// path_extrude2d(path, [caps], [closed]) {...}
|
||||
// path_extrude2d(path, [caps=], [closed=], [s=], [convexity=]) 2D-CHILDREN;
|
||||
// Description:
|
||||
// Extrudes 2D children along the given 2D path, with optional rounded endcaps.
|
||||
// It works by constructing straight sections corresponding to each segment of the path and inserting rounded joints at each corner.
|
||||
|
@ -158,6 +158,7 @@ module chain_hull()
|
|||
// If you set caps to true for asymmetric children then incorrect caps will be generated.
|
||||
// Arguments:
|
||||
// path = The 2D path to extrude the geometry along.
|
||||
// ---
|
||||
// caps = If true, caps each end of the path with a rounded copy of the children. Children must by symmetric across the Y axis, or results are wrong. Default: false
|
||||
// closed = If true, connect the starting point of the path to the ending point. Default: false
|
||||
// convexity = The max number of times a line could pass though a wall. Default: 10
|
||||
|
@ -261,13 +262,15 @@ module path_extrude2d(path, caps=false, closed=false, s, convexity=10) {
|
|||
|
||||
// Module: cylindrical_extrude()
|
||||
// Usage:
|
||||
// cylindrical_extrude(size, ir|id, or|od, [convexity]) ...
|
||||
// cylindrical_extrude(ir|id=, or|od=, [size=], [convexity=], [spin=], [orient=]) 2D-CHILDREN;
|
||||
// Description:
|
||||
// Extrudes all 2D children outwards, curved around a cylindrical shape.
|
||||
// Extrudes its 2D children outwards, curved around a cylindrical shape. Uses $fn/$fa/$fs to
|
||||
// control the faceting of the extrusion.
|
||||
// Arguments:
|
||||
// or = The outer radius to extrude to.
|
||||
// od = The outer diameter to extrude to.
|
||||
// ir = The inner radius to extrude from.
|
||||
// or = The outer radius to extrude to.
|
||||
// ---
|
||||
// od = The outer diameter to extrude to.
|
||||
// id = The inner diameter to extrude from.
|
||||
// size = The [X,Y] size of the 2D children to extrude. Default: [1000,1000]
|
||||
// convexity = The max number of times a line could pass though a wall. Default: 10
|
||||
|
@ -282,11 +285,12 @@ module path_extrude2d(path, caps=false, closed=false, s, convexity=10) {
|
|||
// Example: Orient to the Y Axis.
|
||||
// cylindrical_extrude(or=40, ir=35, orient=BACK)
|
||||
// text(text="Hello World!", size=10, halign="center", valign="center");
|
||||
module cylindrical_extrude(or, ir, od, id, size=1000, convexity=10, spin=0, orient=UP) {
|
||||
module cylindrical_extrude(ir, or, od, id, size=1000, convexity=10, spin=0, orient=UP) {
|
||||
assert(is_num(size) || is_vector(size,2));
|
||||
size = is_num(size)? [size,size] : size;
|
||||
ir = get_radius(r=ir,d=id);
|
||||
or = get_radius(r=or,d=od);
|
||||
assert(all_positive([ir,or]), "Must supply positive inner and outer radius or diameter");
|
||||
index_r = or;
|
||||
circumf = 2 * PI * index_r;
|
||||
width = min(size.x, circumf);
|
||||
|
@ -316,11 +320,15 @@ module cylindrical_extrude(or, ir, od, id, size=1000, convexity=10, spin=0, orie
|
|||
|
||||
|
||||
// Module: extrude_from_to()
|
||||
// Usage:
|
||||
// extrude_from_to(pt1, pt2, [convexity=], [twist=], [scale=], [slices=]) 2D-CHILDREN;
|
||||
// Description:
|
||||
// Extrudes a 2D shape between the 3d points pt1 and pt2. Takes as children a set of 2D shapes to extrude.
|
||||
// Extrudes the 2D children linearly between the 3d points pt1 and pt2. The origin of the 2D children are placed on
|
||||
// pt1 and pt2, and oriented perpendicular to the line between the points.
|
||||
// Arguments:
|
||||
// pt1 = starting point of extrusion.
|
||||
// pt2 = ending point of extrusion.
|
||||
// ---
|
||||
// convexity = max number of times a line could intersect a wall of the 2D shape being extruded.
|
||||
// twist = number of degrees to twist the 2D shape over the entire extrusion length.
|
||||
// scale = scale multiplier for end of extrusion compared the start.
|
||||
|
@ -349,8 +357,10 @@ module extrude_from_to(pt1, pt2, convexity, twist, scale, slices) {
|
|||
|
||||
|
||||
// Module: path_extrude()
|
||||
// Usage: path_extrude(path, [convexity], [clipsize]) 2D-CHILDREN;
|
||||
// Description:
|
||||
// Extrudes 2D children along a 3D path. This may be slow.
|
||||
// Extrudes 2D children along a 3D path. This may be slow and can have problems with twisting.
|
||||
// See Also: path_sweep()
|
||||
// Arguments:
|
||||
// path = Array of points for the bezier path to extrude along.
|
||||
// convexity = Maximum number of walls a ray can pass through.
|
||||
|
@ -407,7 +417,7 @@ module path_extrude(path, convexity=10, clipsize=100) {
|
|||
|
||||
// Module: minkowski_difference()
|
||||
// Usage:
|
||||
// minkowski_difference() { base_shape(); diff_shape(); ... }
|
||||
// minkowski_difference() { BASE; DIFF1; DIFF2; ... }
|
||||
// Description:
|
||||
// Takes a 3D base shape and one or more 3D diff shapes, carves out the diff shapes from the
|
||||
// surface of the base shape, in a way complementary to how `minkowski()` unions shapes to the
|
||||
|
@ -443,16 +453,16 @@ module minkowski_difference(planar=false) {
|
|||
|
||||
// Module: offset3d()
|
||||
// Usage:
|
||||
// offset3d(r, [size], [convexity]);
|
||||
// offset3d(r, [size], [convexity]) CHILDREN;
|
||||
// Description:
|
||||
// Expands or contracts the surface of a 3D object by a given amount. This is very, very slow.
|
||||
// No really, this is unbearably slow. It uses `minkowski()`. Use this as a last resort.
|
||||
// This is so slow that no example images will be rendered.
|
||||
// Arguments:
|
||||
// r = Radius to expand object by. Negative numbers contract the object.
|
||||
// r = Radius to expand object by. Negative numbers contract the object.
|
||||
// size = Maximum size of object to be contracted, given as a scalar. Default: 100
|
||||
// convexity = Max number of times a line could intersect the walls of the object. Default: 10
|
||||
module offset3d(r=1, size=100, convexity=10) {
|
||||
module offset3d(r, size=100, convexity=10) {
|
||||
n = quant(max(8,segs(abs(r))),4);
|
||||
if (r==0) {
|
||||
children();
|
||||
|
@ -482,10 +492,10 @@ module offset3d(r=1, size=100, convexity=10) {
|
|||
|
||||
// Module: round3d()
|
||||
// Usage:
|
||||
// round3d(r) ...
|
||||
// round3d(or) ...
|
||||
// round3d(ir) ...
|
||||
// round3d(or, ir) ...
|
||||
// round3d(r) CHILDREN;
|
||||
// round3d(or) CHILDREN;
|
||||
// round3d(ir) CHILDREN;
|
||||
// round3d(or, ir) CHILDREN;
|
||||
// Description:
|
||||
// Rounds arbitrary 3D objects. Giving `r` rounds all concave and convex corners. Giving just `ir`
|
||||
// rounds just concave corners. Giving just `or` rounds convex corners. Giving both `ir` and `or`
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
// Section: Phillips Drive
|
||||
|
||||
// Module: phillips_mask()
|
||||
// Usage: phillips_mask(size) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a mask for creating a Phillips drive recess given the Phillips size. Each mask can
|
||||
// be lowered to different depths to create different sizes of recess.
|
||||
|
@ -129,7 +130,7 @@ function phillips_diam(size, depth) =
|
|||
|
||||
// Module: torx_mask()
|
||||
// Usage:
|
||||
// torx_mask(size, l, [center]);
|
||||
// torx_mask(size, l, [center]) [ATTACHMENTS];
|
||||
// Description: Creates a torx bit tip.
|
||||
// Arguments:
|
||||
// size = Torx size.
|
||||
|
|
1179
screws.scad
1179
screws.scad
File diff suppressed because it is too large
Load diff
|
@ -120,6 +120,10 @@ test_is_decreasing();
|
|||
module test_find_approx() {
|
||||
assert(find_approx(1, [2,3,1.05,4,1,2,.99], eps=.1)==2);
|
||||
assert(find_approx(1, [2,3,1.05,4,1,2,.99], all=true, eps=.1)==[2,4,6]);
|
||||
assert(find_approx(1, [2,3,4])==undef);
|
||||
assert(find_approx(1, [2,3,4],all=true)==[]);
|
||||
assert(find_approx(1, [])==undef);
|
||||
assert(find_approx(1, [], all=true)==[]);
|
||||
}
|
||||
test_find_approx();
|
||||
|
||||
|
|
|
@ -768,10 +768,9 @@ module test_polygon_area() {
|
|||
assert(approx(polygon_area(rot([13,27,75],
|
||||
p=path3d(circle(r=50,$fn=1000),fill=23)),
|
||||
signed=true), PI*50*50, eps=0.1));
|
||||
assert(abs(triangle_area([0,0], [0,10], [10,0]) + 50) < EPSILON);
|
||||
assert(abs(triangle_area([0,0], [0,10], [0,15])) < EPSILON);
|
||||
assert(abs(triangle_area([0,0], [10,0], [0,10]) - 50) < EPSILON);
|
||||
|
||||
assert(abs(polygon_area([[0,0], [0,10], [10,0]],signed=true) + 50) < EPSILON);
|
||||
assert(abs(polygon_area([[0,0], [0,10], [0,15]],signed=true)) < EPSILON);
|
||||
assert(abs(polygon_area([[0,0], [10,0], [0,10]],signed=true) - 50) < EPSILON);
|
||||
}
|
||||
*test_polygon_area();
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@ module test_is_vector() {
|
|||
assert(is_vector([1,1,1],all_nonzero=true) == true);
|
||||
assert(is_vector([-1,1,1],all_nonzero=true) == true);
|
||||
assert(is_vector([-1,-1,-1],all_nonzero=true) == true);
|
||||
assert(!is_vector([3,INF,4]));
|
||||
assert(!is_vector([3,NAN,4]));
|
||||
}
|
||||
test_is_vector();
|
||||
|
||||
|
|
|
@ -88,27 +88,6 @@ function law_of_sines(a, A, b, B) =
|
|||
asin(constrain(b/r, -1, 1));
|
||||
|
||||
|
||||
// Function: triangle_area()
|
||||
// Usage:
|
||||
// area = triangle_area(p1,p2,p3);
|
||||
// Topics: Geometry, Trigonometry, Triangles, Area
|
||||
// Description:
|
||||
// Returns the area of a triangle formed between three 2D or 3D vertices.
|
||||
// Result will be negative if the points are 2D and in clockwise order.
|
||||
// Arguments:
|
||||
// p1 = The first vertex of the triangle.
|
||||
// p2 = The second vertex of the triangle.
|
||||
// p3 = The third vertex of the triangle.
|
||||
// Example:
|
||||
// triangle_area([0,0], [5,10], [10,0]); // Returns -50
|
||||
// triangle_area([10,0], [5,10], [0,0]); // Returns 50
|
||||
function triangle_area(p1,p2,p3) =
|
||||
assert( is_path([p1,p2,p3]), "Invalid points or incompatible dimensions." )
|
||||
len(p1)==3
|
||||
? 0.5*norm(cross(p3-p1,p3-p2))
|
||||
: 0.5*cross(p3-p1,p3-p2);
|
||||
|
||||
|
||||
|
||||
// Section: 2D Right Triangle Functions
|
||||
// This is a set of functions to make it easier to perform trig calculations on right triangles.
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
// is_vector([1,1,1],all_nonzero=false); // 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_num(vi)) 0]
|
||||
is_list(v) && len(v)>0 && []==[for(vi=v) if(!is_finite(vi)) 0]
|
||||
&& (is_undef(length) || len(v)==length)
|
||||
&& (is_undef(zero) || ((norm(v) >= eps) == !zero))
|
||||
&& (!all_nonzero || all_nonzero(v)) ;
|
||||
|
|
Loading…
Reference in a new issue