Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion drawing.scad
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ module stroke(
translate(path[0]) {
$fn = segs(width[0]/2);
if (is_undef(endcap_angle1)) {
rotate_extrude(convexity=convexity) {
rotate_extrude(convexity=convexity,angle=360) {
right_half(planar=true) {
polygon(endcap_shape1);
}
Expand Down
31 changes: 16 additions & 15 deletions geometry.scad
Original file line number Diff line number Diff line change
Expand Up @@ -1784,27 +1784,28 @@ function point_in_polygon(point, poly, nonzero=false, eps=_EPSILON) =
// Topics: Geometry, Polygons, Lines, Intersection
// See Also: polygon_area(), centroid(), polygon_normal(), point_in_polygon(), polygon_line_intersection()
// Usage:
// pt = polygon_line_intersection(poly, line, [bounded], [nonzero], [eps]);
// pt_or_segments = polygon_line_intersection(poly, line, [bounded], [nonzero], [eps]);
// Description:
// Takes a possibly bounded line, and a 2D or 3D planar polygon, and finds their intersection. Note the polygon is
// treated as its boundary and interior, so the intersection may include both points and line segments.
// If the line does not intersect the polygon then returns `undef`.
// In 3D if the line is not on the plane of the polygon but intersects it then you get a single intersection point.
// Otherwise the polygon and line are in the same plane, or when your input is 2D, you get a list of segments and
// single point lists. Use `is_vector` to distinguish these two cases.
// Takes a possibly bounded line, and a 2D or 3D planar polygon, and finds their intersection. The polygon is
// treated as its boundary and interior, so the intersection may include both points and line segments.
// Returns:
// * If the line does not intersect the polygon: `undef`.
// * In 3D if the line is not coplanar with the polygon but intersects it: the intersection point as a 3-vector, `[x,y,z]`.
// * In the 2D case or the 3D case when the line is coplanar with the polygon: list of segments or degenerate single point "segments".
// .
// In the 2D case, a common result is a list containing a single segment, which lists the two intersection points
// with the boundary of the polygon.
// When single points are in the intersection (the line just touches a polygon corner) they appear on the segment
// list as lists of a single point
// (like single point segments) so a single point intersection in 2D has the form `[[[x,y,z]]]` as compared
// to a single point intersection in 3D, which has the form `[x,y,z]`. You can identify whether an entry in the
// segment list is a true segment by checking its length, which is 2 for a segment and 1 for a point.
// In 3D, you can distinguish output cases using {{is_vector()}}. When run on the output it returns `true` when the output is a single
// intersection point from a non-coplanar line.
// .
// In the 2D or coplanar case, the result is a **list** of segments, so the common case of a single segment will be a
// singleton list of the form `[[p1,p2]]`. A single point appears on the segment list as a degenerate segment or the form `[p]`,
// so this means in 3D a single point will appears as `[[[x,y,z]]]` in the coplanar case. This makes it possible to distinguish
// the coplanar and non-coplanar cases. An intersection featuring two segments and a point could look like `[[p1,p2], [q], [r1,r2]]`.
// To determine if an entry in the segment list is a true segment, check its length, which is 2 for a segment and 1 for a point.
// Arguments:
// poly = The 3D planar polygon to find the intersection with.
// line = A list of two distinct 3D points on the line.
// bounded = If false, the line is considered unbounded. If true, it is treated as a bounded line segment. If given as `[true, false]` or `[false, true]`, the boundedness of the points are specified individually, allowing the line to be treated as a half-bounded ray. Default: false (unbounded)
// nonzero = set to true to use the nonzero rule for determining it points are in a polygon. See point_in_polygon. Default: false.
// nonzero = set to true to use the nonzero rule for determining it points are in a polygon. See {{point_in_polygon()}}. Default: false.
// eps = Tolerance in geometric comparisons. Default: 1e-9
// Example(3D): The line intersects the 3d hexagon in a single point.
// hex = zrot(140,p=rot([-45,40,20],p=path3d(hexagon(r=15))));
Expand Down
34 changes: 31 additions & 3 deletions rounding.scad
Original file line number Diff line number Diff line change
Expand Up @@ -5045,9 +5045,37 @@ module prism_connector(profile, desc1, anchor1, desc2, anchor2, shift1, shift2,
// joint = 3;
// rounded_prism(rect(12), rect(8), h=15, joint_sides=joint,atype="prismoid")
// attach_prism(circle(r=3,$fn=128),RIGHT+FWD, length=4, fillet=2, edge_joint=joint, $fn=32);



// Example(3D,Big): Complicated example where we use attach_prism() to create attachments and then connect a bezier sweep to those attachments using descriptions. The blue line segments show the bezier control points. Note that we use {{bezier_sweep()}} rather than {{path_sweep()}} to ensure that the ends of the sweep mate properly, and setting `last_normal` ensures that the points on the attached prisms line up with the sweep.
// sq = subdivide_path(circle(r=3,$fn=7),maxlen=.5);
// vspace=20;
// bezlen=40;
// cylr=20;
// cylh=65;
// straightlen=5;
// smoothcurve=true; // true for C2 joint
// k=0.6;
// cyl(r=cylr,h=cylh, rounding=2, circum=true, $fn=256)
// let(cylinder=parent())
// attach_prism(sq,FWD,length=straightlen,shift=-vspace,fillet=2,spin=90)
// let(front=parent())
// restore(cylinder)
// attach_prism(sq, RIGHT, length=straightlen, shift=vspace, fillet=2,spin=90)
// let(right=parent())
// restore(cylinder)
// let(avg_dir = desc_dir(front,anchor="end") + desc_dir(right,anchor="end"),
// path=[
// desc_point(front,anchor="end"),
// if (smoothcurve) desc_point(front,anchor="end")+bezlen*(1-k)*desc_dir(front,anchor="end"),
// desc_point(front,anchor="end")+bezlen*desc_dir(front,anchor="end"),
// down(vspace/2,desc_point(cylinder,CTR)+ (cylr+straightlen+bezlen)*avg_dir),
// desc_point(right,anchor="end")+bezlen*desc_dir(right,anchor="end"),
// if (smoothcurve) desc_point(right,anchor="end")+bezlen*(1-k)*desc_dir(right,anchor="end"),
// desc_point(right,anchor="end")]
// )
// {
// bezier_sweep(zrot(90,sq), path, 40, last_normal=UP);
// color("lightblue")stroke(path);
// }


module attach_prism(profile, anchor, fillet=0, rounding=0, inside=false, l, length, h, height, endpoint, T=IDENT, shift=0, overlap=1,
Expand Down