mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
fix anchor bug for non-orthogonal spins
change regular_prism side face anchors to point UP
This commit is contained in:
parent
9ac540e03d
commit
51fbe696b1
3 changed files with 57 additions and 50 deletions
|
@ -3180,12 +3180,12 @@ function attach_geom(
|
||||||
assert(is_list(anchors))
|
assert(is_list(anchors))
|
||||||
assert(is_bool(two_d))
|
assert(is_bool(two_d))
|
||||||
assert(is_vector(axis))
|
assert(is_vector(axis))
|
||||||
|
let(
|
||||||
|
over_f = is_undef(override) ? function(anchor) [undef,undef,undef]
|
||||||
|
: is_func(override) ? override
|
||||||
|
: function(anchor) _local_struct_val(override,anchor)
|
||||||
|
)
|
||||||
!is_undef(size)? (
|
!is_undef(size)? (
|
||||||
let(
|
|
||||||
over_f = is_undef(override) ? function(anchor) [undef,undef,undef]
|
|
||||||
: is_func(override) ? override
|
|
||||||
: function(anchor) _local_struct_val(override,anchor)
|
|
||||||
)
|
|
||||||
two_d? (
|
two_d? (
|
||||||
let(
|
let(
|
||||||
size2 = default(size2, size.x),
|
size2 = default(size2, size.x),
|
||||||
|
@ -3208,8 +3208,8 @@ function attach_geom(
|
||||||
) : !is_undef(vnf)? (
|
) : !is_undef(vnf)? (
|
||||||
assert(is_vnf(vnf))
|
assert(is_vnf(vnf))
|
||||||
assert(two_d == false)
|
assert(two_d == false)
|
||||||
extent? ["vnf_extent", vnf, cp, offset, anchors] :
|
extent? ["vnf_extent", vnf, over_f, cp, offset, anchors]
|
||||||
["vnf_isect", vnf, cp, offset, anchors]
|
: ["vnf_isect", vnf, over_f, cp, offset, anchors]
|
||||||
) : !is_undef(region)? (
|
) : !is_undef(region)? (
|
||||||
assert(is_region(region),2)
|
assert(is_region(region),2)
|
||||||
let( l = default(l, h) )
|
let( l = default(l, h) )
|
||||||
|
@ -3467,32 +3467,32 @@ function _attach_transform(anchor, spin, orient, geom, p) =
|
||||||
spin = default(spin, 0),
|
spin = default(spin, 0),
|
||||||
orient = default(orient, UP),
|
orient = default(orient, UP),
|
||||||
two_d = _attach_geom_2d(geom),
|
two_d = _attach_geom_2d(geom),
|
||||||
m = ($attach_to != undef)? ( // $attach_to is the attachment point on this object
|
m = ($attach_to != undef) ? // $attach_to is the attachment point on this object
|
||||||
let( // which will attach to the parent
|
( // which will attach to the parent
|
||||||
anch = _find_anchor($attach_to, geom),
|
let(
|
||||||
// if $anchor_override is set it defines the object position anchor (but note not direction or spin).
|
anch = _find_anchor($attach_to, geom),
|
||||||
// Otherwise we use the provided anchor for the object.
|
// if $anchor_override is set it defines the object position anchor (but note not direction or spin).
|
||||||
pos = is_undef($anchor_override) ? anch[1]
|
// Otherwise we use the provided anchor for the object.
|
||||||
: _find_anchor(_make_anchor_legal($anchor_override,geom),geom)[1]
|
pos = is_undef($anchor_override) ? anch[1]
|
||||||
)
|
: _find_anchor(_make_anchor_legal($anchor_override,geom),geom)[1]
|
||||||
two_d?
|
)
|
||||||
assert(is_num(spin))
|
two_d?
|
||||||
/*affine3d_zrot(spin) * */
|
assert(is_num(spin))
|
||||||
rot(to=FWD, from=point3d(anch[2]))
|
affine3d_zrot(spin)
|
||||||
* affine3d_translate(point3d(-pos))
|
* rot(to=FWD, from=point3d(anch[2]))
|
||||||
:
|
* affine3d_translate(point3d(-pos))
|
||||||
let(
|
:
|
||||||
ang = vector_angle(anch[2], DOWN), // anch[2] is the anchor direction vector
|
let(
|
||||||
axis = vector_axis(anch[2], DOWN),
|
spinT = is_num(spin) ? affine3d_zrot(-anch[3]-spin)
|
||||||
ang2 = (anch[2]==UP || anch[2]==DOWN)? 0 : 180-anch[3],
|
: affine3d_zrot(-spin.z) * affine3d_yrot(-spin.y) * affine3d_xrot(-spin.x)
|
||||||
axis2 = rot(p=axis,[0,0,ang2])
|
* affine3d_zrot(-anch[3])
|
||||||
)
|
)
|
||||||
affine3d_rot_by_axis(axis2,ang)
|
affine3d_yrot(180)
|
||||||
* (is_num(spin)? affine3d_zrot(ang2+spin)
|
* spinT
|
||||||
: affine3d_zrot(spin.z) * affine3d_yrot(spin.y) * affine3d_xrot(spin.x)
|
* rot(from=anch[2],to=UP)
|
||||||
* affine3d_zrot(ang2))
|
* affine3d_translate(point3d(-pos))
|
||||||
* affine3d_translate(point3d(-pos))
|
)
|
||||||
) : (
|
:
|
||||||
let(
|
let(
|
||||||
anchor = is_undef($attach_alignment) ? anchor
|
anchor = is_undef($attach_alignment) ? anchor
|
||||||
: two_d? _make_anchor_legal(zrot(-spin,$attach_alignment),geom)
|
: two_d? _make_anchor_legal(zrot(-spin,$attach_alignment),geom)
|
||||||
|
@ -3503,7 +3503,6 @@ function _attach_transform(anchor, spin, orient, geom, p) =
|
||||||
assert(is_num(spin))
|
assert(is_num(spin))
|
||||||
affine3d_zrot(spin) * affine3d_translate(point3d(-pos))
|
affine3d_zrot(spin) * affine3d_translate(point3d(-pos))
|
||||||
:
|
:
|
||||||
assert(is_num(spin) || is_vector(spin,3))
|
|
||||||
let(
|
let(
|
||||||
axis = vector_axis(UP,orient), // Returns BACK if orient is UP
|
axis = vector_axis(UP,orient), // Returns BACK if orient is UP
|
||||||
ang = vector_angle(UP,orient)
|
ang = vector_angle(UP,orient)
|
||||||
|
@ -3512,7 +3511,6 @@ function _attach_transform(anchor, spin, orient, geom, p) =
|
||||||
* ( is_num(spin)? affine3d_zrot(spin)
|
* ( is_num(spin)? affine3d_zrot(spin)
|
||||||
: affine3d_zrot(spin.z) * affine3d_yrot(spin.y) * affine3d_xrot(spin.x))
|
: affine3d_zrot(spin.z) * affine3d_yrot(spin.y) * affine3d_xrot(spin.x))
|
||||||
* affine3d_translate(point3d(-pos))
|
* affine3d_translate(point3d(-pos))
|
||||||
)
|
|
||||||
)
|
)
|
||||||
is_undef(p)? m
|
is_undef(p)? m
|
||||||
: is_vnf(p) && p==EMPTY_VNF? p
|
: is_vnf(p) && p==EMPTY_VNF? p
|
||||||
|
@ -3681,8 +3679,11 @@ function _find_anchor(anchor, geom) =
|
||||||
vec = unit(v_mul(r,anchor),UP)
|
vec = unit(v_mul(r,anchor),UP)
|
||||||
) [anchor, pos, vec, oang]
|
) [anchor, pos, vec, oang]
|
||||||
) : type == "vnf_isect"? ( //vnf
|
) : type == "vnf_isect"? ( //vnf
|
||||||
let( vnf=geom[1] )
|
let(
|
||||||
approx(anchor,CTR)? [anchor, cp, UP, 0] : // CENTER anchors anchor on cp, "origin" anchors on [0,0]
|
vnf=geom[1],
|
||||||
|
override = geom[2](anchor)
|
||||||
|
) // CENTER anchors anchor on cp, "origin" anchors on [0,0]
|
||||||
|
approx(anchor,CTR)? [anchor, default(override[0],cp),default(override[1],UP),default(override[2], 0)] :
|
||||||
vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor), 0] :
|
vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor), 0] :
|
||||||
let(
|
let(
|
||||||
eps = 1/2048,
|
eps = 1/2048,
|
||||||
|
@ -3729,10 +3730,13 @@ function _find_anchor(anchor, geom) =
|
||||||
n = unit(sum(unorms)),
|
n = unit(sum(unorms)),
|
||||||
oang = approx(point2d(n), [0,0])? 0 : atan2(n.y, n.x) + 90
|
oang = approx(point2d(n), [0,0])? 0 : atan2(n.y, n.x) + 90
|
||||||
)
|
)
|
||||||
[anchor, pos, n, oang]
|
[anchor, default(override[0],pos),default(override[1], n),default(override[2], oang)]
|
||||||
) : type == "vnf_extent"? ( //vnf
|
) : type == "vnf_extent"? ( //vnf
|
||||||
let( vnf=geom[1] )
|
let(
|
||||||
approx(anchor,CTR)? [anchor, cp, UP, 0] : // CENTER anchors anchor on cp, "origin" anchors on [0,0]
|
vnf=geom[1],
|
||||||
|
override = geom[2](anchor)
|
||||||
|
) // CENTER anchors anchor on cp, "origin" anchors on [0,0]
|
||||||
|
approx(anchor,CTR)? [anchor, default(override[0],cp),default(override[1],UP),default(override[2], 0)] :
|
||||||
vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor,UP), 0] :
|
vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor,UP), 0] :
|
||||||
let(
|
let(
|
||||||
rpts = apply(rot(from=anchor, to=RIGHT) * move(point3d(-cp)), vnf[0]),
|
rpts = apply(rot(from=anchor, to=RIGHT) * move(point3d(-cp)), vnf[0]),
|
||||||
|
@ -3741,7 +3745,7 @@ function _find_anchor(anchor, geom) =
|
||||||
avep = sum(select(rpts,idxs))/len(idxs),
|
avep = sum(select(rpts,idxs))/len(idxs),
|
||||||
mpt = approx(point2d(anchor),[0,0])? [maxx,0,0] : avep,
|
mpt = approx(point2d(anchor),[0,0])? [maxx,0,0] : avep,
|
||||||
pos = point3d(cp) + rot(from=RIGHT, to=anchor, p=mpt)
|
pos = point3d(cp) + rot(from=RIGHT, to=anchor, p=mpt)
|
||||||
) [anchor, pos, anchor, oang]
|
) [anchor, default(override[0],pos),default(override[1],anchor),default(override[2],oang)]
|
||||||
) : type == "trapezoid"? ( //size, size2, shift, override
|
) : type == "trapezoid"? ( //size, size2, shift, override
|
||||||
let(all_comps_good = [for (c=anchor) if (c!=sign(c)) 1]==[])
|
let(all_comps_good = [for (c=anchor) if (c!=sign(c)) 1]==[])
|
||||||
assert(all_comps_good, "All components of an anchor for a rectangle/trapezoid must be -1, 0, or 1")
|
assert(all_comps_good, "All components of an anchor for a rectangle/trapezoid must be -1, 0, or 1")
|
||||||
|
|
|
@ -873,12 +873,12 @@ function octahedron(size=1, anchor=CENTER, spin=0, orient=UP) =
|
||||||
// different `$fn` than the number of prism faces, you can apply texture to the flat faces without forcing a high facet count,
|
// different `$fn` than the number of prism faces, you can apply texture to the flat faces without forcing a high facet count,
|
||||||
// anchors are located on the true object instead of the ideal cylinder and you can anchor to the edges and faces.
|
// anchors are located on the true object instead of the ideal cylinder and you can anchor to the edges and faces.
|
||||||
// Named Anchors:
|
// Named Anchors:
|
||||||
// "edge0", "edge1", etc. = Center of each side edge
|
// "edge0", "edge1", etc. = Center of each side edge, spin pointing up along the edge
|
||||||
// "face0", "face1", etc. = Center of each side face
|
// "face0", "face1", etc. = Center of each side face, spin pointing up
|
||||||
// "topedge0", "topedge1", etc = Center of each top edge, pointing in direction of associated side face
|
// "topedge0", "topedge1", etc = Center of each top edge, pointing in direction of associated side face, spin up
|
||||||
// "botedge0", "botedge1", etc = Center of each bottom edge, pointing in direction of associated side face
|
// "botedge0", "botedge1", etc = Center of each bottom edge, pointing in direction of associated side face, spin up
|
||||||
// "topcorner0", "topcorner1", etc = Top corner, pointing in direction of associated edge anchor
|
// "topcorner0", "topcorner1", etc = Top corner, pointing in direction of associated edge anchor, spin up along associated edge
|
||||||
// "botcorner0", "botcorner1", etc = Bottom corner, pointing in direction of associated edge anchor
|
// "botcorner0", "botcorner1", etc = Bottom corner, pointing in direction of associated edge anchor, spin up along associated edge
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// l / h / length / height = Length of prism
|
// l / h / length / height = Length of prism
|
||||||
// r = Outer radius of prism.
|
// r = Outer radius of prism.
|
||||||
|
@ -1162,7 +1162,8 @@ function regular_prism(n,
|
||||||
Mface = skmat*zrot(-(i+1/2)*360/n),
|
Mface = skmat*zrot(-(i+1/2)*360/n),
|
||||||
faceedge = faces[i][1],
|
faceedge = faces[i][1],
|
||||||
facenormal = faces[i][0],
|
facenormal = faces[i][0],
|
||||||
facespin = _compute_spin(facenormal, faceedge),
|
//facespin = _compute_spin(facenormal, faceedge), // spin along centerline of face instea of pointing up---seems to be wrong choice
|
||||||
|
facespin = _compute_spin(facenormal, UP),
|
||||||
edgenormal = unit(vector_bisect(facenormal,select(faces,i-1)[0])),
|
edgenormal = unit(vector_bisect(facenormal,select(faces,i-1)[0])),
|
||||||
Medge = skmat*zrot(-i*360/n),
|
Medge = skmat*zrot(-i*360/n),
|
||||||
edge = faces[i][2],
|
edge = faces[i][2],
|
||||||
|
@ -1179,7 +1180,9 @@ function regular_prism(n,
|
||||||
],
|
],
|
||||||
override = approx(shift,[0,0]) ? undef : [[UP, [point3d(shift,height/2), UP]]]
|
override = approx(shift,[0,0]) ? undef : [[UP, [point3d(shift,height/2), UP]]]
|
||||||
)
|
)
|
||||||
[reorient(anchor,spin,orient, vnf=ovnf, p=ovnf,anchors=anchors, override=override),anchors,override];
|
[reorient(anchor,spin,orient, vnf=ovnf, p=ovnf,anchors=anchors, override=override),anchors,override];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Module: rect_tube()
|
// Module: rect_tube()
|
||||||
|
|
2
vnf.scad
2
vnf.scad
|
@ -1055,7 +1055,7 @@ function _slice_3dpolygons(polys, dir, cuts) =
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// vnf = A VNF structure, or list of VNF structures.
|
// vnf = A VNF structure, or list of VNF structures.
|
||||||
// convexity = Max number of times a line could intersect a wall of the shape.
|
// convexity = Max number of times a line could intersect a wall of the shape.
|
||||||
// cp = Centerpoint for determining intersection anchors or centering the shape. Determintes the base of the anchor vector. Can be "centroid", "mean", "box" or a 3D point. Default: "centroid"
|
// cp = Centerpoint for determining intersection anchors or centering the shape. Determines the base of the anchor vector. Can be "centroid", "mean", "box" or a 3D point. Default: "centroid"
|
||||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `"origin"`
|
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `"origin"`
|
||||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
// 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`
|
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||||
|
|
Loading…
Reference in a new issue