mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-01-16 21:58:27 +01:00
add position $align
This commit is contained in:
parent
4a4f871ae8
commit
dcfbdfdc71
@ -477,22 +477,57 @@ _ANCHOR_TYPES = ["intersect","hull"];
|
||||
// `$attach_anchor` for each `from=` anchor given, this is set to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for that anchor.
|
||||
// `$attach_to` is set to `undef`.
|
||||
// `$attach_norot` is set to `true`.
|
||||
// `$align` set to the anchor that will position a child flush to the edge of the parent at specified position.
|
||||
// Example:
|
||||
// spheroid(d=20) {
|
||||
// position(TOP) cyl(l=10, d1=10, d2=5, anchor=BOTTOM);
|
||||
// position(RIGHT) cyl(l=10, d1=10, d2=5, anchor=BOTTOM);
|
||||
// position(FRONT) cyl(l=10, d1=10, d2=5, anchor=BOTTOM);
|
||||
// }
|
||||
// Example: Child would require anchor of RIGHT+FRONT+BOT if given explicitly.
|
||||
// cuboid([50,40,15])
|
||||
// position(RIGHT+FRONT+TOP)
|
||||
// color("lightblue")prismoid([10,5],[7,4],height=4, anchor=$align);
|
||||
// Example: Child requires a different anchor for each position, so explicit specification of the anchor is impossible in this case.
|
||||
// cuboid([50,40,15])
|
||||
// position([RIGHT+TOP,LEFT+TOP])
|
||||
// color("lightblue")prismoid([10,5],[7,4],height=4, anchor=$align);
|
||||
// Example: If you try to spin your child, the spin happens after the position anchor, so the child will not be flush:
|
||||
// cuboid([50,40,15])
|
||||
// position([RIGHT+TOP])
|
||||
// color("lightblue")prismoid([10,5],[7,4],height=4,
|
||||
// anchor=$align, spin=90);
|
||||
// Example: You can instead spin the attached children using {{orient()}}. In this example, the required anchor is BOT+FWD, which is less obvious.
|
||||
// cuboid([50,40,15])
|
||||
// position(RIGHT+TOP)
|
||||
// orient(TOP, spin=90)
|
||||
// color("lightblue")prismoid([10,5],[7,4],height=4, anchor=$align);
|
||||
// Example: Of course, {{orient()}} can also place children on different sides of the parent. In this case you don't have to figure out that the required anchor is BOT+BACK.
|
||||
// cuboid([50,40,15])
|
||||
// position(RIGHT+TOP)
|
||||
// orient(RIGHT)
|
||||
// color("lightblue")prismoid([10,5],[7,4],height=4, anchor=$align);
|
||||
// Example: You can combine this with {{diff()}} to remove the child. Note that it's more intuitive to shift the child after positioning, relative to the global coordinate system:
|
||||
// diff()
|
||||
// cuboid([50,40,15])
|
||||
// right(.1)up(.1)
|
||||
// position(RIGHT+TOP)
|
||||
// orient(LEFT)
|
||||
// tag("remove")cuboid([10,5,4], anchor=$align);
|
||||
module position(from)
|
||||
{
|
||||
req_children($children);
|
||||
assert($parent_geom != undef, "No object to attach to!");
|
||||
anchors = (is_vector(from)||is_string(from))? [from] : from;
|
||||
two_d = _attach_geom_2d($parent_geom);
|
||||
for (anchr = anchors) {
|
||||
anch = _find_anchor(anchr, $parent_geom);
|
||||
$attach_to = undef;
|
||||
$attach_anchor = anch;
|
||||
$attach_norot = true;
|
||||
$align=two_d && anchr.y!=0 ? [anchr.x,-anchr.y]
|
||||
:!two_d && anchr.z!=0 ? [anchr.x, anchr.y, -anchr.z]
|
||||
: -anchr;
|
||||
translate(anch[1]) children();
|
||||
}
|
||||
}
|
||||
@ -506,6 +541,8 @@ module position(from)
|
||||
// PARENT() orient(anchor, [spin]) CHILDREN;
|
||||
// Description:
|
||||
// Orients children such that their top is tilted in the direction of the specified parent anchor point.
|
||||
// The `$align` variable can help you anchor the child, aligned with the edges of the parent, based
|
||||
// on the position specified by a parent {{position()}} module. See {{position()}} for examples using `$align`.
|
||||
// For a step-by-step explanation of attachments, see the [Attachments Tutorial](Tutorial-Attachments).
|
||||
// Arguments:
|
||||
// anchor = The anchor on the parent which you want to match the orientation of.
|
||||
@ -514,6 +551,7 @@ module position(from)
|
||||
// `$attach_anchor` is set to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for the `anchor=`, if given.
|
||||
// `$attach_to` is set to `undef`.
|
||||
// `$attach_norot` is set to `true`.
|
||||
// `$align` is set to the anchor that will position the child flush on the parent at a designated {{position()}}
|
||||
//
|
||||
// Example: When orienting to an anchor, the spin of the anchor may cause confusion:
|
||||
// prismoid([50,50],[30,30],h=40) {
|
||||
@ -541,16 +579,27 @@ module orient(anchor, spin) {
|
||||
anch = _find_anchor(anchor, $parent_geom);
|
||||
two_d = _attach_geom_2d($parent_geom);
|
||||
fromvec = two_d? BACK : UP;
|
||||
spin = default(spin, anch[3]);
|
||||
assert(is_finite(spin));
|
||||
|
||||
$align = is_undef($attach_anchor) ? undef
|
||||
: two_d ? let(newalign=rot(from=anch[2], to=fromvec, p=zrot(-spin,$attach_anchor[0])))
|
||||
[sign(newalign.x), -1]
|
||||
: let(newalign=rot(spin, from=fromvec, to=anch[2], reverse=true, p=$attach_anchor[0]))
|
||||
[sign(newalign.x), sign(newalign.y), -1];
|
||||
$attach_to = undef;
|
||||
$attach_anchor = anch;
|
||||
$attach_norot = true;
|
||||
spin = default(spin, anch[3]);
|
||||
assert(is_finite(spin));
|
||||
rot(spin, from=fromvec, to=anch[2]) children();
|
||||
if (two_d)
|
||||
rot(spin)rot(from=fromvec, to=anch[2]) children();
|
||||
else
|
||||
rot(spin, from=fromvec, to=anch[2]) children();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Module: attach()
|
||||
// Synopsis: Attaches children to a parent object at an anchor point and orientation.
|
||||
// Topics: Attachments
|
||||
@ -2011,6 +2060,7 @@ module attachable(
|
||||
$parent_geom = geom;
|
||||
$parent_size = _attach_geom_size(geom);
|
||||
$attach_to = undef;
|
||||
$align=undef;
|
||||
if (_is_shown())
|
||||
_color($color) children(0);
|
||||
if (is_def($save_color)) {
|
||||
|
@ -375,6 +375,31 @@ cube([50,50,20],center=true)
|
||||
position(TOP+RIGHT) left(5) cube([4,50,10], anchor=RIGHT+BOT);
|
||||
```
|
||||
|
||||
When you position a child at an edge or corner of a parent object, you very likely
|
||||
need to change the anchor for the child in a matching way to align the child with the surface and edge
|
||||
of the parent. You can automate this process by making use of the `$align` special variable, which
|
||||
is set by `position()`. To align a child with a corner you can do:
|
||||
|
||||
```openscad-3D
|
||||
include<BOSL2/std.scad>
|
||||
cuboid([50,40,15])
|
||||
position(RIGHT+FRONT+TOP)
|
||||
color("lightblue")prismoid([10,5],[7,4],height=4, anchor=$align);
|
||||
```
|
||||
|
||||
In this example, the `$align` variable replaces the explicit anchor of `RIGHT+FRONT+BOT` that
|
||||
would be required for this case. The `position()` module can also accept a list of positions,
|
||||
and it will place a copy of the child at each location. However, if you want to align multiple
|
||||
children to the parent in different locations, each child needs a different anchor. This can
|
||||
be achieved using the `$align` variable:
|
||||
|
||||
```openscad-3D
|
||||
cuboid([50,40,15])
|
||||
position([RIGHT+TOP,LEFT+TOP])
|
||||
color("lightblue")prismoid([10,5],[7,4],height=4, anchor=$align);
|
||||
```
|
||||
|
||||
|
||||
|
||||
Positioning objects works the same way in 2D.
|
||||
|
||||
@ -463,6 +488,28 @@ prismoid([50,50],[30,30],h=40)
|
||||
anchor_arrow(40);
|
||||
```
|
||||
|
||||
The potential confusion that spin creates for the proper anchoring of children
|
||||
can be eliminated using the `$align` variable which takes into account the spin
|
||||
that the `orient()` module applies.
|
||||
|
||||
```openscad-3D
|
||||
cuboid([50,40,15])
|
||||
position(RIGHT+TOP)
|
||||
orient(RIGHT)
|
||||
color("lightblue")prismoid([10,5],[7,4],height=4, anchor=$align);
|
||||
```
|
||||
|
||||
In this case, the correct anchor is chosen to place the child on the right side
|
||||
with the appropriate anchor taking the spin into account. You can use this method
|
||||
for children placed on the top by using orient with a TOP direction, but nonzero spin.
|
||||
|
||||
```openscad-3D
|
||||
cuboid([50,40,15])
|
||||
position(RIGHT+TOP)
|
||||
orient(TOP, spin=90)
|
||||
color("lightblue")prismoid([10,5],[7,4],height=4, anchor=$align);
|
||||
```
|
||||
|
||||
|
||||
## Attachment overview
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user