mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-28 07:49:45 +00:00
commit
9717497174
4 changed files with 101 additions and 95 deletions
|
@ -101,19 +101,22 @@ _ANCHOR_TYPES = ["intersect","hull"];
|
|||
// motors have anchors for `"screw1"`, `"screw2"`, etc. to refer to the various screwholes on the
|
||||
// stepper motor shape. The names, positions, directions, and spins of these anchors are
|
||||
// specific to the object, and are documented when they exist.
|
||||
// .
|
||||
// The anchor argument is ignored if you use {{align()}} or the two-argument form of {{attach()}} because
|
||||
// these modules provide their own anchoring for their children.
|
||||
// Subsection: Spin
|
||||
// Spin is specified with the `spin` argument in most shape modules. Specifying a spin`
|
||||
// Spin is specified with the `spin` argument in most shape modules. Specifying a spin
|
||||
// angle when creating an object will rotate the object counter-clockwise around the Z axis by the given
|
||||
// number of degrees. Spin is always applied after anchoring, and before orientation.
|
||||
// Since spin is applied after anchoring it is not always what you might think of intuitively
|
||||
// as spinning the shape. To do that, apply `zrot()` to the shape before anchoring.
|
||||
// Since spin is applied **after** anchoring it does not, in general, rotate around the object's center,
|
||||
// so it is not always what you might think of intuitively as spinning the shape.
|
||||
// Subsection: Orient
|
||||
// Orientation is specified with the `orient` argument in most shape modules. Specifying `orient`
|
||||
// when creating an object will rotate the object such that the top of the object will be pointed
|
||||
// at the vector direction given in the `orient` argument. Orientation is always applied after
|
||||
// anchoring and spin. The constants `UP`, `DOWN`, `FRONT`, `BACK`, `LEFT`, and `RIGHT` can be
|
||||
// added together to form the directional vector for this (e.g. `LEFT+BACK`). The orient parameter
|
||||
// is ignored when you use {{attach()}} because {{attach()}} provides its own orientation.
|
||||
// is ignored when you use {{attach()}} with two arguments, because {{attach()}} provides its own orientation.
|
||||
// Subsection: Specifying Directions
|
||||
// You can use direction vectors to specify anchors for objects or to specify edges, faces, and
|
||||
// corners of cubes. You can simply specify these direction vectors numerically, but another
|
||||
|
@ -612,7 +615,7 @@ module orient(anchor, spin) {
|
|||
// `$align` set to the align value used for the child.
|
||||
// `$idx` set to a unique index for each child, increasing by alignment first.
|
||||
// `$attach_anchor` for each anchor given, this is set to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for that anchor.
|
||||
// if inside is true then set default tag to "remove"
|
||||
// if `inside` is true then set default tag to "remove"
|
||||
// Example: Cuboid positioned on the right of its parent. Note that it is in its native orientation.
|
||||
// cuboid([20,35,25])
|
||||
// align(RIGHT)
|
||||
|
@ -659,10 +662,10 @@ module orient(anchor, spin) {
|
|||
// cuboid([40,30,10])
|
||||
// align(FRONT,TOP,inside=true,shiftout=0.01)
|
||||
// prismoid([10,5],[7,5],height=4);
|
||||
// Example: Setting inset shifts all of the children away from their aligned edge, which is a different direction for each child.
|
||||
// Example: Setting `inset` shifts all of the children away from their aligned edge, which is a different direction for each child.
|
||||
// cuboid([40,30,30])
|
||||
// align(FRONT,[TOP,BOT,LEFT,RIGHT,TOP+RIGHT,BOT+LEFT], inset=3)
|
||||
// color("green") cuboid(2);
|
||||
// color("green") cuboid(5);
|
||||
// Example: Changing the child characteristics based on the alignment
|
||||
// cuboid([20,20,8])
|
||||
// align(TOP,[for(i=[-1:1], j=[-1:1]) [i,j]])
|
||||
|
@ -867,14 +870,14 @@ function _make_anchor_legal(anchor,geom) =
|
|||
// Example: Using the `overlap` option can help:
|
||||
// spheroid(d=20)
|
||||
// attach([1,1.5,1], BOTTOM, overlap=1.5) cyl(l=11.5, d1=10, d2=5);
|
||||
// Example: Alignment works for cylinders but you can only align with either the top or bototm face:
|
||||
// Example: Alignment works on the sides of cylinders but you can only align with either the top or bototm face:
|
||||
// cyl(h=30,d=10)
|
||||
// attach([LEFT,[1,1.3]], BOT,align=TOP) cuboid(6);
|
||||
// Example: Attaching to edges. The light blue and orange objects are attached to edges. The purple object is attached to an edge and aligned.
|
||||
// prismoid([20,10],[10,10],7){
|
||||
// attach(RIGHT+TOP,BOT,align=FRONT) color("pink")cuboid(2);
|
||||
// attach(BACK+TOP, BOT) color("lightblue")cuboid(2);
|
||||
// attach(RIGHT+BOT, RIGHT,spin=90) color("orange")cyl(h=8,d=1);
|
||||
// attach(RIGHT+BOT, RIGHT) color("orange")cyl(h=8,d=1);
|
||||
// }
|
||||
// Example: Attaching inside the parent. For inside attachment the anchors are lined up pointing the same direction, so the most natural way to anchor the child is using its TOP anchor. This is equivalent to anchoring outside with the BOTTOM anchor and then lowering the child into the parent by its full depth.
|
||||
// back_half()
|
||||
|
@ -2973,10 +2976,11 @@ module attachable(
|
|||
dummy1 =
|
||||
assert($children==2, "attachable() expects exactly two children; the shape to manage, and the union of all attachment candidates.")
|
||||
assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("Invalid anchor: ",anchor))
|
||||
assert(is_undef(spin) || is_vector(spin,3) || is_num(spin), str("Invalid spin: ",spin))
|
||||
assert(is_undef(spin) || is_finite(spin), str("Invalid spin: ",spin))
|
||||
assert(is_undef(orient) || is_vector(orient,3), str("Invalid orient: ",orient));
|
||||
anchor = first_defined([anchor, CENTER]);
|
||||
spin = default(spin, 0);
|
||||
assert(in_list(v_abs(axis),[UP,RIGHT,BACK]), "axis must be a coordinate direction");
|
||||
anchor = default(anchor,CENTER);
|
||||
spin = default(spin,0);
|
||||
orient = is_def($anchor_override)? UP : default(orient, UP);
|
||||
region = !is_undef(region)? region :
|
||||
!is_undef(path)? [path] :
|
||||
|
@ -3131,9 +3135,9 @@ function reorient(
|
|||
geom,
|
||||
p=undef
|
||||
) =
|
||||
assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("Got: ",anchor))
|
||||
assert(is_undef(spin) || is_vector(spin,3) || is_num(spin), str("Got: ",spin))
|
||||
assert(is_undef(orient) || is_vector(orient,3), str("Got: ",orient))
|
||||
assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("Invalid anchor: ",anchor))
|
||||
assert(is_undef(spin) || is_finite(spin), str("Invalid spin: ",spin))
|
||||
assert(is_undef(orient) || is_vector(orient,3), str("Invalid orient: ",orient))
|
||||
let(
|
||||
anchor = default(anchor, CENTER),
|
||||
spin = default(spin, 0),
|
||||
|
@ -3616,12 +3620,12 @@ function _attach_geom_edge_path(geom, edge) =
|
|||
|
||||
function _attach_transform(anchor, spin, orient, geom, p) =
|
||||
assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("Invalid anchor: ",anchor))
|
||||
assert(is_undef(spin) || is_vector(spin,3) || is_num(spin), str("Invalid spin: ",spin))
|
||||
assert(is_undef(spin) || is_finite(spin), str("Invalid spin: ",spin))
|
||||
assert(is_undef(orient) || is_vector(orient,3), str("Invalid orient: ",orient))
|
||||
let(
|
||||
anchor = default(anchor, CENTER),
|
||||
spin = default(spin, 0),
|
||||
orient = default(orient, UP),
|
||||
anchor=default(anchor,CENTER),
|
||||
spin=default(spin,0),
|
||||
orient=default(orient,UP),
|
||||
two_d = _attach_geom_2d(geom),
|
||||
m = ($attach_to != undef) ? // $attach_to is the attachment point on this object
|
||||
( // which will attach to the parent
|
||||
|
|
|
@ -2050,10 +2050,9 @@ function reuleaux_polygon(n=3, r, d, anchor=CENTER, spin=0) =
|
|||
module text(text, size=10, font, halign, valign, spacing=1.0, direction="ltr", language="en", script="latin", anchor="baseline", spin=0) {
|
||||
no_children($children);
|
||||
dummy1 =
|
||||
assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("Got: ",anchor))
|
||||
assert(is_undef(spin) || is_vector(spin,3) || is_num(spin), str("Got: ",spin));
|
||||
assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("Invalid anchor: ",anchor))
|
||||
assert(is_finite(spin), str("Invalid spin: ",spin));
|
||||
anchor = default(anchor, CENTER);
|
||||
spin = default(spin, 0);
|
||||
geom = attach_geom(size=[size,size],two_d=true);
|
||||
anch = !any([for (c=anchor) c=="["])? anchor :
|
||||
let(
|
||||
|
|
|
@ -681,54 +681,6 @@ prismoid(150,60,100)
|
|||
show_anchors(s=45);
|
||||
```
|
||||
|
||||
Is is also possible to attach to edges and corners of the parent
|
||||
object. The anchors for edges spin the child so its BACK direction is
|
||||
aligned with the edge. If the edge belongs to a top or bottom
|
||||
horizontal face, then the BACK directions will point clockwise around
|
||||
the face, as seen from outside the shape. (This is the same direction
|
||||
required for construction of valid faces in OpenSCAD.) Otherwise, the
|
||||
BACK direction will point upwards.
|
||||
|
||||
Examine the red flags below, where only edge anchors appear on a
|
||||
prismoid. The top face shows the red flags pointing clockwise.
|
||||
The sloped side edges point along the edges, generally upward, and
|
||||
the bottom ones appear to point counter-clockwise, but if we viewed
|
||||
the shape from the bottom they would also appear clockwise.
|
||||
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
prismoid([100,175],[55,88], h=55)
|
||||
for(i=[-1:1], j=[-1:1], k=[-1:1])
|
||||
let(anchor=[i,j,k])
|
||||
if (sum(v_abs(anchor))==2)
|
||||
attach(anchor,BOT)anchor_arrow(40);
|
||||
```
|
||||
|
||||
In this example cylinders sink half-way into the top edges of the
|
||||
prismoid:
|
||||
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
$fn=16;
|
||||
r=6;
|
||||
prismoid([100,175],[55,88], h=55){
|
||||
attach([TOP+RIGHT,TOP+LEFT],LEFT,overlap=r/2) cyl(r=r,l=88+2*r,rounding=r);
|
||||
attach([TOP+FWD,TOP+BACK],LEFT,overlap=r/2) cyl(r=r,l=55+2*r, rounding=r);
|
||||
}
|
||||
```
|
||||
|
||||
This type of edge attachment is useful for attaching 3d edge masks to
|
||||
edges:
|
||||
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
$fn=32;
|
||||
diff()
|
||||
cuboid(75)
|
||||
attach([FRONT+LEFT, FRONT+RIGHT, BACK+LEFT, BACK+RIGHT],
|
||||
FWD+LEFT,inside=true)
|
||||
rounding_edge_mask(l=76, r1=8,r2=28);
|
||||
```
|
||||
|
||||
## Parent-Child Anchor Attachment (Double Argument Attachment)
|
||||
|
||||
|
@ -1098,6 +1050,55 @@ cylinder(d1=30,d2=15,h=25)
|
|||
cylinder(d1=30,d2=15,h=25);
|
||||
```
|
||||
|
||||
Is is also possible to attach to edges and corners of the parent
|
||||
object. The anchors for edges spin the child so its BACK direction is
|
||||
aligned with the edge. If the edge belongs to a top or bottom
|
||||
horizontal face, then the BACK directions will point clockwise around
|
||||
the face, as seen from outside the shape. (This is the same direction
|
||||
required for construction of valid faces in OpenSCAD.) Otherwise, the
|
||||
BACK direction will point upwards.
|
||||
|
||||
Examine the red flags below, where only edge anchors appear on a
|
||||
prismoid. The top face shows the red flags pointing clockwise.
|
||||
The sloped side edges point along the edges, generally upward, and
|
||||
the bottom ones appear to point counter-clockwise, but if we viewed
|
||||
the shape from the bottom they would also appear clockwise.
|
||||
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
prismoid([100,175],[55,88], h=55)
|
||||
for(i=[-1:1], j=[-1:1], k=[-1:1])
|
||||
let(anchor=[i,j,k])
|
||||
if (sum(v_abs(anchor))==2)
|
||||
attach(anchor,BOT)anchor_arrow(40);
|
||||
```
|
||||
|
||||
In this example cylinders sink half-way into the top edges of the
|
||||
prismoid:
|
||||
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
$fn=16;
|
||||
r=6;
|
||||
prismoid([100,175],[55,88], h=55){
|
||||
attach([TOP+RIGHT,TOP+LEFT],LEFT,overlap=r/2) cyl(r=r,l=88+2*r,rounding=r);
|
||||
attach([TOP+FWD,TOP+BACK],LEFT,overlap=r/2) cyl(r=r,l=55+2*r, rounding=r);
|
||||
}
|
||||
```
|
||||
|
||||
This type of edge attachment is useful for attaching 3d edge masks to
|
||||
edges:
|
||||
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
$fn=32;
|
||||
diff()
|
||||
cuboid(75)
|
||||
attach([FRONT+LEFT, FRONT+RIGHT, BACK+LEFT, BACK+RIGHT],
|
||||
FWD+LEFT,inside=true)
|
||||
rounding_edge_mask(l=76, r1=8,r2=28);
|
||||
```
|
||||
|
||||
## Parent Anchor Attachment (Single Argument Attachment)
|
||||
|
||||
The second form of attachment is parent anchor attachment, which just
|
||||
|
@ -1278,7 +1279,7 @@ cube(100, center=true)
|
|||
}
|
||||
```
|
||||
|
||||
Remember that tags are inherited by children. In this case, we need to explicitly
|
||||
Remember that tags applied with `tag()` are inherited by children. In this case, we need to explicitly
|
||||
untag the first cylinder (or change its tag to something else), or it
|
||||
will inherit the "keep" tag and get kept.
|
||||
|
||||
|
@ -1292,6 +1293,16 @@ tag("keep")cube(100, center=true)
|
|||
}
|
||||
```
|
||||
|
||||
You can apply a tag that is not propagated to the children using
|
||||
`tag_this()`. The above example could then be redone:
|
||||
|
||||
diff("hole", "keep")
|
||||
tag_this("keep")cube(100, center=true)
|
||||
attach([RIGHT,TOP]) {
|
||||
cylinder(d=95, h=5);
|
||||
tag("hole") cylinder(d=50, h=11, anchor=CTR);
|
||||
}
|
||||
|
||||
|
||||
You can of course apply `tag()` to several children.
|
||||
|
||||
|
@ -1361,7 +1372,8 @@ intersection is computed between the union of the `intersect` tagged objects and
|
|||
the objects that don't match any listed tags. Finally the objects listed in `keep` are union
|
||||
ed with the result.
|
||||
|
||||
In this example the parent is intersected with a conical bounding shape.
|
||||
In this example the parent (untagged) is intersected with a conical
|
||||
bounding shape, which is tagged with the intersect tag.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
|
@ -1659,7 +1671,7 @@ arguments of `attachable()`.
|
|||
In the most basic form, where the shape is fully cuboid, with top and bottom of the same size,
|
||||
and directly over one another, you can just use `size=`.
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) {
|
||||
attachable(anchor,spin,orient, size=[s*3,s,s]) {
|
||||
|
@ -1677,7 +1689,7 @@ When the shape is prismoidal, where the top is a different size from the bottom,
|
|||
the `size2=` argument as well. While `size=` takes all three axes sizes, the `size2=` argument
|
||||
only takes the [X,Y] sizes of the top of the shape.
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
module prismoidal(size=[100,100,100], scale=0.5, anchor=CENTER, spin=0, orient=UP) {
|
||||
attachable(anchor,spin,orient, size=size, size2=[size.x, size.y]*scale) {
|
||||
|
@ -1699,7 +1711,7 @@ When the top of the prismoid can be shifted away from directly above the bottom,
|
|||
the `shift=` argument. The `shift=` argument takes an [X,Y] vector of the offset of the center
|
||||
of the top from the XY center of the bottom of the shape.
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
module prismoidal(size=[100,100,100], scale=0.5, shift=[0,0], anchor=CENTER, spin=0, orient=UP) {
|
||||
attachable(anchor,spin,orient, size=size, size2=[size.x, size.y]*scale, shift=shift) {
|
||||
|
@ -1721,7 +1733,7 @@ In the case that the prismoid is not oriented vertically, (ie, where the `shift=
|
|||
arguments should refer to a plane other than XY) you can use the `axis=` argument. This lets
|
||||
you make prismoids naturally oriented forwards/backwards or sideways.
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
module yprismoidal(
|
||||
size=[100,100,100], scale=0.5, shift=[0,0],
|
||||
|
@ -1750,7 +1762,7 @@ yprismoidal([100,60,30], scale=1.5, shift=[20,20]) show_anchors(20);
|
|||
### Cylindrical Attachables
|
||||
To make a cylindrical shape attachable, you use the `l`, and `r`/`d`, args of `attachable()`.
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
module twistar(l,r,d, anchor=CENTER, spin=0, orient=UP) {
|
||||
r = get_radius(r=r,d=d,dflt=1);
|
||||
|
@ -1799,7 +1811,7 @@ ytwistar(l=100, r=40) show_anchors(20);
|
|||
To make a conical shape attachable, you use the `l`, `r1`/`d1`, and `r2`/`d2`, args of
|
||||
`attachable()`.
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
module twistar(l, r,r1,r2, d,d1,d2, anchor=CENTER, spin=0, orient=UP) {
|
||||
r1 = get_radius(r1=r1,r=r,d1=d1,d=d,dflt=1);
|
||||
|
@ -1816,7 +1828,7 @@ twistar(l=100, r1=40, r2=20) show_anchors(20);
|
|||
If the cone is ellipsoidal in shape, you can pass the unequal X/Y sizes as a 2-item vectors
|
||||
to the `r1=`/`r2=` or `d1=`/`d2=` arguments.
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
module ovalish(l,rx1,ry1,rx2,ry2, anchor=CENTER, spin=0, orient=UP) {
|
||||
attachable(anchor,spin,orient, r1=[rx1,ry1], r2=[rx2,ry2], l=l) {
|
||||
|
@ -1837,7 +1849,7 @@ ovalish(l=100, rx1=50, ry1=30, rx2=30, ry2=50) show_anchors(20);
|
|||
For conical shapes that are not oriented vertically, use the `axis=` argument to indicate the
|
||||
direction of the primary shape axis:
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
module ytwistar(l, r,r1,r2, d,d1,d2, anchor=CENTER, spin=0, orient=UP) {
|
||||
r1 = get_radius(r1=r1,r=r,d1=d1,d=d,dflt=1);
|
||||
|
@ -1855,7 +1867,7 @@ ytwistar(l=100, r1=40, r2=20) show_anchors(20);
|
|||
### Spherical Attachables
|
||||
To make a spherical shape attachable, you use the `r`/`d` args of `attachable()`.
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include <BOSL2/std.scad>
|
||||
module spikeball(r, d, anchor=CENTER, spin=0, orient=UP) {
|
||||
r = get_radius(r=r,d=d,dflt=1);
|
||||
|
@ -2059,7 +2071,7 @@ override the position. If you omit the other list items then the
|
|||
value drived from the standard anchor will be used. Below we override
|
||||
position of the FWD anchor:
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include<BOSL2/std.scad>
|
||||
module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) {
|
||||
override = [
|
||||
|
@ -2080,7 +2092,7 @@ Note how the FWD anchor is now rooted on the cylindrical portion. If
|
|||
you wanted to also change its direction and spin you could do it like
|
||||
this:
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include<BOSL2/std.scad>
|
||||
module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) {
|
||||
override = [
|
||||
|
@ -2105,7 +2117,7 @@ position of the red flag on the arrow. If you want to override all of
|
|||
the x=0 anchors to be on the cylinder, with their standard directions,
|
||||
you can do that by supplying a list:
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include<BOSL2/std.scad>
|
||||
module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) {
|
||||
override = [
|
||||
|
@ -2130,7 +2142,7 @@ the default, or a `[position, direction, spin]` triple to override the
|
|||
default. As before, you can omit values to keep their default.
|
||||
Here is the same example using a function literal for the override:
|
||||
|
||||
```openscad-3D
|
||||
```openscad-3D;Big
|
||||
include<BOSL2/std.scad>
|
||||
module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) {
|
||||
override = function (anchor)
|
||||
|
|
|
@ -47,22 +47,13 @@ include <BOSL2/std.scad>
|
|||
cube([50,40,20], anchor=TOP+FRONT+LEFT);
|
||||
```
|
||||
|
||||
You can use `spin=` to rotate around the Z axis:
|
||||
You can use `spin=` to rotate around the Z axis **after** anchoring:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], anchor=FRONT, spin=30);
|
||||
```
|
||||
|
||||
3D objects also gain the ability to use an extra trick with `spin=`;
|
||||
if you pass a list of `[X,Y,Z]` rotation angles to `spin=`, it will
|
||||
rotate by the three given axis angles, similar to using `rotate()`:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], anchor=FRONT, spin=[15,0,30]);
|
||||
```
|
||||
|
||||
3D objects also can be given an `orient=` argument as a vector, pointing
|
||||
to where the top of the shape should be rotated towards.
|
||||
|
||||
|
|
Loading…
Reference in a new issue