mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-17 18:09:40 +00:00
Merge pull request #492 from RonaldoCMP/master
Test for convexity of 3d polygons
This commit is contained in:
commit
a1ae5a5057
2 changed files with 19 additions and 16 deletions
|
@ -1074,6 +1074,7 @@ function distance_from_plane(plane, point) =
|
||||||
let( plane = normalize_plane(plane) )
|
let( plane = normalize_plane(plane) )
|
||||||
point3d(plane)* point - plane[3];
|
point3d(plane)* point - plane[3];
|
||||||
|
|
||||||
|
|
||||||
// Returns [POINT, U] if line intersects plane at one point.
|
// Returns [POINT, U] if line intersects plane at one point.
|
||||||
// Returns [LINE, undef] if the line is on the plane.
|
// Returns [LINE, undef] if the line is on the plane.
|
||||||
// Returns undef if line is parallel to, but not on the given plane.
|
// Returns undef if line is parallel to, but not on the given plane.
|
||||||
|
@ -1596,7 +1597,6 @@ function circle_circle_tangents(c1,r1,c2,r2,d1,d2) =
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Function: circle_line_intersection()
|
// Function: circle_line_intersection()
|
||||||
// Usage:
|
// Usage:
|
||||||
// isect = circle_line_intersection(c,r,line,<bounded>,<eps>);
|
// isect = circle_line_intersection(c,r,line,<bounded>,<eps>);
|
||||||
|
@ -1629,7 +1629,6 @@ function circle_line_intersection(c,r,line,d,bounded=false,eps=EPSILON) =
|
||||||
let( offset = sqrt(r*r-d*d),
|
let( offset = sqrt(r*r-d*d),
|
||||||
uvec=unit(line[1]-line[0])
|
uvec=unit(line[1]-line[0])
|
||||||
) [closest-offset*uvec, closest+offset*uvec]
|
) [closest-offset*uvec, closest+offset*uvec]
|
||||||
|
|
||||||
)
|
)
|
||||||
[for(p=isect)
|
[for(p=isect)
|
||||||
if ((!bounded[0] || (p-line[0])*(line[1]-line[0])>=0)
|
if ((!bounded[0] || (p-line[0])*(line[1]-line[0])>=0)
|
||||||
|
@ -1637,7 +1636,6 @@ function circle_line_intersection(c,r,line,d,bounded=false,eps=EPSILON) =
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Section: Pointlists
|
// Section: Pointlists
|
||||||
|
|
||||||
|
|
||||||
|
@ -1758,27 +1756,31 @@ function polygon_area(poly, signed=false) =
|
||||||
// Usage:
|
// Usage:
|
||||||
// is_convex_polygon(poly);
|
// is_convex_polygon(poly);
|
||||||
// Description:
|
// Description:
|
||||||
// Returns true if the given 2D polygon is convex. The result is meaningless if the polygon is not simple (self-intersecting).
|
// Returns true if the given 2D or 3D polygon is convex.
|
||||||
// If the points are collinear the result is true.
|
// The result is meaningless if the polygon is not simple (self-intersecting) or non coplanar.
|
||||||
|
// If the points are collinear an error is generated.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// poly = Polygon to check.
|
// poly = Polygon to check.
|
||||||
// Example:
|
// Example:
|
||||||
// is_convex_polygon(circle(d=50)); // Returns: true
|
// is_convex_polygon(circle(d=50)); // Returns: true
|
||||||
|
// is_convex_polygon(rot([50,120,30], p=path3d(circle(1,$fn=50)))); // Returns: true
|
||||||
// Example:
|
// Example:
|
||||||
// spiral = [for (i=[0:36]) let(a=-i*10) (10+i)*[cos(a),sin(a)]];
|
// spiral = [for (i=[0:36]) let(a=-i*10) (10+i)*[cos(a),sin(a)]];
|
||||||
// is_convex_polygon(spiral); // Returns: false
|
// is_convex_polygon(spiral); // Returns: false
|
||||||
function is_convex_polygon(poly) =
|
function is_convex_polygon(poly) =
|
||||||
assert(is_path(poly,dim=2), "The input should be a 2D polygon." )
|
assert(is_path(poly), "The input should be a 2D or 3D polygon." )
|
||||||
let( l = len(poly) )
|
let( lp = len(poly),
|
||||||
len([for( i = l-1,
|
p0 = poly[0] )
|
||||||
c = cross(poly[(i+1)%l]-poly[i], poly[(i+2)%l]-poly[(i+1)%l]),
|
assert( lp>=3 , "A polygon must have at least 3 points" )
|
||||||
s = sign(c);
|
let( crosses = [for(i=[0:1:lp-1]) cross(poly[(i+1)%lp]-poly[i], poly[(i+2)%lp]-poly[(i+1)%lp]) ] )
|
||||||
i>=0 && sign(c)==s;
|
len(p0)==2
|
||||||
i = i-1,
|
? assert( !approx(max(crosses)) && !approx(min(crosses)), "The points are collinear" )
|
||||||
c = i<0? 0: cross(poly[(i+1)%l]-poly[i],poly[(i+2)%l]-poly[(i+1)%l]),
|
min(crosses) >=0 || max(crosses)<=0
|
||||||
s = s==0 ? sign(c) : s
|
: let( prod = crosses*sum(crosses),
|
||||||
) i
|
minc = min(prod),
|
||||||
])== l;
|
maxc = max(prod) )
|
||||||
|
assert( !approx(maxc-minc), "The points are collinear" )
|
||||||
|
minc>=0 || maxc<=0;
|
||||||
|
|
||||||
|
|
||||||
// Function: polygon_shift()
|
// Function: polygon_shift()
|
||||||
|
|
|
@ -844,6 +844,7 @@ module test_polygon_area() {
|
||||||
module test_is_convex_polygon() {
|
module test_is_convex_polygon() {
|
||||||
assert(is_convex_polygon([[1,1],[-1,1],[-1,-1],[1,-1]]));
|
assert(is_convex_polygon([[1,1],[-1,1],[-1,-1],[1,-1]]));
|
||||||
assert(is_convex_polygon(circle(r=50,$fn=1000)));
|
assert(is_convex_polygon(circle(r=50,$fn=1000)));
|
||||||
|
assert(is_convex_polygon(rot([50,120,30], p=path3d(circle(1,$fn=50)))));
|
||||||
assert(!is_convex_polygon([[1,1],[0,0],[-1,1],[-1,-1],[1,-1]]));
|
assert(!is_convex_polygon([[1,1],[0,0],[-1,1],[-1,-1],[1,-1]]));
|
||||||
}
|
}
|
||||||
*test_is_convex_polygon();
|
*test_is_convex_polygon();
|
||||||
|
|
Loading…
Reference in a new issue