mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-11 17:24:13 +02:00
add plot_revolution
This commit is contained in:
@@ -142,7 +142,7 @@ function lerpn(a,b,n,endpoint=true) =
|
|||||||
// Function: bilerp()
|
// Function: bilerp()
|
||||||
// Synopsis: Bi-linear interpolation between four values
|
// Synopsis: Bi-linear interpolation between four values
|
||||||
// Topics: Interpolation, Math
|
// Topics: Interpolation, Math
|
||||||
// See Also: lerpn()
|
// See Also: lerp()
|
||||||
// Usage:
|
// Usage:
|
||||||
// x = bilerp(pts, x, y);
|
// x = bilerp(pts, x, y);
|
||||||
// Description:
|
// Description:
|
||||||
|
322
rounding.scad
322
rounding.scad
@@ -2579,7 +2579,9 @@ function _circle_mask(r) =
|
|||||||
// same dimensions that is has on the plane, with y axis mapping to the z axis and the x axis bending
|
// same dimensions that is has on the plane, with y axis mapping to the z axis and the x axis bending
|
||||||
// around the curve of the cylinder. The angular span of the path on the cylinder must be somewhat
|
// around the curve of the cylinder. The angular span of the path on the cylinder must be somewhat
|
||||||
// less than 180 degrees, and the path shouldn't have closely spaced points at concave points of high curvature because
|
// less than 180 degrees, and the path shouldn't have closely spaced points at concave points of high curvature because
|
||||||
// this causes self-intersection in the mask polyhedron, resulting in CGAL failures.
|
// this causes self-intersection in the mask polyhedron, resulting in CGAL failures. The path also cannot include
|
||||||
|
// sharp corners, because it internally uses {{offset()}} which will expand those sharp corners into very long single
|
||||||
|
// segments that produce incorrect result.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// r / radius = center radius of the cylindrical shell to cut a hole in
|
// r / radius = center radius of the cylindrical shell to cut a hole in
|
||||||
// thickness = thickness of cylindrical shell (may need to be slighly oversized)
|
// thickness = thickness of cylindrical shell (may need to be slighly oversized)
|
||||||
@@ -4535,6 +4537,10 @@ function _find_center_anchor(desc1, desc2, anchor2, flip) =
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function _is_anchor(a) = is_string(a) || is_vector(a,2) || is_vector(a,3);
|
||||||
|
|
||||||
|
function _is_anchor_list(list) = is_list(list) && [for(a=list) if (!_is_anchor(a)) a]==[];
|
||||||
|
|
||||||
|
|
||||||
module prism_connector(profile, desc1, anchor1, desc2, anchor2, shift1=0, shift2=0, spin_align=1,
|
module prism_connector(profile, desc1, anchor1, desc2, anchor2, shift1=0, shift2=0, spin_align=1,
|
||||||
scale=1,
|
scale=1,
|
||||||
@@ -4545,155 +4551,173 @@ module prism_connector(profile, desc1, anchor1, desc2, anchor2, shift1=0, shift2
|
|||||||
smooth_normals, smooth_normals1, smooth_normals2,
|
smooth_normals, smooth_normals1, smooth_normals2,
|
||||||
debug=false, debug_pos=false)
|
debug=false, debug_pos=false)
|
||||||
{
|
{
|
||||||
base_fillet = first_defined([fillet1,fillet,0]);
|
dummy1 = assert(_is_anchor(anchor1) || _is_anchor_list(anchor1) , "anchor1 must be an anchor (string or a 3-vector) or a list of anchors")
|
||||||
aux_fillet = first_defined([fillet2,fillet,0]);
|
assert(_is_anchor(anchor2) || _is_anchor_list(anchor2) , "anchor2 must be an anchor (string or a 3-vector) or a list of anchors");
|
||||||
|
if (_is_anchor_list(anchor1) || _is_anchor_list(anchor2)) {
|
||||||
base_overlap = first_defined([overlap1,overlap,1]);
|
anchor1_list=_is_anchor(anchor1) ? [anchor1] : anchor1;
|
||||||
aux_overlap = first_defined([overlap2,overlap,1]);
|
anchor2_list=_is_anchor(anchor2) ? [anchor2] : anchor2;
|
||||||
|
for(i = idx(anchor1_list))
|
||||||
base_n = first_defined([n1,n,15]);
|
for(j= idx(anchor2_list))
|
||||||
aux_n = first_defined([n2,n,15]);
|
{
|
||||||
|
$anchor1 = anchor1_list[i];
|
||||||
base_uniform = first_defined([uniform1, uniform, true]);
|
$anchor2 = anchor2_list[j];
|
||||||
aux_uniform = first_defined([uniform2, uniform, true]);
|
$idx = [i,j];
|
||||||
|
prism_connector(profile=profile, desc1=desc1, anchor1=$anchor1, desc2=desc2, anchor2=$anchor2, shift1=shift1, shift2=shift2, spin_align=spin_align,
|
||||||
base_k = first_defined([k1,k,0.7]);
|
scale=scale, fillet=fillet, fillet1=fillet1, fillet2=fillet2, overlap=overlap, overlap1=overlap1, overlap2=overlap2,
|
||||||
aux_k = first_defined([k2,k,0.7]);
|
k=k, k1=k1, k2=k2, n=n, n1=n1, n2=n2, uniform=uniform, uniform1=uniform1, uniform2=uniform2,
|
||||||
|
smooth_normals=smooth_normals, smooth_normals1=smooth_normals1, smooth_normals2=smooth_normals2,
|
||||||
profile = force_path(profile,"profile");
|
debug=debug, debug_pos=debug_pos) children();
|
||||||
dummy0 = assert(is_path(profile,2), "profile must be a 2d path");
|
|
||||||
|
|
||||||
corrected_base_anchor = is_vector(anchor1) && norm(anchor1)==0 ? _find_center_anchor(desc1,desc2,anchor2,true) : undef;
|
|
||||||
corrected_aux_anchor = is_vector(anchor2) && norm(anchor2)==0 ? _find_center_anchor(desc2,desc1,anchor1,false) : undef;
|
|
||||||
|
|
||||||
|
|
||||||
base_anchor=is_string(anchor1) ? anchor1
|
|
||||||
: is_def(corrected_base_anchor) ? corrected_base_anchor[0]
|
|
||||||
: point3d(anchor1);
|
|
||||||
aux_anchor=is_string(anchor2) ? anchor2
|
|
||||||
: is_def(corrected_aux_anchor) ? corrected_aux_anchor[0]
|
|
||||||
: point3d(anchor2);
|
|
||||||
|
|
||||||
base=desc1;
|
|
||||||
aux=desc2;
|
|
||||||
|
|
||||||
current = parent();
|
|
||||||
tobase = current==base ? ident(4) : linear_solve(current[0],base[0]); // Maps from current frame into the base frame
|
|
||||||
auxmap = linear_solve(base[0], aux[0]); // Map from the base (desc1) coordinate frame into the aux (desc2) coordinate frame
|
|
||||||
|
|
||||||
dummy = assert(is_vector(base_anchor) || is_string(base_anchor), "anchor1 must be a string or a 3-vector")
|
|
||||||
assert(is_vector(aux_anchor) || is_string(aux_anchor), "anchor2 must be a string or a 3-vector")
|
|
||||||
assert(is_rotation(auxmap), "desc1 and desc2 are not related to each other by a rotation (and translation)");
|
|
||||||
|
|
||||||
base_type = _get_obj_type(1,base[1],base_anchor,profile);
|
|
||||||
base_axis = base_type=="cyl" ? base[1][5] : RIGHT;
|
|
||||||
base_edge = _is_geom_an_edge(base[1],base_anchor);
|
|
||||||
base_r = in_list(base_type,["cyl","sphere"]) ? base[1][1] : 1;
|
|
||||||
base_anch = _find_anchor(base_anchor, base[1]);
|
|
||||||
base_spin = base_anch[3];
|
|
||||||
base_anch_pos = base_anch[1];
|
|
||||||
base_anch_dir = base_anch[2];
|
|
||||||
|
|
||||||
prelim_shift1 = _check_join_shift(1,base_type,shift1,true);
|
|
||||||
shift1 = corrected_base_anchor ? corrected_base_anchor[1] + prelim_shift1 : prelim_shift1;
|
|
||||||
aux_type = _get_obj_type(2,aux[1],aux_anchor,profile);
|
|
||||||
aux_anch = _find_anchor(aux_anchor, aux[1]);
|
|
||||||
aux_edge = _is_geom_an_edge(aux[1],aux_anchor);
|
|
||||||
aux_r = in_list(aux_type,["cyl","sphere"]) ? aux[1][1] : 1;
|
|
||||||
aux_anch_pos = aux_anch[1];
|
|
||||||
aux_anch_dir = aux_anch[2];
|
|
||||||
aux_spin = aux_anch[3];
|
|
||||||
aux_spin_dir = apply(rot(from=UP,to=aux_anch[2])*zrot(aux_spin),BACK);
|
|
||||||
aux_axis = aux_type=="cyl" ? aux[1][5] : RIGHT;
|
|
||||||
prelim_shift2 = _check_join_shift(2,aux_type,shift2,false);
|
|
||||||
shift2 = corrected_aux_anchor ? corrected_aux_anchor[1] + prelim_shift2 : prelim_shift2;
|
|
||||||
|
|
||||||
|
|
||||||
base_smooth_normals = first_defined([smooth_normals1, smooth_normals,!base_edge]);
|
|
||||||
aux_smooth_normals = first_defined([smooth_normals2, smooth_normals,!aux_edge]);
|
|
||||||
|
|
||||||
backdir = base_type=="cyl" ? base_axis
|
|
||||||
: apply(rot(from=UP,to=base_anch_dir)*zrot(base_spin),BACK);
|
|
||||||
anch_shift = base_type=="plane" || is_list(base_type) ? base_anch_pos : CENTER;
|
|
||||||
|
|
||||||
|
|
||||||
// Map from the starting position for a join_prism object to
|
|
||||||
// the standard position for the object.
|
|
||||||
// If the aux object is an edge (type is a list) then the starting position
|
|
||||||
// of the prism is with the edge lying on the X axis and the object below.
|
|
||||||
aux_to_canonical = aux_type=="sphere" ? IDENT
|
|
||||||
: aux_type=="cyl" ? frame_map(x=aux_axis, z=aux_anch[2])
|
|
||||||
: aux_type=="plane" ? move(aux_anch_pos) * rot(from=UP, to=aux_anch[2])*zrot(aux_spin)
|
|
||||||
: /* list */ move(aux_anch_pos) * frame_map(z=aux_anch[2],x=aux_spin_dir) ;
|
|
||||||
|
|
||||||
// aux_T is the map that maps the auxiliary object from its initial position to
|
|
||||||
// the position for the prism. The initial position is centered for a sphere,
|
|
||||||
// with the axis X aligned for a cylinder, and with the face of a polyhedron
|
|
||||||
// laying in the XY plane for polyhedra.
|
|
||||||
aux_T = move(-shift1)
|
|
||||||
* frame_map(x=backdir, z=base_anch_dir, reverse=true)
|
|
||||||
* move(-anch_shift)
|
|
||||||
* auxmap
|
|
||||||
* aux_to_canonical
|
|
||||||
* move(shift2);
|
|
||||||
aux_root = aux_type=="plane" || is_list(aux_type) || aux_anchor==CTR ? apply(aux_T,CTR)
|
|
||||||
: apply(aux_T * matrix_inverse(aux_to_canonical), aux_anch_pos);
|
|
||||||
|
|
||||||
base_root = base_type=="plane" || is_list(base_type) || base_anchor==CTR ? CENTER : base_r*UP;
|
|
||||||
|
|
||||||
prism_axis = aux_root-base_root;
|
|
||||||
|
|
||||||
base_inside = prism_axis.z<0 ? -1 : 1;
|
|
||||||
|
|
||||||
aux_normal = aux_type=="cyl" || aux_type=="sphere" ? apply(aux_T*matrix_inverse(aux_to_canonical), aux_anch[2]) - apply(aux_T*matrix_inverse(aux_to_canonical), CTR)
|
|
||||||
: apply(aux_T, UP) - apply(aux_T,CTR); // Is this right? Added second term
|
|
||||||
aux_inside = aux_normal*(base_root-aux_root) < 0 ? -1 : 1;
|
|
||||||
|
|
||||||
shaft = rot(from=UP,to=prism_axis, p=zrot(base_spin,BACK));
|
|
||||||
|
|
||||||
obj1_back = apply(frame_map(x=backdir,z=base_anch_dir,reverse=true)*rot(from=UP,to=base_anch_dir)*zrot(base_spin),BACK);
|
|
||||||
obj2_back = aux_type=="plane" ? apply(aux_T,BACK)-apply(aux_T,CTR)
|
|
||||||
: is_list(aux_type) ? apply(aux_T*matrix_inverse(frame_map(z=aux_anch[2],x=aux_spin_dir)),aux_spin_dir)-apply(aux_T,CTR)
|
|
||||||
: aux_type=="sphere"? apply(aux_T,aux_spin_dir)-apply(aux_T,CTR)
|
|
||||||
/*cyl*/ : apply(aux_T*matrix_inverse(aux_to_canonical),aux_spin_dir)-apply(aux_T,CTR);
|
|
||||||
|
|
||||||
v1 = vector_perp(prism_axis, shaft);
|
|
||||||
v2 = vector_perp(prism_axis, obj1_back);
|
|
||||||
v3 = vector_perp(prism_axis, obj2_back);
|
|
||||||
sign1 = cross(v1,v2)*prism_axis < 0 ? 1 : -1;
|
|
||||||
sign2 = cross(v3,v1)*prism_axis < 0 ? 1 : -1;
|
|
||||||
|
|
||||||
spin1 = sign1 * vector_angle(v1,v2);
|
|
||||||
spin2 = -sign2 * vector_angle(v3,v1);
|
|
||||||
spin = spin_align==1 ? spin1
|
|
||||||
: spin_align==2 ? spin2
|
|
||||||
: spin_align==12 ? mean_angle(spin1,spin2)
|
|
||||||
: spin_align==21 ? mean_angle(spin2,spin1)
|
|
||||||
: assert(false, str("spin_align must be one of 1, 2, 12, or 21 but was ",spin_align));
|
|
||||||
multmatrix(tobase)
|
|
||||||
move(anch_shift)
|
|
||||||
frame_map(x=backdir, z=base_anch_dir)
|
|
||||||
move(shift1){
|
|
||||||
// For debugging spin, shows line in the spin direction
|
|
||||||
//stroke([aux_root,aux_root+unit(obj2_back)*15], width=1,color="lightblue");
|
|
||||||
//stroke([base_root,base_root+unit(obj1_back)*15], width=1,color="lightgreen");
|
|
||||||
|
|
||||||
if (debug_pos)
|
|
||||||
move(base_root)rot(from=UP,to=prism_axis)
|
|
||||||
linear_extrude(height=norm(base_root-aux_root))zrot(base_spin-spin)polygon(profile);
|
|
||||||
else{
|
|
||||||
join_prism(zrot(base_spin-spin,profile),
|
|
||||||
base=base_type, base_r=u_mul(base_r,base_inside),
|
|
||||||
aux=aux_type, aux_T=aux_T, aux_r=u_mul(aux_r,aux_inside),
|
|
||||||
scale=scale,
|
|
||||||
start=base_root, end=aux_root,
|
|
||||||
base_k=base_k, aux_k=aux_k, base_overlap=base_overlap, aux_overlap=aux_overlap,
|
|
||||||
base_n=base_n, aux_n=aux_n, base_fillet=base_fillet, aux_fillet=aux_fillet,
|
|
||||||
base_smooth_normals = base_smooth_normals, aux_smooth_normals=aux_smooth_normals,
|
|
||||||
debug=debug,
|
|
||||||
_name1="desc1", _name2="desc2") children();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
base_fillet = first_defined([fillet1,fillet,0]);
|
||||||
|
aux_fillet = first_defined([fillet2,fillet,0]);
|
||||||
|
|
||||||
|
base_overlap = first_defined([overlap1,overlap,1]);
|
||||||
|
aux_overlap = first_defined([overlap2,overlap,1]);
|
||||||
|
|
||||||
|
base_n = first_defined([n1,n,15]);
|
||||||
|
aux_n = first_defined([n2,n,15]);
|
||||||
|
|
||||||
|
base_uniform = first_defined([uniform1, uniform, true]);
|
||||||
|
aux_uniform = first_defined([uniform2, uniform, true]);
|
||||||
|
|
||||||
|
base_k = first_defined([k1,k,0.7]);
|
||||||
|
aux_k = first_defined([k2,k,0.7]);
|
||||||
|
|
||||||
|
profile = force_path(profile,"profile");
|
||||||
|
dummy0 = assert(is_path(profile,2), "profile must be a 2d path");
|
||||||
|
|
||||||
|
corrected_base_anchor = is_vector(anchor1) && norm(anchor1)==0 ? _find_center_anchor(desc1,desc2,anchor2,true) : undef;
|
||||||
|
corrected_aux_anchor = is_vector(anchor2) && norm(anchor2)==0 ? _find_center_anchor(desc2,desc1,anchor1,false) : undef;
|
||||||
|
|
||||||
|
|
||||||
|
base_anchor=is_string(anchor1) ? anchor1
|
||||||
|
: is_def(corrected_base_anchor) ? corrected_base_anchor[0]
|
||||||
|
: point3d(anchor1);
|
||||||
|
aux_anchor=is_string(anchor2) ? anchor2
|
||||||
|
: is_def(corrected_aux_anchor) ? corrected_aux_anchor[0]
|
||||||
|
: point3d(anchor2);
|
||||||
|
|
||||||
|
base=desc1;
|
||||||
|
aux=desc2;
|
||||||
|
|
||||||
|
current = parent();
|
||||||
|
tobase = current==base ? ident(4) : linear_solve(current[0],base[0]); // Maps from current frame into the base frame
|
||||||
|
auxmap = linear_solve(base[0], aux[0]); // Map from the base (desc1) coordinate frame into the aux (desc2) coordinate frame
|
||||||
|
|
||||||
|
dummy =
|
||||||
|
assert(is_rotation(auxmap), "desc1 and desc2 are not related to each other by a rotation (and translation)");
|
||||||
|
|
||||||
|
base_type = _get_obj_type(1,base[1],base_anchor,profile);
|
||||||
|
base_axis = base_type=="cyl" ? base[1][5] : RIGHT;
|
||||||
|
base_edge = _is_geom_an_edge(base[1],base_anchor);
|
||||||
|
base_r = in_list(base_type,["cyl","sphere"]) ? base[1][1] : 1;
|
||||||
|
base_anch = _find_anchor(base_anchor, base[1]);
|
||||||
|
base_spin = base_anch[3];
|
||||||
|
base_anch_pos = base_anch[1];
|
||||||
|
base_anch_dir = base_anch[2];
|
||||||
|
|
||||||
|
prelim_shift1 = _check_join_shift(1,base_type,shift1,true);
|
||||||
|
shift1 = corrected_base_anchor ? corrected_base_anchor[1] + prelim_shift1 : prelim_shift1;
|
||||||
|
aux_type = _get_obj_type(2,aux[1],aux_anchor,profile);
|
||||||
|
aux_anch = _find_anchor(aux_anchor, aux[1]);
|
||||||
|
aux_edge = _is_geom_an_edge(aux[1],aux_anchor);
|
||||||
|
aux_r = in_list(aux_type,["cyl","sphere"]) ? aux[1][1] : 1;
|
||||||
|
aux_anch_pos = aux_anch[1];
|
||||||
|
aux_anch_dir = aux_anch[2];
|
||||||
|
aux_spin = aux_anch[3];
|
||||||
|
aux_spin_dir = apply(rot(from=UP,to=aux_anch[2])*zrot(aux_spin),BACK);
|
||||||
|
aux_axis = aux_type=="cyl" ? aux[1][5] : RIGHT;
|
||||||
|
prelim_shift2 = _check_join_shift(2,aux_type,shift2,false);
|
||||||
|
shift2 = corrected_aux_anchor ? corrected_aux_anchor[1] + prelim_shift2 : prelim_shift2;
|
||||||
|
|
||||||
|
|
||||||
|
base_smooth_normals = first_defined([smooth_normals1, smooth_normals,!base_edge]);
|
||||||
|
aux_smooth_normals = first_defined([smooth_normals2, smooth_normals,!aux_edge]);
|
||||||
|
|
||||||
|
backdir = base_type=="cyl" ? base_axis
|
||||||
|
: apply(rot(from=UP,to=base_anch_dir)*zrot(base_spin),BACK);
|
||||||
|
anch_shift = base_type=="plane" || is_list(base_type) ? base_anch_pos : CENTER;
|
||||||
|
|
||||||
|
|
||||||
|
// Map from the starting position for a join_prism object to
|
||||||
|
// the standard position for the object.
|
||||||
|
// If the aux object is an edge (type is a list) then the starting position
|
||||||
|
// of the prism is with the edge lying on the X axis and the object below.
|
||||||
|
aux_to_canonical = aux_type=="sphere" ? IDENT
|
||||||
|
: aux_type=="cyl" ? frame_map(x=aux_axis, z=aux_anch[2])
|
||||||
|
: aux_type=="plane" ? move(aux_anch_pos) * rot(from=UP, to=aux_anch[2])*zrot(aux_spin)
|
||||||
|
: /* list */ move(aux_anch_pos) * frame_map(z=aux_anch[2],x=aux_spin_dir) ;
|
||||||
|
|
||||||
|
// aux_T is the map that maps the auxiliary object from its initial position to
|
||||||
|
// the position for the prism. The initial position is centered for a sphere,
|
||||||
|
// with the axis X aligned for a cylinder, and with the face of a polyhedron
|
||||||
|
// laying in the XY plane for polyhedra.
|
||||||
|
aux_T = move(-shift1)
|
||||||
|
* frame_map(x=backdir, z=base_anch_dir, reverse=true)
|
||||||
|
* move(-anch_shift)
|
||||||
|
* auxmap
|
||||||
|
* aux_to_canonical
|
||||||
|
* move(shift2);
|
||||||
|
aux_root = aux_type=="plane" || is_list(aux_type) || aux_anchor==CTR ? apply(aux_T,CTR)
|
||||||
|
: apply(aux_T * matrix_inverse(aux_to_canonical), aux_anch_pos);
|
||||||
|
|
||||||
|
base_root = base_type=="plane" || is_list(base_type) || base_anchor==CTR ? CENTER : base_r*UP;
|
||||||
|
|
||||||
|
prism_axis = aux_root-base_root;
|
||||||
|
|
||||||
|
base_inside = prism_axis.z<0 ? -1 : 1;
|
||||||
|
|
||||||
|
aux_normal = aux_type=="cyl" || aux_type=="sphere" ? apply(aux_T*matrix_inverse(aux_to_canonical), aux_anch[2]) - apply(aux_T*matrix_inverse(aux_to_canonical), CTR)
|
||||||
|
: apply(aux_T, UP) - apply(aux_T,CTR); // Is this right? Added second term
|
||||||
|
aux_inside = aux_normal*(base_root-aux_root) < 0 ? -1 : 1;
|
||||||
|
|
||||||
|
shaft = rot(from=UP,to=prism_axis, p=zrot(base_spin,BACK));
|
||||||
|
|
||||||
|
obj1_back = apply(frame_map(x=backdir,z=base_anch_dir,reverse=true)*rot(from=UP,to=base_anch_dir)*zrot(base_spin),BACK);
|
||||||
|
obj2_back = aux_type=="plane" ? apply(aux_T,BACK)-apply(aux_T,CTR)
|
||||||
|
: is_list(aux_type) ? apply(aux_T*matrix_inverse(frame_map(z=aux_anch[2],x=aux_spin_dir)),aux_spin_dir)-apply(aux_T,CTR)
|
||||||
|
: aux_type=="sphere"? apply(aux_T,aux_spin_dir)-apply(aux_T,CTR)
|
||||||
|
/*cyl*/ : apply(aux_T*matrix_inverse(aux_to_canonical),aux_spin_dir)-apply(aux_T,CTR);
|
||||||
|
|
||||||
|
v1 = vector_perp(prism_axis, shaft);
|
||||||
|
v2 = vector_perp(prism_axis, obj1_back);
|
||||||
|
v3 = vector_perp(prism_axis, obj2_back);
|
||||||
|
sign1 = cross(v1,v2)*prism_axis < 0 ? 1 : -1;
|
||||||
|
sign2 = cross(v3,v1)*prism_axis < 0 ? 1 : -1;
|
||||||
|
|
||||||
|
spin1 = sign1 * vector_angle(v1,v2);
|
||||||
|
spin2 = -sign2 * vector_angle(v3,v1);
|
||||||
|
spin = spin_align==1 ? spin1
|
||||||
|
: spin_align==2 ? spin2
|
||||||
|
: spin_align==12 ? mean_angle(spin1,spin2)
|
||||||
|
: spin_align==21 ? mean_angle(spin2,spin1)
|
||||||
|
: assert(false, str("spin_align must be one of 1, 2, 12, or 21 but was ",spin_align));
|
||||||
|
multmatrix(tobase)
|
||||||
|
move(anch_shift)
|
||||||
|
frame_map(x=backdir, z=base_anch_dir)
|
||||||
|
move(shift1){
|
||||||
|
// For debugging spin, shows line in the spin direction
|
||||||
|
//stroke([aux_root,aux_root+unit(obj2_back)*15], width=1,color="lightblue");
|
||||||
|
//stroke([base_root,base_root+unit(obj1_back)*15], width=1,color="lightgreen");
|
||||||
|
|
||||||
|
if (debug_pos)
|
||||||
|
move(base_root)rot(from=UP,to=prism_axis)
|
||||||
|
linear_extrude(height=norm(base_root-aux_root))zrot(base_spin-spin)polygon(profile);
|
||||||
|
else{
|
||||||
|
join_prism(zrot(base_spin-spin,profile),
|
||||||
|
base=base_type, base_r=u_mul(base_r,base_inside),
|
||||||
|
aux=aux_type, aux_T=aux_T, aux_r=u_mul(aux_r,aux_inside),
|
||||||
|
scale=scale,
|
||||||
|
start=base_root, end=aux_root,
|
||||||
|
base_k=base_k, aux_k=aux_k, base_overlap=base_overlap, aux_overlap=aux_overlap,
|
||||||
|
base_n=base_n, aux_n=aux_n, base_fillet=base_fillet, aux_fillet=aux_fillet,
|
||||||
|
base_smooth_normals = base_smooth_normals, aux_smooth_normals=aux_smooth_normals,
|
||||||
|
debug=debug,
|
||||||
|
_name1="desc1", _name2="desc2") children();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -3417,7 +3417,7 @@ function associate_vertices(polygons, split, curpoly=0) =
|
|||||||
// Topics: Textures, Knurling
|
// Topics: Textures, Knurling
|
||||||
// Synopsis: Produce a standard texture.
|
// Synopsis: Produce a standard texture.
|
||||||
// Topics: Extrusion, Textures
|
// Topics: Extrusion, Textures
|
||||||
// See Also: linear_sweep(), rotate_sweep(), heightfield(), cylindrical_heightfield()
|
// See Also: linear_sweep(), rotate_sweep(), cyl(), vnf_vertex_array(), sweep(), path_sweep(), textured_tile()
|
||||||
// Usage:
|
// Usage:
|
||||||
// tx = texture(tex, [n=], [inset=], [gap=], [roughness=]);
|
// tx = texture(tex, [n=], [inset=], [gap=], [roughness=]);
|
||||||
// Description:
|
// Description:
|
||||||
|
@@ -883,7 +883,8 @@ module deprecate(new_name)
|
|||||||
// Usage:
|
// Usage:
|
||||||
// echo_viewport();
|
// echo_viewport();
|
||||||
// Description:
|
// Description:
|
||||||
// Display the current viewport parameters so that they can be pasted into examples for the wiki.
|
// Display the current viewport parameters so that they can be pasted into examples for the wiki.
|
||||||
|
// The viewport should have a 4x3 aspect ratio to ensure proper framing of the object.
|
||||||
|
|
||||||
module echo_viewport()
|
module echo_viewport()
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user