mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
Fix path_normals to handle 2d and better error message.
Improve error message for bogus endcaps to stroke() and running unit() on a zero vector
This commit is contained in:
parent
029cbb8997
commit
1627c3409d
3 changed files with 26 additions and 15 deletions
36
paths.scad
36
paths.scad
|
@ -351,22 +351,32 @@ function path_tangents(path, closed=false, uniform=true) =
|
||||||
// norms = path_normals(path, <tangents>, <closed>);
|
// norms = path_normals(path, <tangents>, <closed>);
|
||||||
// Description:
|
// Description:
|
||||||
// Compute the normal vector to the input path. This vector is perpendicular to the
|
// Compute the normal vector to the input path. This vector is perpendicular to the
|
||||||
// path tangent and lies in the plane of the curve. When there are collinear points,
|
// path tangent and lies in the plane of the curve. For 3d paths we define the plane of the curve
|
||||||
// the curve does not define a unique plane and the normal is not uniquely defined.
|
// at path point i to be the plane defined by point i and its two neighbors. At the endpoints of open paths
|
||||||
|
// we use the three end points. The computed normal is the one lying in this plane and pointing to the
|
||||||
|
// right of the direction of the path. If points are collinear then the path does not define a unique plane
|
||||||
|
// and hence the (right pointing) normal is not uniquely defined. In this case the function issues an error.
|
||||||
|
// For 2d paths the plane is always defined so the normal fails to exist only
|
||||||
|
// when the derivative is zero (in the case of repeated points).
|
||||||
function path_normals(path, tangents, closed=false) =
|
function path_normals(path, tangents, closed=false) =
|
||||||
assert(is_path(path))
|
assert(is_path(path,[2,3]))
|
||||||
assert(is_bool(closed))
|
assert(is_bool(closed))
|
||||||
let( tangents = default(tangents, path_tangents(path,closed)) )
|
let(
|
||||||
assert(is_path(tangents))
|
tangents = default(tangents, path_tangents(path,closed)),
|
||||||
|
dim=len(path[0])
|
||||||
|
)
|
||||||
|
assert(is_path(tangents) && len(tangents[0])==dim,"Dimensions of path and tangents must match")
|
||||||
[
|
[
|
||||||
for(i=idx(path)) let(
|
for(i=idx(path))
|
||||||
pts = i==0? (closed? select(path,-1,1) : select(path,0,2)) :
|
let(
|
||||||
i==len(path)-1? (closed? select(path,i-1,i+1) : select(path,i-2,i)) :
|
pts = i==0 ? (closed? select(path,-1,1) : select(path,0,2))
|
||||||
select(path,i-1,i+1)
|
: i==len(path)-1 ? (closed? select(path,i-1,i+1) : select(path,i-2,i))
|
||||||
) unit(cross(
|
: select(path,i-1,i+1)
|
||||||
cross(pts[1]-pts[0], pts[2]-pts[0]),
|
)
|
||||||
tangents[i]
|
dim == 2 ? [tangents[i].y,-tangents[i].x]
|
||||||
))
|
: let(v=cross(cross(pts[1]-pts[0], pts[2]-pts[0]),tangents[i]))
|
||||||
|
assert(norm(v)>EPSILON, "3D path contains collinear points")
|
||||||
|
v
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,8 @@ module stroke(
|
||||||
cap=="tail"? [[0,0], [w/2,l2], [w/2,l2-l], [0,-l], [-w/2,l2-l], [-w/2,l2]] :
|
cap=="tail"? [[0,0], [w/2,l2], [w/2,l2-l], [0,-l], [-w/2,l2-l], [-w/2,l2]] :
|
||||||
cap=="tail2"? [[w/2,0], [w/2,-l], [0,-l-l2], [-w/2,-l], [-w/2,0]] :
|
cap=="tail2"? [[w/2,0], [w/2,-l], [0,-l-l2], [-w/2,-l], [-w/2,0]] :
|
||||||
is_path(cap)? cap :
|
is_path(cap)? cap :
|
||||||
[]
|
is_undef(cap)? [] :
|
||||||
|
assert(false, str("Invalid endcap: ",cap))
|
||||||
) * linewidth;
|
) * linewidth;
|
||||||
|
|
||||||
assert(is_bool(closed));
|
assert(is_bool(closed));
|
||||||
|
|
|
@ -128,7 +128,7 @@ function vceil(v) =
|
||||||
// unit([0,0,0]); // Asserts an error.
|
// unit([0,0,0]); // Asserts an error.
|
||||||
function unit(v, error=[[["ASSERT"]]]) =
|
function unit(v, error=[[["ASSERT"]]]) =
|
||||||
assert(is_vector(v), str("Expected a vector. Got: ",v))
|
assert(is_vector(v), str("Expected a vector. Got: ",v))
|
||||||
norm(v)<EPSILON? (error==[[["ASSERT"]]]? assert(norm(v)>=EPSILON) : error) :
|
norm(v)<EPSILON? (error==[[["ASSERT"]]]? assert(norm(v)>=EPSILON,"Tried to normalize a zero vector") : error) :
|
||||||
v/norm(v);
|
v/norm(v);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue