mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-01 09:49:45 +00:00
commit
94583da672
3 changed files with 34 additions and 14 deletions
|
@ -3034,7 +3034,7 @@ module corner_profile(corners=CORNERS_ALL, except=[], r, d, convexity=10) {
|
||||||
// attachable(anchor, spin, orient, size=[sz,sz,sz], anchors=anchors) {
|
// attachable(anchor, spin, orient, size=[sz,sz,sz], anchors=anchors) {
|
||||||
// diff() {
|
// diff() {
|
||||||
// cuboid(sz);
|
// cuboid(sz);
|
||||||
// tag("remove") attach("socket") zcyl(d=prong_size, h=prong_size*2);
|
// tag("remove") attach("socket") zcyl(d=prong_size, h=prong_size*2, $fn=6);
|
||||||
// }
|
// }
|
||||||
// children();
|
// children();
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -1247,7 +1247,10 @@ module rabbit_clip(type, length, width, snap, thickness, depth, compression=0.1
|
||||||
// .
|
// .
|
||||||
// The teeth are chamfered proportionally based on the `chamfer` argument which specifies the fraction of the teeth tips
|
// The teeth are chamfered proportionally based on the `chamfer` argument which specifies the fraction of the teeth tips
|
||||||
// to remove. The teeth valleys are chamfered by half the specified value to ensure that there is room for the parts
|
// to remove. The teeth valleys are chamfered by half the specified value to ensure that there is room for the parts
|
||||||
// to mate. The base is added based on the unchamfered dimensions of the joint, and the "teeth_bot" anchor is located
|
// to mate. If you use the rounding parameter then the roundings cut away the chamfer corners, so chamfered and rounded
|
||||||
|
// joints are compatible with each other. Note that rounding doesn't always produce a smooth transition to the roundover,
|
||||||
|
// particularly with large cone angle.
|
||||||
|
// The base is added based on the unchamfered dimensions of the joint, and the "teeth_bot" anchor is located
|
||||||
// based on the unchamfered dimensions.
|
// based on the unchamfered dimensions.
|
||||||
// .
|
// .
|
||||||
// By default the teeth are symmetric, which is ideal for registration and for situations where loading may occur in either
|
// By default the teeth are symmetric, which is ideal for registration and for situations where loading may occur in either
|
||||||
|
@ -1260,7 +1263,6 @@ module rabbit_clip(type, length, width, snap, thickness, depth, compression=0.1
|
||||||
// For two hirth joints to mate they must have the same tooth count, opposite cone angles, and the chamfer/rounding values
|
// For two hirth joints to mate they must have the same tooth count, opposite cone angles, and the chamfer/rounding values
|
||||||
// must be equal. (One can be chamfered and one rounded, but with the same value.) The rotation required to mate the parts
|
// must be equal. (One can be chamfered and one rounded, but with the same value.) The rotation required to mate the parts
|
||||||
// depends on the skew and whether the tooth count is odd or even. To apply this rotation automatically, set `rot=true`.
|
// depends on the skew and whether the tooth count is odd or even. To apply this rotation automatically, set `rot=true`.
|
||||||
|
|
||||||
// Named Anchors:
|
// Named Anchors:
|
||||||
// "teeth_bot" = center of the joint, aligned with the bottom of the (unchamfered/unrounded) teeth, pointing DOWN.
|
// "teeth_bot" = center of the joint, aligned with the bottom of the (unchamfered/unrounded) teeth, pointing DOWN.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
|
|
40
nurbs.scad
40
nurbs.scad
|
@ -67,6 +67,16 @@ include<BOSL2/beziers.scad>
|
||||||
// weights = vector whose length is the same as control giving weights at each control point. Default: all 1
|
// weights = vector whose length is the same as control giving weights at each control point. Default: all 1
|
||||||
// type = One of "clamped", "closed" or "open" to define end point handling of the spline. Default: "clamped"
|
// type = One of "clamped", "closed" or "open" to define end point handling of the spline. Default: "clamped"
|
||||||
// knots = List of knot values. Default: uniform
|
// knots = List of knot values. Default: uniform
|
||||||
|
// Example(2D,NoAxes): Compute some points and draw a curve and also some specific points:
|
||||||
|
// control = [[5,0],[0,20],[33,43],[37,88],[60,62],[44,22],[77,44],[79,22],[44,3],[22,7]];
|
||||||
|
// curve = nurbs_curve(control,2,splinesteps=16);
|
||||||
|
// pts = nurbs_curve(control,2,u=[0.4,0.8]);
|
||||||
|
// stroke(curve);
|
||||||
|
// color("red")move_copies(pts) circle(r=1.5,$fn=16);
|
||||||
|
// Example(2D,NoAxes): Compute NURBS points and make a polygon
|
||||||
|
// control = [[5,0],[0,20],[33,43],[37,88],[60,62],[44,22],[77,44],[79,22],[44,3],[22,7]];
|
||||||
|
// curve = nurbs_curve(control,2,splinesteps=16,type="closed");
|
||||||
|
// polygon(curve);
|
||||||
// Example(2D,NoAxes): Simple quadratic uniform clamped b-spline with some points computed using splinesteps.
|
// Example(2D,NoAxes): Simple quadratic uniform clamped b-spline with some points computed using splinesteps.
|
||||||
// pts = [[13,43],[30,52],[49,22],[24,3]];
|
// pts = [[13,43],[30,52],[49,22],[24,3]];
|
||||||
// debug_nurbs(pts,2);
|
// debug_nurbs(pts,2);
|
||||||
|
@ -167,7 +177,7 @@ function nurbs_curve(control,degree,splinesteps,u, mult,weights,type="clamped",
|
||||||
assert(num_defined([splinesteps,u])==1, "Must define exactly one of u and splinesteps")
|
assert(num_defined([splinesteps,u])==1, "Must define exactly one of u and splinesteps")
|
||||||
is_finite(u) ? nurbs_curve(control,degree,[u],mult,weights,type=type)[0]
|
is_finite(u) ? nurbs_curve(control,degree,[u],mult,weights,type=type)[0]
|
||||||
: assert(is_undef(splinesteps) || (is_int(splinesteps) || splinesteps>0), "splinesteps must be a positive integer")
|
: assert(is_undef(splinesteps) || (is_int(splinesteps) || splinesteps>0), "splinesteps must be a positive integer")
|
||||||
let(u=is_range(u) ? list(u) : u,f=echo(u=u))
|
let(u=is_range(u) ? list(u) : u)
|
||||||
assert(is_undef(u) || (is_vector(u) && min(u)>=0 && max(u)<=1), "u must be a list of points on the interval [0,1] or a range contained in that interval")
|
assert(is_undef(u) || (is_vector(u) && min(u)>=0 && max(u)<=1), "u must be a list of points on the interval [0,1] or a range contained in that interval")
|
||||||
is_def(weights) ? assert(is_vector(weights, len(control)), "Weights should be a vector whose length is the number of control points")
|
is_def(weights) ? assert(is_vector(weights, len(control)), "Weights should be a vector whose length is the number of control points")
|
||||||
let(
|
let(
|
||||||
|
@ -205,8 +215,6 @@ function nurbs_curve(control,degree,splinesteps,u, mult,weights,type="clamped",
|
||||||
control = type=="open" ? control
|
control = type=="open" ? control
|
||||||
: type=="clamped" ? control //concat(repeat(control[0], degree),control, repeat(last(control),degree))
|
: type=="clamped" ? control //concat(repeat(control[0], degree),control, repeat(last(control),degree))
|
||||||
: /*type=="closed"*/ concat(control, select(control,count(degree))),
|
: /*type=="closed"*/ concat(control, select(control,count(degree))),
|
||||||
// n = len(control)-1, // number of control pts -1
|
|
||||||
// m = n+p+1, // number of knots - 1
|
|
||||||
mult = !uniform ? mult
|
mult = !uniform ? mult
|
||||||
: type=="clamped" ? assert(is_undef(mult) || mult[0]==1 && last(mult)==1,"For clamped b-splines, first and last multiplicity must be 1")
|
: type=="clamped" ? assert(is_undef(mult) || mult[0]==1 && last(mult)==1,"For clamped b-splines, first and last multiplicity must be 1")
|
||||||
[degree+1,each slice(default(mult, repeat(1,len(control)-degree+1)),1,-2),degree+1]
|
[degree+1,each slice(default(mult, repeat(1,len(control)-degree+1)),1,-2),degree+1]
|
||||||
|
@ -266,7 +274,7 @@ function nurbs_curve(control,degree,splinesteps,u, mult,weights,type="clamped",
|
||||||
knotidxR=msum[mind]-1,
|
knotidxR=msum[mind]-1,
|
||||||
knotidx = knotidxR<len(control) ? knotidxR : knotidxR - mult[mind]
|
knotidx = knotidxR<len(control) ? knotidxR : knotidxR - mult[mind]
|
||||||
)
|
)
|
||||||
bspline_pt_recurse(knot,select(control,knotidx-degree,knotidx),uval,1,degree,0,degree,knotidx)
|
_nurbs_pt(knot,select(control,knotidx-degree,knotidx),uval,1,degree,knotidx)
|
||||||
]
|
]
|
||||||
: let(
|
: let(
|
||||||
kmult = _calc_mult(knot),
|
kmult = _calc_mult(knot),
|
||||||
|
@ -292,22 +300,22 @@ function nurbs_curve(control,degree,splinesteps,u, mult,weights,type="clamped",
|
||||||
if (is_def(output)) output]
|
if (is_def(output)) output]
|
||||||
)
|
)
|
||||||
[for(i=idx(adjusted_u))
|
[for(i=idx(adjusted_u))
|
||||||
bspline_pt_recurse(knot,select(control, knotidx[i]-degree,knotidx[i]), adjusted_u[i], 1, degree, 0, degree, knotidx[i])
|
_nurbs_pt(knot,select(control, knotidx[i]-degree,knotidx[i]), adjusted_u[i], 1, degree, knotidx[i])
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
function bspline_pt_recurse(knot, control, u, r, h,s,p,k) =
|
function _nurbs_pt(knot, control, u, r, p, k) =
|
||||||
r>h ? control[0]
|
r>p ? control[0]
|
||||||
:
|
:
|
||||||
let(
|
let(
|
||||||
ctrl_new = [for(i=[k-p+r:1:k-s])
|
ctrl_new = [for(i=[k-p+r:1:k])
|
||||||
let(
|
let(
|
||||||
alpha = (u-knot[i]) / (knot[i+p-r+1]-knot[i])
|
alpha = (u-knot[i]) / (knot[i+p-r+1]-knot[i])
|
||||||
)
|
)
|
||||||
(1-alpha) * control[i-1-(k-p)-r+1] + alpha*control[i-(k-p)-r+1]
|
(1-alpha) * control[i-1-(k-p)-r+1] + alpha*control[i-(k-p)-r+1]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
bspline_pt_recurse(knot,ctrl_new,u,r+1,h,s,p,k);
|
_nurbs_pt(knot,ctrl_new,u,r+1,p,k);
|
||||||
|
|
||||||
|
|
||||||
function _extend_knot_mult(mult, next, len) =
|
function _extend_knot_mult(mult, next, len) =
|
||||||
|
@ -355,7 +363,16 @@ function _calc_mult(knots) =
|
||||||
// show_index = if true then display index of each control point vertex. Default: true
|
// show_index = if true then display index of each control point vertex. Default: true
|
||||||
// show_weights = if true then display any non-unity weights. Default: true if weights vector is supplied, false otherwise
|
// show_weights = if true then display any non-unity weights. Default: true if weights vector is supplied, false otherwise
|
||||||
// show_knots = If true then show the knots on the spline curve. Default: false
|
// show_knots = If true then show the knots on the spline curve. Default: false
|
||||||
|
// Example(2D,Med,NoAxes): The default display includes the control point polygon with its vertices numbered, and the NURBS curve
|
||||||
|
// pts = [[5,0],[0,20],[33,43],[37,88],[60,62],[44,22],[77,44],[79,22],[44,3],[22,7]];
|
||||||
|
// debug_nurbs(pts,4,type="closed");
|
||||||
|
// Example(2D,Med,NoAxes): If you want to see the knots set `show_knots=true`:
|
||||||
|
// pts = [[5,0],[0,20],[33,43],[37,88],[60,62],[44,22],[77,44],[79,22],[44,3],[22,7]];
|
||||||
|
// debug_nurbs(pts,4,type="clamped",show_knots=true);
|
||||||
|
// Example(2D,Med,NoAxes): Non-unity weights are displayed if you give a weight vector
|
||||||
|
// pts = [[5,0],[0,20],[33,43],[37,88],[60,62],[44,22],[77,44],[79,22],[44,3],[22,7]];
|
||||||
|
// weights = [1,1,1,7,1,1,7,1,1,1];
|
||||||
|
// debug_nurbs(pts,4,type="closed",weights=weights);
|
||||||
|
|
||||||
module debug_nurbs(control,degree,splinesteps=16,width=1, size, mult,weights,type="clamped",knots, show_weights, show_knots=false, show_index=true)
|
module debug_nurbs(control,degree,splinesteps=16,width=1, size, mult,weights,type="clamped",knots, show_weights, show_knots=false, show_index=true)
|
||||||
{
|
{
|
||||||
|
@ -369,7 +386,8 @@ module debug_nurbs(control,degree,splinesteps=16,width=1, size, mult,weights,typ
|
||||||
stroke(control, width=width/2, color="lightblue", closed=type=="closed");
|
stroke(control, width=width/2, color="lightblue", closed=type=="closed");
|
||||||
if (show_knots){
|
if (show_knots){
|
||||||
knotpts = nurbs_curve(control=control, degree=degree, splinesteps=1, mult=mult, weights=weights, type=type, knots=knots);
|
knotpts = nurbs_curve(control=control, degree=degree, splinesteps=1, mult=mult, weights=weights, type=type, knots=knots);
|
||||||
color("green")
|
echo(knotpts);
|
||||||
|
color([1,.5,1])
|
||||||
move_copies(knotpts)
|
move_copies(knotpts)
|
||||||
if (twodim)circle(r=width);
|
if (twodim)circle(r=width);
|
||||||
else sphere(r=width);
|
else sphere(r=width);
|
||||||
|
|
Loading…
Reference in a new issue