mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-01-17 06:08:32 +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_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_to` is set to `undef`.
|
||||||
// `$attach_norot` is set to `true`.
|
// `$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:
|
// Example:
|
||||||
// spheroid(d=20) {
|
// spheroid(d=20) {
|
||||||
// position(TOP) cyl(l=10, d1=10, d2=5, anchor=BOTTOM);
|
// position(TOP) cyl(l=10, d1=10, d2=5, anchor=BOTTOM);
|
||||||
// position(RIGHT) 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);
|
// 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)
|
module position(from)
|
||||||
{
|
{
|
||||||
req_children($children);
|
req_children($children);
|
||||||
assert($parent_geom != undef, "No object to attach to!");
|
assert($parent_geom != undef, "No object to attach to!");
|
||||||
anchors = (is_vector(from)||is_string(from))? [from] : from;
|
anchors = (is_vector(from)||is_string(from))? [from] : from;
|
||||||
|
two_d = _attach_geom_2d($parent_geom);
|
||||||
for (anchr = anchors) {
|
for (anchr = anchors) {
|
||||||
anch = _find_anchor(anchr, $parent_geom);
|
anch = _find_anchor(anchr, $parent_geom);
|
||||||
$attach_to = undef;
|
$attach_to = undef;
|
||||||
$attach_anchor = anch;
|
$attach_anchor = anch;
|
||||||
$attach_norot = true;
|
$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();
|
translate(anch[1]) children();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -506,6 +541,8 @@ module position(from)
|
|||||||
// PARENT() orient(anchor, [spin]) CHILDREN;
|
// PARENT() orient(anchor, [spin]) CHILDREN;
|
||||||
// Description:
|
// Description:
|
||||||
// Orients children such that their top is tilted in the direction of the specified parent anchor point.
|
// 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).
|
// For a step-by-step explanation of attachments, see the [Attachments Tutorial](Tutorial-Attachments).
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// anchor = The anchor on the parent which you want to match the orientation of.
|
// 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_anchor` is set to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for the `anchor=`, if given.
|
||||||
// `$attach_to` is set to `undef`.
|
// `$attach_to` is set to `undef`.
|
||||||
// `$attach_norot` is set to `true`.
|
// `$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:
|
// Example: When orienting to an anchor, the spin of the anchor may cause confusion:
|
||||||
// prismoid([50,50],[30,30],h=40) {
|
// prismoid([50,50],[30,30],h=40) {
|
||||||
@ -541,16 +579,27 @@ module orient(anchor, spin) {
|
|||||||
anch = _find_anchor(anchor, $parent_geom);
|
anch = _find_anchor(anchor, $parent_geom);
|
||||||
two_d = _attach_geom_2d($parent_geom);
|
two_d = _attach_geom_2d($parent_geom);
|
||||||
fromvec = two_d? BACK : UP;
|
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_to = undef;
|
||||||
$attach_anchor = anch;
|
$attach_anchor = anch;
|
||||||
$attach_norot = true;
|
$attach_norot = true;
|
||||||
spin = default(spin, anch[3]);
|
if (two_d)
|
||||||
assert(is_finite(spin));
|
rot(spin)rot(from=fromvec, to=anch[2]) children();
|
||||||
rot(spin, from=fromvec, to=anch[2]) children();
|
else
|
||||||
|
rot(spin, from=fromvec, to=anch[2]) children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Module: attach()
|
// Module: attach()
|
||||||
// Synopsis: Attaches children to a parent object at an anchor point and orientation.
|
// Synopsis: Attaches children to a parent object at an anchor point and orientation.
|
||||||
// Topics: Attachments
|
// Topics: Attachments
|
||||||
@ -2011,6 +2060,7 @@ module attachable(
|
|||||||
$parent_geom = geom;
|
$parent_geom = geom;
|
||||||
$parent_size = _attach_geom_size(geom);
|
$parent_size = _attach_geom_size(geom);
|
||||||
$attach_to = undef;
|
$attach_to = undef;
|
||||||
|
$align=undef;
|
||||||
if (_is_shown())
|
if (_is_shown())
|
||||||
_color($color) children(0);
|
_color($color) children(0);
|
||||||
if (is_def($save_color)) {
|
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);
|
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.
|
Positioning objects works the same way in 2D.
|
||||||
|
|
||||||
@ -463,6 +488,28 @@ prismoid([50,50],[30,30],h=40)
|
|||||||
anchor_arrow(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
|
## Attachment overview
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user