Finding points in a plane
If the planes defined by pl1, pl2 are parallel then with the following procedure, we can construct parallel intermediate planes for each lambda value.
gr1 = Table[ParametricPlot3D[pl1[[k]] + lambda (pl2[[k]] - pl1[[k]]), {lambda, 0, 1}, PlotStyle -> {Thick, Red}], {k, 1,4}];
gr2 = Table[Graphics3D[Polygon[{pl1[[1]] + lambda (pl2[[1]] - pl1[[1]]), pl1[[2]] + lambda (pl2[[2]] - pl1[[2]]), pl1[[3]] + lambda (pl2[[3]] - pl1[[3]]), pl1[[4]] + lambda (pl2[[4]] - pl1[[4]])}]], {lambda, 0, 1, 0.2}];
Show[gr1, gr2, PlotRange -> All]
NOTE
Given a plane defined by three points like
pts = {{2.15565, 1.90829, 4.10935}, {2.15565, 10.3417, 4.10935}, {18.0059, 10.3417, 4.10935}};
and a segment
seg = {{1.53685, 1, 0.6}, {2.77444, 2.81657, 7.6187}};
the intersection point is calculated as pint the solution lambda for
sol = NSolve[(seg[[1]]+lambda(seg[[2]]-seg[[1]])-pts[[3]]).Cross[pts[[1]]-pts[[3]],pts[[2]]-pts[[3]]] == 0,lambda][[1]]
If[0 <= (lambda /. sol) <= 1, pint = seg[[1]] + lambda (seg[[2]] - seg[[1]]) /. sol, Print["No intersection"]]
If[0 <= (lambda /. sol) <= 1,
gr1 = ParametricPlot3D[seg[[1]] + lambda (seg[[2]] - seg[[1]]),{lambda, 0, 1}, PlotStyle -> {Red, Thick}];
gr2 = Graphics3D[{Green, Sphere[pint, 0.1]}];
gr3 = Graphics3D[Polygon[pts]];
Show[gr1, gr2, gr3, PlotRange -> {{pint[[1]] - 2, pint[[1]] + 2}, {pint[[2]] - 2, pint[[2]] + 2}, {pint[[3]] - 2, pint[[3]] + 2}}]
]
lines = MapThread[Line[{#1, #2}] &, {pl1, pl2}];
plane = Polygon[# + {0, 0, 5.6187} & /@ pl1];
intersections = (RegionIntersection[plane, #] & /@ lines)[[All, 1, 1]];
Graphics3D[{Red, Thick, lines, Opacity[0.1], Polygon[pl1],
Blue, Polygon[pl2], Black, plane, Green, Polygon@intersections,
Opacity[1], Sphere[#, .3] & /@ intersections}, Boxed -> False]
Update: An alternative approach to find the intersections:
scale = Rescale[.6 + 5.6187, MinMax[{pl1[[1, -1]], pl2[[1, -1]]}], {0, 1}];
intersections2 = pl1 + scale (pl2 - pl1) ;
intersections2 == intersections
True
Graphics3D[{Red, Thick, lines, Opacity[.1], Blue, Hexahedron[pts],
Black, plane, Green, Polygon@intersections2, Opacity[1],
Sphere[#, .2] & /@ intersections2}, Boxed -> False]
Update 2: A purely graphical approach using ParametricPlot3D
(as in Cesareo's answer) with MeshFunctions
and Mesh
options to find the desired intersections:
Show[ParametricPlot3D[pl1 + λ (pl2 - pl1), {λ, 0, 1},
PlotStyle -> Directive[Red, Thick],
MeshFunctions -> {#3 &},
Mesh -> {{.06 + 5.6187}},
MeshStyle -> ({Green, Sphere[#, .2] & @@ #} &)],
Graphics3D[{Opacity[0.1], Red, Polygon[pl1], Blue, Polygon[pl2], Black, plane}],
Boxed -> False, Axes -> False]
I'm recording my approach to this problem to (a) have a repository for when I inevitably forget how to do this and (b) to avoid muddying up the question which others have provided helpful answers to.
Here's my somewhat ugly approach having learned that knowing the length (via Norm
) and direction (via Normalize
) of the edges, I can construct a parallel edge with a shorter length that can be readily translated in the x and y directions.
th = {1, .5, 2};
dir = {{1, 1}, {1, -1}, {-1, -1}, {-1, 1}};
pl1 = pts[[{0, 4, 7, 3} + 1]];
pl2 = pts[[{1, 5, 6, 2} + 1]];
tr[pt_, th_, d_] := Module[{v = Last@pt - First@pt, u},
u = (1 - th[[3]]/v[[3]]) Norm@v Normalize@v;
u = # + {d[[1]], d[[2]], 0} th & /@ {First@pt, u + First@pt}
];
Graphics3D[{Thick,
Red, MapThread[Line[{#1, #2}] &, {pl1, pl2}],
{Opacity[0.1], Polygon[pl1], Polygon[pl2]},
Blue, MapThread[Line[tr[{#1, #2}, th, #3]] &, {pl1, pl2, dir}]
}]
Hexagon
was new to me, which makes drawing the shell and cutout regions fairly straightforward. RegionDifference
works like a charm on these shapes.
cutout = Region@
Hexahedron@
Flatten[MapThread[tr[{#1, #2}, th, #3] &, {pl1, pl2, dir}], {2, 1}]
shell = Region[Hexahedron[pts[[1 ;; 8]]]]
RegionDifference[shell, cutout]