1
0
mirror of https://github.com/JustinSDK/dotSCAD.git synced 2025-08-23 06:43:10 +02:00

lines_intersection support 3D

This commit is contained in:
Justin Lin
2021-03-04 08:33:00 +08:00
parent 5a4a89a86b
commit 835db1717e
6 changed files with 32 additions and 12 deletions

View File

@@ -77,7 +77,6 @@ These examples incubate dotSCAD and dotSCAD refactors these examples. See [examp
- [bijection_offset](https://openhome.cc/eGossip/OpenSCAD/lib3x-bijection_offset.html)
- [contours](https://openhome.cc/eGossip/OpenSCAD/lib3x-contours.html)
- [in_shape](https://openhome.cc/eGossip/OpenSCAD/lib3x-in_shape.html)
- [lines_intersection](https://openhome.cc/eGossip/OpenSCAD/lib3x-lines_intersection.html)
- [trim_shape](https://openhome.cc/eGossip/OpenSCAD/lib3x-trim_shape.html)
### 2D/3D Function
@@ -86,6 +85,7 @@ These examples incubate dotSCAD and dotSCAD refactors these examples. See [examp
- [bezier_smooth](https://openhome.cc/eGossip/OpenSCAD/lib3x-bezier_smooth.html)
- [cross_sections](https://openhome.cc/eGossip/OpenSCAD/lib3x-cross_sections.html)
- [in_polyline](https://openhome.cc/eGossip/OpenSCAD/lib3x-in_polyline.html)
- [lines_intersection](https://openhome.cc/eGossip/OpenSCAD/lib3x-lines_intersection.html)
- [paths2sections](https://openhome.cc/eGossip/OpenSCAD/lib3x-paths2sections.html)
- [path_scaling_sections](https://openhome.cc/eGossip/OpenSCAD/lib3x-path_scaling_sections.html)
- [midpt_smooth](https://openhome.cc/eGossip/OpenSCAD/lib3x-midpt_smooth.html)

View File

@@ -6,8 +6,8 @@ Find the intersection of two line segments. Return `[]` if lines don't intersect
## Parameters
- `line1` : Two points of 2D line1.
- `line2` : Two points of 2D line2.
- `line1` : Two points of 2D or 3D line1.
- `line2` : Two points of 2D or 3D line2.
- `ext` : Default to `false`, which doesn't extend a line to an intersection with another line.
- `epsilon` : An upper bound on the relative error due to rounding in floating point arithmetic. Default to 0.0001.
@@ -21,3 +21,7 @@ Find the intersection of two line segments. Return `[]` if lines don't intersect
assert(lines_intersection(line1, line2) == [0, 2.5]);
assert(lines_intersection(line1, line3, ext = true) == [0, 10]);
line4 = [[0, 0, 0], [10, 10, 10]];
line5 = [[10, 0, 0], [0, 10, 10]];
assert(lines_intersection(line4, line5) == [5, 5, 5]);

View File

@@ -1,4 +1,4 @@
function __line_intersection(line_pts1, line_pts2, epsilon = 0.0001) =
function __line_intersection2(line_pts1, line_pts2, epsilon = 0.0001) =
let(
a1 = line_pts1[0],
a2 = line_pts1[1],
@@ -11,3 +11,20 @@ function __line_intersection(line_pts1, line_pts2, epsilon = 0.0001) =
)
abs(c) < epsilon ? [] : // they are parallel or conincident edges
a1 + a * cross(s, b) / c;
function __line_intersection3(line_pts1, line_pts2, epsilon = 0.0001) =
let(
a1 = line_pts1[0],
a2 = line_pts1[1],
b1 = line_pts2[0],
b2 = line_pts2[1],
a = a2 - a1,
b = b2 - b1,
s = b1 - a1,
n1 = cross(a, b),
norm_n1 = norm(n1)
)
cross(a, s) * (b2 - a1) != 0 || // they aren't coplanar
norm_n1 < epsilon ? [] : // they are parallel or conincident edges
let(n2 = cross(s, b))
a1 + a * (norm(n2) / norm_n1 * (n1 * n2 >= 0 ? 1 : -1));

View File

@@ -38,7 +38,7 @@ function _bijection_offset_impl(pts, d, epsilon) =
offset_es = _bijection__bijection_offset_edges(es, d),
leng = len(offset_es),
leng_minus_one = leng - 1,
last_p = __line_intersection(offset_es[leng_minus_one], offset_es[0], epsilon)
last_p = __line_intersection2(offset_es[leng_minus_one], offset_es[0], epsilon)
)
concat(
last_p != [] && last_p == last_p ? [last_p] : [],
@@ -47,7 +47,7 @@ function _bijection_offset_impl(pts, d, epsilon) =
let(
this_edge = offset_es[i],
next_edge = offset_es[i + 1],
p = __line_intersection(this_edge, next_edge, epsilon)
p = __line_intersection2(this_edge, next_edge, epsilon)
)
// p == p to avoid [nan, nan], because [nan, nan] != [nan, nan]
if(p != [] && p == p) p

View File

@@ -4,7 +4,7 @@ use <../__comm__/__lines_from.scad>;
function _trim_shape_any_intersection_sub(lines, line, lines_leng, i, epsilon) =
let(
p = __line_intersection(lines[i], line, epsilon)
p = __line_intersection2(lines[i], line, epsilon)
)
(p != [] && __in_line(line, p, epsilon) && __in_line(lines[i], p, epsilon)) ? [i, p] : _trim_shape_any_intersection(lines, line, lines_leng, i + 1, epsilon);

View File

@@ -12,8 +12,7 @@ use <__comm__/__line_intersection.scad>;
use <__comm__/__in_line.scad>;
function lines_intersection(line1, line2, ext = false, epsilon = 0.0001) =
let(
pt = __line_intersection(line1, line2, epsilon)
)
let(pt = len(line1[0]) == 2 ? __line_intersection2(line1, line2, epsilon) :
__line_intersection3(line1, line2, epsilon))
ext ? pt :
pt != [] && __in_line(line1, pt, epsilon) && __in_line(line2, pt, epsilon) ? pt : [];