mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
make functions in edges.scad internal
move some stuff from paths to mutators to get like stuff all together
This commit is contained in:
parent
9c2d410555
commit
6d3eabddc5
4 changed files with 281 additions and 285 deletions
88
edges.scad
88
edges.scad
|
@ -41,7 +41,7 @@ function _edges_text(edges) =
|
||||||
is_string(edges) ? [str("\"",edges,"\"")] :
|
is_string(edges) ? [str("\"",edges,"\"")] :
|
||||||
edges==EDGES_NONE ? ["EDGES_NONE"] :
|
edges==EDGES_NONE ? ["EDGES_NONE"] :
|
||||||
edges==EDGES_ALL ? ["EDGES_ALL"] :
|
edges==EDGES_ALL ? ["EDGES_ALL"] :
|
||||||
is_edge_array(edges) ? [""] :
|
_is_edge_array(edges) ? [""] :
|
||||||
is_vector(edges,3) ? _edges_vec_txt(edges) :
|
is_vector(edges,3) ? _edges_vec_txt(edges) :
|
||||||
is_list(edges) ? let(
|
is_list(edges) ? let(
|
||||||
lst = [for (x=edges) each _edges_text(x)],
|
lst = [for (x=edges) each _edges_text(x)],
|
||||||
|
@ -109,20 +109,20 @@ EDGE_OFFSETS = [
|
||||||
|
|
||||||
// Section: Edge Helpers
|
// Section: Edge Helpers
|
||||||
|
|
||||||
// Function: is_edge_array()
|
/// Internal Function: _is_edge_array()
|
||||||
// Topics: Edges, Type Checking
|
// Topics: Edges, Type Checking
|
||||||
// Usage:
|
// Usage:
|
||||||
// bool = is_edge_array(x);
|
// bool = _is_edge_array(x);
|
||||||
// Description:
|
// Description:
|
||||||
// Returns true if the given value has the form of an edge array.
|
// Returns true if the given value has the form of an edge array.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// x = The item to check the type of.
|
// x = The item to check the type of.
|
||||||
// See Also: edges(), EDGES_NONE, EDGES_ALL
|
// See Also: edges(), EDGES_NONE, EDGES_ALL
|
||||||
function is_edge_array(x) = is_list(x) && is_vector(x[0]) && len(x)==3 && len(x[0])==4;
|
function _is_edge_array(x) = is_list(x) && is_vector(x[0]) && len(x)==3 && len(x[0])==4;
|
||||||
|
|
||||||
|
|
||||||
function _edge_set(v) =
|
function _edge_set(v) =
|
||||||
is_edge_array(v)? v : [
|
_is_edge_array(v)? v : [
|
||||||
for (ax=[0:2]) [
|
for (ax=[0:2]) [
|
||||||
for (b=[-1,1], a=[-1,1]) let(
|
for (b=[-1,1], a=[-1,1]) let(
|
||||||
v2=[[0,a,b],[a,0,b],[a,b,0]][ax]
|
v2=[[0,a,b],[a,0,b],[a,b,0]][ax]
|
||||||
|
@ -153,15 +153,15 @@ function _edge_set(v) =
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
// Function: normalize_edges()
|
/// Internal Function: _normalize_edges()
|
||||||
// Topics: Edges
|
/// Topics: Edges
|
||||||
// Usage:
|
// Usage:
|
||||||
// edges = normalize_edges(v);
|
// edges = _normalize_edges(v);
|
||||||
// Description:
|
// Description:
|
||||||
// Normalizes all values in an edge array to be `1`, if it was originally greater than `0`,
|
// Normalizes all values in an edge array to be `1`, if it was originally greater than `0`,
|
||||||
// or `0`, if it was originally less than or equal to `0`.
|
// or `0`, if it was originally less than or equal to `0`.
|
||||||
// See Also: is_edge_array(), edges(), EDGES_NONE, EDGES_ALL
|
// See Also: edges(), EDGES_NONE, EDGES_ALL
|
||||||
function normalize_edges(v) = [for (ax=v) [for (edge=ax) edge>0? 1 : 0]];
|
function _normalize_edges(v) = [for (ax=v) [for (edge=ax) edge>0? 1 : 0]];
|
||||||
|
|
||||||
|
|
||||||
// Function: edges()
|
// Function: edges()
|
||||||
|
@ -259,7 +259,7 @@ function normalize_edges(v) = [for (ax=v) [for (edge=ax) edge>0? 1 : 0]];
|
||||||
// v = The edge set to include.
|
// v = The edge set to include.
|
||||||
// except = The edge set to specifically exclude, even if they are in `v`.
|
// except = The edge set to specifically exclude, even if they are in `v`.
|
||||||
//
|
//
|
||||||
// See Also: is_edge_array(), normalize_edges(), EDGES_NONE, EDGES_ALL
|
// See Also: EDGES_NONE, EDGES_ALL
|
||||||
//
|
//
|
||||||
// Example(3D): Just the front-top edge
|
// Example(3D): Just the front-top edge
|
||||||
// edg = edges(FRONT+TOP);
|
// edg = edges(FRONT+TOP);
|
||||||
|
@ -283,11 +283,11 @@ function normalize_edges(v) = [for (ax=v) [for (edge=ax) edge>0? 1 : 0]];
|
||||||
// edg = edges("ALL", except=edges("Z", except=BACK));
|
// edg = edges("ALL", except=edges("Z", except=BACK));
|
||||||
// show_edges(edges=edg);
|
// show_edges(edges=edg);
|
||||||
function edges(v, except=[]) =
|
function edges(v, except=[]) =
|
||||||
(is_string(v) || is_vector(v) || is_edge_array(v))? edges([v], except=except) :
|
(is_string(v) || is_vector(v) || _is_edge_array(v))? edges([v], except=except) :
|
||||||
(is_string(except) || is_vector(except) || is_edge_array(except))? edges(v, except=[except]) :
|
(is_string(except) || is_vector(except) || _is_edge_array(except))? edges(v, except=[except]) :
|
||||||
except==[]? normalize_edges(sum([for (x=v) _edge_set(x)])) :
|
except==[]? _normalize_edges(sum([for (x=v) _edge_set(x)])) :
|
||||||
normalize_edges(
|
_normalize_edges(
|
||||||
normalize_edges(sum([for (x=v) _edge_set(x)])) -
|
_normalize_edges(sum([for (x=v) _edge_set(x)])) -
|
||||||
sum([for (x=except) _edge_set(x)])
|
sum([for (x=except) _edge_set(x)])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ function edges(v, except=[]) =
|
||||||
// size = The scalar size of the cube.
|
// size = The scalar size of the cube.
|
||||||
// text = The text to show on the front of the cube.
|
// text = The text to show on the front of the cube.
|
||||||
// txtsize = The size of the text.
|
// txtsize = The size of the text.
|
||||||
// See Also: is_edge_array(), edges(), EDGES_NONE, EDGES_ALL
|
// See Also: edges(), EDGES_NONE, EDGES_ALL
|
||||||
// Example:
|
// Example:
|
||||||
// show_edges(size=30, edges=["X","Y"]);
|
// show_edges(size=30, edges=["X","Y"]);
|
||||||
module show_edges(edges="ALL", size=20, text, txtsize=3) {
|
module show_edges(edges="ALL", size=20, text, txtsize=3) {
|
||||||
|
@ -365,29 +365,29 @@ CORNER_OFFSETS = [
|
||||||
|
|
||||||
// Section: Corner Helpers
|
// Section: Corner Helpers
|
||||||
|
|
||||||
// Function: is_corner_array()
|
/// Internal Function: _is_corner_array()
|
||||||
// Topics: Corners, Type Checking
|
/// Topics: Corners, Type Checking
|
||||||
// Usage:
|
// Usage:
|
||||||
// bool = is_corner_array(x)
|
// bool = _is_corner_array(x)
|
||||||
// Description:
|
// Description:
|
||||||
// Returns true if the given value has the form of a corner array.
|
// Returns true if the given value has the form of a corner array.
|
||||||
// See Also: CORNERS_NONE, CORNERS_ALL, corners()
|
// See Also: CORNERS_NONE, CORNERS_ALL, corners()
|
||||||
function is_corner_array(x) = is_vector(x) && len(x)==8 && all([for (xx=x) xx==1||xx==0]);
|
function _is_corner_array(x) = is_vector(x) && len(x)==8 && all([for (xx=x) xx==1||xx==0]);
|
||||||
|
|
||||||
|
|
||||||
// Function: normalize_corners()
|
/// Internal Function: _normalize_corners()
|
||||||
// Topics: Corners
|
/// Topics: Corners
|
||||||
// Usage:
|
// Usage:
|
||||||
// corns = normalize_corners(v);
|
// corns = _normalize_corners(v);
|
||||||
// Description:
|
// Description:
|
||||||
// Normalizes all values in a corner array to be `1`, if it was originally greater than `0`,
|
// Normalizes all values in a corner array to be `1`, if it was originally greater than `0`,
|
||||||
// or `0`, if it was originally less than or equal to `0`.
|
// or `0`, if it was originally less than or equal to `0`.
|
||||||
// See Also: CORNERS_NONE, CORNERS_ALL, is_corner_array(), corners()
|
// See Also: CORNERS_NONE, CORNERS_ALL, corners()
|
||||||
function normalize_corners(v) = [for (x=v) x>0? 1 : 0];
|
function _normalize_corners(v) = [for (x=v) x>0? 1 : 0];
|
||||||
|
|
||||||
|
|
||||||
function _corner_set(v) =
|
function _corner_set(v) =
|
||||||
is_corner_array(v)? v : [
|
_is_corner_array(v)? v : [
|
||||||
for (i=[0:7]) let(
|
for (i=[0:7]) let(
|
||||||
v2 = CORNER_OFFSETS[i]
|
v2 = CORNER_OFFSETS[i]
|
||||||
) (
|
) (
|
||||||
|
@ -480,7 +480,7 @@ function _corner_set(v) =
|
||||||
// show_corners(corners="ALL");
|
// show_corners(corners="ALL");
|
||||||
// show_corners(corners="NONE");
|
// show_corners(corners="NONE");
|
||||||
// }
|
// }
|
||||||
// See Also: CORNERS_NONE, CORNERS_ALL, is_corner_array(), normalize_corners()
|
// See Also: CORNERS_NONE, CORNERS_ALL
|
||||||
// Example(3D): Just the front-top-right corner
|
// Example(3D): Just the front-top-right corner
|
||||||
// crn = corners(FRONT+TOP+RIGHT);
|
// crn = corners(FRONT+TOP+RIGHT);
|
||||||
// show_corners(corners=crn);
|
// show_corners(corners=crn);
|
||||||
|
@ -497,37 +497,37 @@ function _corner_set(v) =
|
||||||
// crn = corners([BOTTOM,FRONT], except=BOTTOM+FRONT);
|
// crn = corners([BOTTOM,FRONT], except=BOTTOM+FRONT);
|
||||||
// show_corners(corners=crn);
|
// show_corners(corners=crn);
|
||||||
function corners(v, except=[]) =
|
function corners(v, except=[]) =
|
||||||
(is_string(v) || is_vector(v) || is_corner_array(v))? corners([v], except=except) :
|
(is_string(v) || is_vector(v) || _is_corner_array(v))? corners([v], except=except) :
|
||||||
(is_string(except) || is_vector(except) || is_corner_array(except))? corners(v, except=[except]) :
|
(is_string(except) || is_vector(except) || _is_corner_array(except))? corners(v, except=[except]) :
|
||||||
except==[]? normalize_corners(sum([for (x=v) _corner_set(x)])) :
|
except==[]? _normalize_corners(sum([for (x=v) _corner_set(x)])) :
|
||||||
let(
|
let(
|
||||||
a = normalize_corners(sum([for (x=v) _corner_set(x)])),
|
a = _normalize_corners(sum([for (x=v) _corner_set(x)])),
|
||||||
b = normalize_corners(sum([for (x=except) _corner_set(x)]))
|
b = _normalize_corners(sum([for (x=except) _corner_set(x)]))
|
||||||
) normalize_corners(a - b);
|
) _normalize_corners(a - b);
|
||||||
|
|
||||||
|
|
||||||
// Function: corner_edges()
|
/// Internal Function: _corner_edges()
|
||||||
// Topics: Corners
|
/// Topics: Corners
|
||||||
// Description:
|
// Description:
|
||||||
// Returns [XCOUNT,YCOUNT,ZCOUNT] where each is the count of edges aligned with that
|
// Returns [XCOUNT,YCOUNT,ZCOUNT] where each is the count of edges aligned with that
|
||||||
// axis that are in the edge set and touch the given corner.
|
// axis that are in the edge set and touch the given corner.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// edges = Standard edges array.
|
// edges = Standard edges array.
|
||||||
// v = Vector pointing to the corner to count edge intersections at.
|
// v = Vector pointing to the corner to count edge intersections at.
|
||||||
// See Also: CORNERS_NONE, CORNERS_ALL, is_corner_array(), corners(), corner_edge_count()
|
// See Also: CORNERS_NONE, CORNERS_ALL, corners()
|
||||||
function corner_edges(edges, v) =
|
function _corner_edges(edges, v) =
|
||||||
let(u = (v+[1,1,1])/2) [edges[0][u.y+u.z*2], edges[1][u.x+u.z*2], edges[2][u.x+u.y*2]];
|
let(u = (v+[1,1,1])/2) [edges[0][u.y+u.z*2], edges[1][u.x+u.z*2], edges[2][u.x+u.y*2]];
|
||||||
|
|
||||||
|
|
||||||
// Function: corner_edge_count()
|
/// InternalFunction: _corner_edge_count()
|
||||||
// Topics: Corners
|
/// Topics: Corners
|
||||||
// Description:
|
// Description:
|
||||||
// Counts how many given edges intersect at a specific corner.
|
// Counts how many given edges intersect at a specific corner.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// edges = Standard edges array.
|
// edges = Standard edges array.
|
||||||
// v = Vector pointing to the corner to count edge intersections at.
|
// v = Vector pointing to the corner to count edge intersections at.
|
||||||
// See Also: CORNERS_NONE, CORNERS_ALL, is_corner_array(), corners(), corner_edges()
|
// See Also: CORNERS_NONE, CORNERS_ALL, corners()
|
||||||
function corner_edge_count(edges, v) =
|
function _corner_edge_count(edges, v) =
|
||||||
let(u = (v+[1,1,1])/2) edges[0][u.y+u.z*2] + edges[1][u.x+u.z*2] + edges[2][u.x+u.y*2];
|
let(u = (v+[1,1,1])/2) edges[0][u.y+u.z*2] + edges[1][u.x+u.z*2] + edges[2][u.x+u.y*2];
|
||||||
|
|
||||||
|
|
||||||
|
@ -535,7 +535,7 @@ function _corners_text(corners) =
|
||||||
is_string(corners) ? [str("\"",corners,"\"")] :
|
is_string(corners) ? [str("\"",corners,"\"")] :
|
||||||
corners==CORNERS_NONE ? ["CORNERS_NONE"] :
|
corners==CORNERS_NONE ? ["CORNERS_NONE"] :
|
||||||
corners==CORNERS_ALL ? ["CORNERS_ALL"] :
|
corners==CORNERS_ALL ? ["CORNERS_ALL"] :
|
||||||
is_corner_array(corners) ? [""] :
|
_is_corner_array(corners) ? [""] :
|
||||||
is_vector(corners,3) ? _edges_vec_txt(corners) :
|
is_vector(corners,3) ? _edges_vec_txt(corners) :
|
||||||
is_list(corners) ? let(
|
is_list(corners) ? let(
|
||||||
lst = [for (x=corners) each _corners_text(x)],
|
lst = [for (x=corners) each _corners_text(x)],
|
||||||
|
@ -563,7 +563,7 @@ function _corners_text(corners) =
|
||||||
// size = The scalar size of the cube.
|
// size = The scalar size of the cube.
|
||||||
// text = If given, overrides the text to be shown on the front of the cube.
|
// text = If given, overrides the text to be shown on the front of the cube.
|
||||||
// txtsize = The size of the text.
|
// txtsize = The size of the text.
|
||||||
// See Also: CORNERS_NONE, CORNERS_ALL, is_corner_array(), corners()
|
// See Also: CORNERS_NONE, CORNERS_ALL, corners()
|
||||||
// Example:
|
// Example:
|
||||||
// show_corners(corners=FWD+RIGHT, size=30);
|
// show_corners(corners=FWD+RIGHT, size=30);
|
||||||
module show_corners(corners="ALL", size=20, text, txtsize=3) {
|
module show_corners(corners="ALL", size=20, text, txtsize=3) {
|
||||||
|
|
182
mutators.scad
182
mutators.scad
|
@ -598,6 +598,188 @@ module cylindrical_extrude(or, ir, od, id, size=1000, convexity=10, spin=0, orie
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Module: extrude_from_to()
|
||||||
|
// Description:
|
||||||
|
// Extrudes a 2D shape between the 3d points pt1 and pt2. Takes as children a set of 2D shapes to extrude.
|
||||||
|
// Arguments:
|
||||||
|
// pt1 = starting point of extrusion.
|
||||||
|
// pt2 = ending point of extrusion.
|
||||||
|
// convexity = max number of times a line could intersect a wall of the 2D shape being extruded.
|
||||||
|
// twist = number of degrees to twist the 2D shape over the entire extrusion length.
|
||||||
|
// scale = scale multiplier for end of extrusion compared the start.
|
||||||
|
// slices = Number of slices along the extrusion to break the extrusion into. Useful for refining `twist` extrusions.
|
||||||
|
// Example(FlatSpin,VPD=200,VPT=[0,0,15]):
|
||||||
|
// extrude_from_to([0,0,0], [10,20,30], convexity=4, twist=360, scale=3.0, slices=40) {
|
||||||
|
// xcopies(3) circle(3, $fn=32);
|
||||||
|
// }
|
||||||
|
module extrude_from_to(pt1, pt2, convexity, twist, scale, slices) {
|
||||||
|
assert(is_vector(pt1));
|
||||||
|
assert(is_vector(pt2));
|
||||||
|
pt1 = point3d(pt1);
|
||||||
|
pt2 = point3d(pt2);
|
||||||
|
rtp = xyz_to_spherical(pt2-pt1);
|
||||||
|
translate(pt1) {
|
||||||
|
rotate([0, rtp[2], rtp[1]]) {
|
||||||
|
if (rtp[0] > 0) {
|
||||||
|
linear_extrude(height=rtp[0], convexity=convexity, center=false, slices=slices, twist=twist, scale=scale) {
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Module: spiral_sweep()
|
||||||
|
// Description:
|
||||||
|
// Takes a closed 2D polygon path, centered on the XY plane, and sweeps/extrudes it along a 3D spiral path
|
||||||
|
// of a given radius, height and twist. The origin in the profile traces out the helix of the specified radius.
|
||||||
|
// If twist is positive the path will be right-handed; if twist is negative the path will be left-handed.
|
||||||
|
// .
|
||||||
|
// Higbee specifies tapering applied to the ends of the extrusion and is given as the linear distance
|
||||||
|
// over which to taper.
|
||||||
|
// Arguments:
|
||||||
|
// poly = Array of points of a polygon path, to be extruded.
|
||||||
|
// h = height of the spiral to extrude along.
|
||||||
|
// r = Radius of the spiral to extrude along. Default: 50
|
||||||
|
// twist = number of degrees of rotation to spiral up along height.
|
||||||
|
// ---
|
||||||
|
// d = Diameter of the spiral to extrude along.
|
||||||
|
// higbee = Length to taper thread ends over.
|
||||||
|
// higbee1 = Taper length at start
|
||||||
|
// higbee2 = Taper length at end
|
||||||
|
// internal = direction to taper the threads with higbee. If true threads taper outward; if false they taper inward. Default: false
|
||||||
|
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER`
|
||||||
|
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#spin). Default: `0`
|
||||||
|
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP`
|
||||||
|
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=BOTTOM`.
|
||||||
|
// Example:
|
||||||
|
// poly = [[-10,0], [-3,-5], [3,-5], [10,0], [0,-30]];
|
||||||
|
// spiral_sweep(poly, h=200, r=50, twist=1080, $fn=36);
|
||||||
|
module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, higbee1, higbee2, internal=false, anchor, spin=0, orient=UP) {
|
||||||
|
higsample = 10; // Oversample factor for higbee tapering
|
||||||
|
dummy1=assert(is_num(twist) && twist != 0);
|
||||||
|
bounds = pointlist_bounds(poly);
|
||||||
|
yctr = (bounds[0].y+bounds[1].y)/2;
|
||||||
|
xmin = bounds[0].x;
|
||||||
|
xmax = bounds[1].x;
|
||||||
|
poly = path3d(clockwise_polygon(poly));
|
||||||
|
anchor = get_anchor(anchor,center,BOT,BOT);
|
||||||
|
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50);
|
||||||
|
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50);
|
||||||
|
sides = segs(max(r1,r2));
|
||||||
|
dir = sign(twist);
|
||||||
|
ang_step = 360/sides*dir;
|
||||||
|
anglist = [for(ang = [0:ang_step:twist-EPSILON]) ang,
|
||||||
|
twist];
|
||||||
|
higbee1 = first_defined([higbee1, higbee, 0]);
|
||||||
|
higbee2 = first_defined([higbee2, higbee, 0]);
|
||||||
|
higang1 = 360 * higbee1 / (2 * r1 * PI);
|
||||||
|
higang2 = 360 * higbee2 / (2 * r2 * PI);
|
||||||
|
dummy2=assert(higbee1>=0 && higbee2>=0)
|
||||||
|
assert(higang1 < dir*twist/2,"Higbee1 is more than half the threads")
|
||||||
|
assert(higang2 < dir*twist/2,"Higbee2 is more than half the threads");
|
||||||
|
function polygon_r(N,theta) =
|
||||||
|
let( alpha = 360/N )
|
||||||
|
cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2));
|
||||||
|
higofs = pow(0.05,2); // Smallest hig scale is the square root of this value
|
||||||
|
function taperfunc(x) = sqrt((1-higofs)*x+higofs);
|
||||||
|
interp_ang = [
|
||||||
|
for(i=idx(anglist,e=-2))
|
||||||
|
each lerpn(anglist[i],anglist[i+1],
|
||||||
|
(higang1>0 && higang1>dir*anglist[i+1]
|
||||||
|
|| (higang2>0 && higang2>dir*(twist-anglist[i]))) ? ceil((anglist[i+1]-anglist[i])/ang_step*higsample)
|
||||||
|
: 1,
|
||||||
|
endpoint=false),
|
||||||
|
last(anglist)
|
||||||
|
];
|
||||||
|
skewmat = affine3d_skew_xz(xa=atan2(r2-r1,h));
|
||||||
|
points = [
|
||||||
|
for (a = interp_ang) let (
|
||||||
|
hsc = dir*a<higang1 ? taperfunc(dir*a/higang1)
|
||||||
|
: dir*(twist-a)<higang2 ? taperfunc(dir*(twist-a)/higang2)
|
||||||
|
: 1,
|
||||||
|
u = a/twist,
|
||||||
|
r = lerp(r1,r2,u),
|
||||||
|
mat = affine3d_zrot(a)
|
||||||
|
* affine3d_translate([polygon_r(sides,a)*r, 0, h * (u-0.5)])
|
||||||
|
* affine3d_xrot(90)
|
||||||
|
* skewmat
|
||||||
|
* scale([hsc,lerp(hsc,1,0.25),1], cp=[internal ? xmax : xmin, yctr, 0]),
|
||||||
|
pts = apply(mat, poly)
|
||||||
|
) pts
|
||||||
|
];
|
||||||
|
|
||||||
|
vnf = vnf_vertex_array(
|
||||||
|
points, col_wrap=true, caps=true, reverse=dir>0?true:false,
|
||||||
|
style=higbee1>0 || higbee2>0 ? "quincunx" : "alt"
|
||||||
|
);
|
||||||
|
|
||||||
|
attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) {
|
||||||
|
vnf_polyhedron(vnf, convexity=ceil(2*dir*twist/360));
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Module: path_extrude()
|
||||||
|
// Description:
|
||||||
|
// Extrudes 2D children along a 3D path. This may be slow.
|
||||||
|
// Arguments:
|
||||||
|
// path = array of points for the bezier path to extrude along.
|
||||||
|
// convexity = maximum number of walls a ran can pass through.
|
||||||
|
// clipsize = increase if artifacts are left. Default: 1000
|
||||||
|
// Example(FlatSpin,VPD=600,VPT=[75,16,20]):
|
||||||
|
// path = [ [0, 0, 0], [33, 33, 33], [66, 33, 40], [100, 0, 0], [150,0,0] ];
|
||||||
|
// path_extrude(path) circle(r=10, $fn=6);
|
||||||
|
module path_extrude(path, convexity=10, clipsize=100) {
|
||||||
|
function polyquats(path, q=q_ident(), v=[0,0,1], i=0) = let(
|
||||||
|
v2 = path[i+1] - path[i],
|
||||||
|
ang = vector_angle(v,v2),
|
||||||
|
axis = ang>0.001? unit(cross(v,v2)) : [0,0,1],
|
||||||
|
newq = q_mul(quat(axis, ang), q),
|
||||||
|
dist = norm(v2)
|
||||||
|
) i < (len(path)-2)?
|
||||||
|
concat([[dist, newq, ang]], polyquats(path, newq, v2, i+1)) :
|
||||||
|
[[dist, newq, ang]];
|
||||||
|
|
||||||
|
epsilon = 0.0001; // Make segments ever so slightly too long so they overlap.
|
||||||
|
ptcount = len(path);
|
||||||
|
pquats = polyquats(path);
|
||||||
|
for (i = [0:1:ptcount-2]) {
|
||||||
|
pt1 = path[i];
|
||||||
|
pt2 = path[i+1];
|
||||||
|
dist = pquats[i][0];
|
||||||
|
q = pquats[i][1];
|
||||||
|
difference() {
|
||||||
|
translate(pt1) {
|
||||||
|
q_rot(q) {
|
||||||
|
down(clipsize/2/2) {
|
||||||
|
if ((dist+clipsize/2) > 0) {
|
||||||
|
linear_extrude(height=dist+clipsize/2, convexity=convexity) {
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
translate(pt1) {
|
||||||
|
hq = (i > 0)? q_slerp(q, pquats[i-1][1], 0.5) : q;
|
||||||
|
q_rot(hq) down(clipsize/2+epsilon) cube(clipsize, center=true);
|
||||||
|
}
|
||||||
|
translate(pt2) {
|
||||||
|
hq = (i < ptcount-2)? q_slerp(q, pquats[i+1][1], 0.5) : q;
|
||||||
|
q_rot(hq) up(clipsize/2+epsilon) cube(clipsize, center=true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Section: Offset Mutators
|
// Section: Offset Mutators
|
||||||
|
|
186
paths.scad
186
paths.scad
|
@ -1215,190 +1215,4 @@ function resample_path(path, N, spacing, closed=false) =
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Section: 3D Modules
|
|
||||||
|
|
||||||
|
|
||||||
// Module: extrude_from_to()
|
|
||||||
// Description:
|
|
||||||
// Extrudes a 2D shape between the 3d points pt1 and pt2. Takes as children a set of 2D shapes to extrude.
|
|
||||||
// Arguments:
|
|
||||||
// pt1 = starting point of extrusion.
|
|
||||||
// pt2 = ending point of extrusion.
|
|
||||||
// convexity = max number of times a line could intersect a wall of the 2D shape being extruded.
|
|
||||||
// twist = number of degrees to twist the 2D shape over the entire extrusion length.
|
|
||||||
// scale = scale multiplier for end of extrusion compared the start.
|
|
||||||
// slices = Number of slices along the extrusion to break the extrusion into. Useful for refining `twist` extrusions.
|
|
||||||
// Example(FlatSpin,VPD=200,VPT=[0,0,15]):
|
|
||||||
// extrude_from_to([0,0,0], [10,20,30], convexity=4, twist=360, scale=3.0, slices=40) {
|
|
||||||
// xcopies(3) circle(3, $fn=32);
|
|
||||||
// }
|
|
||||||
module extrude_from_to(pt1, pt2, convexity, twist, scale, slices) {
|
|
||||||
assert(is_vector(pt1));
|
|
||||||
assert(is_vector(pt2));
|
|
||||||
pt1 = point3d(pt1);
|
|
||||||
pt2 = point3d(pt2);
|
|
||||||
rtp = xyz_to_spherical(pt2-pt1);
|
|
||||||
translate(pt1) {
|
|
||||||
rotate([0, rtp[2], rtp[1]]) {
|
|
||||||
if (rtp[0] > 0) {
|
|
||||||
linear_extrude(height=rtp[0], convexity=convexity, center=false, slices=slices, twist=twist, scale=scale) {
|
|
||||||
children();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Module: spiral_sweep()
|
|
||||||
// Description:
|
|
||||||
// Takes a closed 2D polygon path, centered on the XY plane, and sweeps/extrudes it along a 3D spiral path
|
|
||||||
// of a given radius, height and twist. The origin in the profile traces out the helix of the specified radius.
|
|
||||||
// If twist is positive the path will be right-handed; if twist is negative the path will be left-handed.
|
|
||||||
// .
|
|
||||||
// Higbee specifies tapering applied to the ends of the extrusion and is given as the linear distance
|
|
||||||
// over which to taper.
|
|
||||||
// Arguments:
|
|
||||||
// poly = Array of points of a polygon path, to be extruded.
|
|
||||||
// h = height of the spiral to extrude along.
|
|
||||||
// r = Radius of the spiral to extrude along. Default: 50
|
|
||||||
// twist = number of degrees of rotation to spiral up along height.
|
|
||||||
// ---
|
|
||||||
// d = Diameter of the spiral to extrude along.
|
|
||||||
// higbee = Length to taper thread ends over.
|
|
||||||
// higbee1 = Taper length at start
|
|
||||||
// higbee2 = Taper length at end
|
|
||||||
// internal = direction to taper the threads with higbee. If true threads taper outward; if false they taper inward. Default: false
|
|
||||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER`
|
|
||||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#spin). Default: `0`
|
|
||||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP`
|
|
||||||
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=BOTTOM`.
|
|
||||||
// Example:
|
|
||||||
// poly = [[-10,0], [-3,-5], [3,-5], [10,0], [0,-30]];
|
|
||||||
// spiral_sweep(poly, h=200, r=50, twist=1080, $fn=36);
|
|
||||||
module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, higbee1, higbee2, internal=false, anchor, spin=0, orient=UP) {
|
|
||||||
higsample = 10; // Oversample factor for higbee tapering
|
|
||||||
dummy1=assert(is_num(twist) && twist != 0);
|
|
||||||
bounds = pointlist_bounds(poly);
|
|
||||||
yctr = (bounds[0].y+bounds[1].y)/2;
|
|
||||||
xmin = bounds[0].x;
|
|
||||||
xmax = bounds[1].x;
|
|
||||||
poly = path3d(clockwise_polygon(poly));
|
|
||||||
anchor = get_anchor(anchor,center,BOT,BOT);
|
|
||||||
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50);
|
|
||||||
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50);
|
|
||||||
sides = segs(max(r1,r2));
|
|
||||||
dir = sign(twist);
|
|
||||||
ang_step = 360/sides*dir;
|
|
||||||
anglist = [for(ang = [0:ang_step:twist-EPSILON]) ang,
|
|
||||||
twist];
|
|
||||||
higbee1 = first_defined([higbee1, higbee, 0]);
|
|
||||||
higbee2 = first_defined([higbee2, higbee, 0]);
|
|
||||||
higang1 = 360 * higbee1 / (2 * r1 * PI);
|
|
||||||
higang2 = 360 * higbee2 / (2 * r2 * PI);
|
|
||||||
dummy2=assert(higbee1>=0 && higbee2>=0)
|
|
||||||
assert(higang1 < dir*twist/2,"Higbee1 is more than half the threads")
|
|
||||||
assert(higang2 < dir*twist/2,"Higbee2 is more than half the threads");
|
|
||||||
function polygon_r(N,theta) =
|
|
||||||
let( alpha = 360/N )
|
|
||||||
cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2));
|
|
||||||
higofs = pow(0.05,2); // Smallest hig scale is the square root of this value
|
|
||||||
function taperfunc(x) = sqrt((1-higofs)*x+higofs);
|
|
||||||
interp_ang = [
|
|
||||||
for(i=idx(anglist,e=-2))
|
|
||||||
each lerpn(anglist[i],anglist[i+1],
|
|
||||||
(higang1>0 && higang1>dir*anglist[i+1]
|
|
||||||
|| (higang2>0 && higang2>dir*(twist-anglist[i]))) ? ceil((anglist[i+1]-anglist[i])/ang_step*higsample)
|
|
||||||
: 1,
|
|
||||||
endpoint=false),
|
|
||||||
last(anglist)
|
|
||||||
];
|
|
||||||
skewmat = affine3d_skew_xz(xa=atan2(r2-r1,h));
|
|
||||||
points = [
|
|
||||||
for (a = interp_ang) let (
|
|
||||||
hsc = dir*a<higang1 ? taperfunc(dir*a/higang1)
|
|
||||||
: dir*(twist-a)<higang2 ? taperfunc(dir*(twist-a)/higang2)
|
|
||||||
: 1,
|
|
||||||
u = a/twist,
|
|
||||||
r = lerp(r1,r2,u),
|
|
||||||
mat = affine3d_zrot(a)
|
|
||||||
* affine3d_translate([polygon_r(sides,a)*r, 0, h * (u-0.5)])
|
|
||||||
* affine3d_xrot(90)
|
|
||||||
* skewmat
|
|
||||||
* scale([hsc,lerp(hsc,1,0.25),1], cp=[internal ? xmax : xmin, yctr, 0]),
|
|
||||||
pts = apply(mat, poly)
|
|
||||||
) pts
|
|
||||||
];
|
|
||||||
|
|
||||||
vnf = vnf_vertex_array(
|
|
||||||
points, col_wrap=true, caps=true, reverse=dir>0?true:false,
|
|
||||||
style=higbee1>0 || higbee2>0 ? "quincunx" : "alt"
|
|
||||||
);
|
|
||||||
|
|
||||||
attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) {
|
|
||||||
vnf_polyhedron(vnf, convexity=ceil(2*dir*twist/360));
|
|
||||||
children();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Module: path_extrude()
|
|
||||||
// Description:
|
|
||||||
// Extrudes 2D children along a 3D path. This may be slow.
|
|
||||||
// Arguments:
|
|
||||||
// path = array of points for the bezier path to extrude along.
|
|
||||||
// convexity = maximum number of walls a ran can pass through.
|
|
||||||
// clipsize = increase if artifacts are left. Default: 1000
|
|
||||||
// Example(FlatSpin,VPD=600,VPT=[75,16,20]):
|
|
||||||
// path = [ [0, 0, 0], [33, 33, 33], [66, 33, 40], [100, 0, 0], [150,0,0] ];
|
|
||||||
// path_extrude(path) circle(r=10, $fn=6);
|
|
||||||
module path_extrude(path, convexity=10, clipsize=100) {
|
|
||||||
function polyquats(path, q=q_ident(), v=[0,0,1], i=0) = let(
|
|
||||||
v2 = path[i+1] - path[i],
|
|
||||||
ang = vector_angle(v,v2),
|
|
||||||
axis = ang>0.001? unit(cross(v,v2)) : [0,0,1],
|
|
||||||
newq = q_mul(quat(axis, ang), q),
|
|
||||||
dist = norm(v2)
|
|
||||||
) i < (len(path)-2)?
|
|
||||||
concat([[dist, newq, ang]], polyquats(path, newq, v2, i+1)) :
|
|
||||||
[[dist, newq, ang]];
|
|
||||||
|
|
||||||
epsilon = 0.0001; // Make segments ever so slightly too long so they overlap.
|
|
||||||
ptcount = len(path);
|
|
||||||
pquats = polyquats(path);
|
|
||||||
for (i = [0:1:ptcount-2]) {
|
|
||||||
pt1 = path[i];
|
|
||||||
pt2 = path[i+1];
|
|
||||||
dist = pquats[i][0];
|
|
||||||
q = pquats[i][1];
|
|
||||||
difference() {
|
|
||||||
translate(pt1) {
|
|
||||||
q_rot(q) {
|
|
||||||
down(clipsize/2/2) {
|
|
||||||
if ((dist+clipsize/2) > 0) {
|
|
||||||
linear_extrude(height=dist+clipsize/2, convexity=convexity) {
|
|
||||||
children();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
translate(pt1) {
|
|
||||||
hq = (i > 0)? q_slerp(q, pquats[i-1][1], 0.5) : q;
|
|
||||||
q_rot(hq) down(clipsize/2+epsilon) cube(clipsize, center=true);
|
|
||||||
}
|
|
||||||
translate(pt2) {
|
|
||||||
hq = (i < ptcount-2)? q_slerp(q, pquats[i+1][1], 0.5) : q;
|
|
||||||
q_rot(hq) up(clipsize/2+epsilon) cube(clipsize, center=true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
include <../std.scad>
|
include <../std.scad>
|
||||||
|
|
||||||
|
|
||||||
module test_is_edge_array() {
|
module test__is_edge_array() {
|
||||||
assert(is_edge_array([[0,0,0,0],[0,0,0,0],[0,0,0,0]]));
|
assert(_is_edge_array([[0,0,0,0],[0,0,0,0],[0,0,0,0]]));
|
||||||
assert(is_edge_array([[1,1,1,1],[1,1,1,1],[1,1,1,1]]));
|
assert(_is_edge_array([[1,1,1,1],[1,1,1,1],[1,1,1,1]]));
|
||||||
assert(!is_edge_array([[1,1,1],[1,1,1],[1,1,1]]));
|
assert(!_is_edge_array([[1,1,1],[1,1,1],[1,1,1]]));
|
||||||
assert(!is_edge_array([[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1]]));
|
assert(!_is_edge_array([[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1]]));
|
||||||
assert(!is_edge_array([[1,1,1,1],[1,1,1,1]]));
|
assert(!_is_edge_array([[1,1,1,1],[1,1,1,1]]));
|
||||||
assert(!is_edge_array([1,1,1,1]));
|
assert(!_is_edge_array([1,1,1,1]));
|
||||||
assert(!is_edge_array("foo"));
|
assert(!_is_edge_array("foo"));
|
||||||
assert(!is_edge_array(42));
|
assert(!_is_edge_array(42));
|
||||||
assert(!is_edge_array(true));
|
assert(!_is_edge_array(true));
|
||||||
assert(is_edge_array(edges(["X","Y"])));
|
assert(_is_edge_array(edges(["X","Y"])));
|
||||||
}
|
}
|
||||||
test_is_edge_array();
|
test__is_edge_array();
|
||||||
|
|
||||||
|
|
||||||
module test__edge_set() {
|
module test__edge_set() {
|
||||||
|
@ -62,14 +62,14 @@ module test__edge_set() {
|
||||||
test__edge_set();
|
test__edge_set();
|
||||||
|
|
||||||
|
|
||||||
module test_normalize_edges() {
|
module test__normalize_edges() {
|
||||||
assert(normalize_edges([[-2,-2,-2,-2],[-2,-2,-2,-2],[-2,-2,-2,-2]]) == [[0,0,0,0],[0,0,0,0],[0,0,0,0]]);
|
assert(_normalize_edges([[-2,-2,-2,-2],[-2,-2,-2,-2],[-2,-2,-2,-2]]) == [[0,0,0,0],[0,0,0,0],[0,0,0,0]]);
|
||||||
assert(normalize_edges([[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]]) == [[0,0,0,0],[0,0,0,0],[0,0,0,0]]);
|
assert(_normalize_edges([[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]]) == [[0,0,0,0],[0,0,0,0],[0,0,0,0]]);
|
||||||
assert(normalize_edges([[0,0,0,0],[0,0,0,0],[0,0,0,0]]) == [[0,0,0,0],[0,0,0,0],[0,0,0,0]]);
|
assert(_normalize_edges([[0,0,0,0],[0,0,0,0],[0,0,0,0]]) == [[0,0,0,0],[0,0,0,0],[0,0,0,0]]);
|
||||||
assert(normalize_edges([[1,1,1,1],[1,1,1,1],[1,1,1,1]]) == [[1,1,1,1],[1,1,1,1],[1,1,1,1]]);
|
assert(_normalize_edges([[1,1,1,1],[1,1,1,1],[1,1,1,1]]) == [[1,1,1,1],[1,1,1,1],[1,1,1,1]]);
|
||||||
assert(normalize_edges([[2,2,2,2],[2,2,2,2],[2,2,2,2]]) == [[1,1,1,1],[1,1,1,1],[1,1,1,1]]);
|
assert(_normalize_edges([[2,2,2,2],[2,2,2,2],[2,2,2,2]]) == [[1,1,1,1],[1,1,1,1],[1,1,1,1]]);
|
||||||
}
|
}
|
||||||
test_normalize_edges();
|
test__normalize_edges();
|
||||||
|
|
||||||
|
|
||||||
module test_edges() {
|
module test_edges() {
|
||||||
|
@ -90,24 +90,24 @@ module test_edges() {
|
||||||
test_edges();
|
test_edges();
|
||||||
|
|
||||||
|
|
||||||
module test_corner_edge_count() {
|
module test__corner_edge_count() {
|
||||||
edges = edges([TOP,FRONT+RIGHT]);
|
edges = edges([TOP,FRONT+RIGHT]);
|
||||||
assert(corner_edge_count(edges,TOP+FRONT+RIGHT) == 3);
|
assert(_corner_edge_count(edges,TOP+FRONT+RIGHT) == 3);
|
||||||
assert(corner_edge_count(edges,TOP+FRONT+LEFT) == 2);
|
assert(_corner_edge_count(edges,TOP+FRONT+LEFT) == 2);
|
||||||
assert(corner_edge_count(edges,BOTTOM+FRONT+RIGHT) == 1);
|
assert(_corner_edge_count(edges,BOTTOM+FRONT+RIGHT) == 1);
|
||||||
assert(corner_edge_count(edges,BOTTOM+FRONT+LEFT) == 0);
|
assert(_corner_edge_count(edges,BOTTOM+FRONT+LEFT) == 0);
|
||||||
}
|
}
|
||||||
test_corner_edge_count();
|
test__corner_edge_count();
|
||||||
|
|
||||||
|
|
||||||
module test_corner_edges() {
|
module test__corner_edges() {
|
||||||
edges = edges([TOP,FRONT+RIGHT]);
|
edges = edges([TOP,FRONT+RIGHT]);
|
||||||
assert_equal(corner_edges(edges,TOP+FRONT+RIGHT), [1,1,1]);
|
assert_equal(_corner_edges(edges,TOP+FRONT+RIGHT), [1,1,1]);
|
||||||
assert_equal(corner_edges(edges,TOP+FRONT+LEFT), [1,1,0]);
|
assert_equal(_corner_edges(edges,TOP+FRONT+LEFT), [1,1,0]);
|
||||||
assert_equal(corner_edges(edges,BOTTOM+FRONT+RIGHT), [0,0,1]);
|
assert_equal(_corner_edges(edges,BOTTOM+FRONT+RIGHT), [0,0,1]);
|
||||||
assert_equal(corner_edges(edges,BOTTOM+FRONT+LEFT), [0,0,0]);
|
assert_equal(_corner_edges(edges,BOTTOM+FRONT+LEFT), [0,0,0]);
|
||||||
}
|
}
|
||||||
test_corner_edges();
|
test__corner_edges();
|
||||||
|
|
||||||
|
|
||||||
module test_corners() {
|
module test_corners() {
|
||||||
|
@ -174,36 +174,36 @@ module test_corners() {
|
||||||
test_corners();
|
test_corners();
|
||||||
|
|
||||||
|
|
||||||
module test_is_corner_array() {
|
module test__is_corner_array() {
|
||||||
edges = edges([TOP,FRONT+RIGHT]);
|
edges = edges([TOP,FRONT+RIGHT]);
|
||||||
corners = corners([TOP,FRONT+RIGHT]);
|
corners = corners([TOP,FRONT+RIGHT]);
|
||||||
assert(!is_corner_array(undef));
|
assert(!_is_corner_array(undef));
|
||||||
assert(!is_corner_array(true));
|
assert(!_is_corner_array(true));
|
||||||
assert(!is_corner_array(false));
|
assert(!_is_corner_array(false));
|
||||||
assert(!is_corner_array(INF));
|
assert(!_is_corner_array(INF));
|
||||||
assert(!is_corner_array(-INF));
|
assert(!_is_corner_array(-INF));
|
||||||
assert(!is_corner_array(NAN));
|
assert(!_is_corner_array(NAN));
|
||||||
assert(!is_corner_array(-4));
|
assert(!_is_corner_array(-4));
|
||||||
assert(!is_corner_array(0));
|
assert(!_is_corner_array(0));
|
||||||
assert(!is_corner_array(4));
|
assert(!_is_corner_array(4));
|
||||||
assert(!is_corner_array("foo"));
|
assert(!_is_corner_array("foo"));
|
||||||
assert(!is_corner_array([]));
|
assert(!_is_corner_array([]));
|
||||||
assert(!is_corner_array([4,5,6]));
|
assert(!_is_corner_array([4,5,6]));
|
||||||
assert(!is_corner_array([2:3:9]));
|
assert(!_is_corner_array([2:3:9]));
|
||||||
assert(!is_corner_array(edges));
|
assert(!_is_corner_array(edges));
|
||||||
assert(is_corner_array(corners));
|
assert(_is_corner_array(corners));
|
||||||
}
|
}
|
||||||
test_is_corner_array();
|
test__is_corner_array();
|
||||||
|
|
||||||
|
|
||||||
module test_normalize_corners() {
|
module test__normalize_corners() {
|
||||||
assert_equal(normalize_corners([-2,-2,-2,-2,-2,-2,-2,-2]), [0,0,0,0,0,0,0,0]);
|
assert_equal(_normalize_corners([-2,-2,-2,-2,-2,-2,-2,-2]), [0,0,0,0,0,0,0,0]);
|
||||||
assert_equal(normalize_corners([-1,-1,-1,-1,-1,-1,-1,-1]), [0,0,0,0,0,0,0,0]);
|
assert_equal(_normalize_corners([-1,-1,-1,-1,-1,-1,-1,-1]), [0,0,0,0,0,0,0,0]);
|
||||||
assert_equal(normalize_corners([0,0,0,0,0,0,0,0]), [0,0,0,0,0,0,0,0]);
|
assert_equal(_normalize_corners([0,0,0,0,0,0,0,0]), [0,0,0,0,0,0,0,0]);
|
||||||
assert_equal(normalize_corners([1,1,1,1,1,1,1,1]), [1,1,1,1,1,1,1,1]);
|
assert_equal(_normalize_corners([1,1,1,1,1,1,1,1]), [1,1,1,1,1,1,1,1]);
|
||||||
assert_equal(normalize_corners([2,2,2,2,2,2,2,2]), [1,1,1,1,1,1,1,1]);
|
assert_equal(_normalize_corners([2,2,2,2,2,2,2,2]), [1,1,1,1,1,1,1,1]);
|
||||||
}
|
}
|
||||||
test_normalize_corners();
|
test__normalize_corners();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue