How to extract intersection between two 3D shapes
18 ビュー (過去 30 日間)
古いコメントを表示
I have a two 3D shapes, one defined by a patch object, the other by a simple analytical function (in my case a sphere):
[verts, faces, cindex] = teapotGeometry;
sphere_origin = [1 1 1];
sphere_radius = 1;
figure;
p = patch('Faces',faces,'Vertices',verts,'FaceVertexCData',cindex,'FaceColor','interp');
sph = drawSphere([sphere_origin sphere_radius]); % using matGeom (https://github.com/mattools/matGeom)
I'd like a way to slice the patch into 2 or more sub-objects that contains the part of the teapot outside the sphere, and the one that is inside.
My main problems are that I don't know:
- How to find the exact intersection between the sphere and the 3D shape (not just the closest vertice, but the extrapolated one). (DONE: using surfaceintersection as @darova suggested)
- How to add the faces to the extrapolated vertices in a way that conserve the integrity of the teapot if i were to plot only the sub-objects found.
I suppose the right way to start is to find the faces that are intersecting the sphere like this:
out_pnt = find(vecnorm(verts-sphere_origin,2,2)>=sphere_radius);
out_faces = any(ismember(faces,out_pnt),2);
But going from there to finding the exact set of points that define the intersection is really difficult for me right now.
Any part of the answer could really help me, thanks in advance.
10 件のコメント
Joseph Olson
2022 年 2 月 21 日
Seems like the inShape function is what you want!
https://www.mathworks.com/matlabcentral/answers/496500-intersection-volume-of-two-3d-alphashapes
回答 (1 件)
DGM
2025 年 6 月 21 日
移動済み: DGM
2025 年 6 月 21 日
Normally, this would be my answer:
I was going to make another demo for this specific example, but there are a few problems. The given teapot model is represented using quadrilaterals instead of triangles, but that's fairly easy to convert. The bigger problem is that it's not a closed surface, and it contains at least one non-manifold vertex. That means we can't use CGAL on it unless we do a bunch of work to fix the model.
Using FEX #48613 can be done, but all it will give you is a list of edges in 3D. It won't return solid geometry. That doesn't seem like the intended goal.
EDIT:
I dug up a few alternate teapot models. A lot of them aren't valid solid geometry, and a lot of those that are have some other issues (extremely high-aspect triangles, near-coincident vertices) which result in problems due to the relatively limited precision of exported STLs. There are cleaner models than this one, but this one is smaller.
% given parameters
sphere_origin = [1.75 1 1]*3;
sphere_radius = 2.5;
% say you have some teapot geometry
T = stlread('utahteapot.stl'); % a different version (may still be problematic for CGAL)
Ft = T.ConnectivityList;
Vt = T.Points;
% and you have some sphere geometry
[X,Y,Z] = sphere(32); % using sphere to get gridded XYZ data
[Fs,Vs] = mesh2tri(X,Y,Z,'f'); % convert to triangulated FV data (FEX #28327)
Vs = Vs*sphere_radius + sphere_origin; % scale and offset
% preview display
patch('faces',Ft,'vertices',Vt,'facecolor','w','edgecolor','none');
hold on;
patch('faces',Fs,'vertices',Vs,'facecolor','w','edgecolor','none');
view(3); view(144,44); camlight;
axis equal; grid on
xlabel('X'); ylabel('Y'); zlabel('Z')

% do the CSG
[Fout Vout] = scad_op(Ft,Vt,Fs,Vs,'difference');
% plot the result
clf
patch('faces',Fout,'vertices',Vout,'facecolor','w','edgecolor','none');
view(3); view(144,44); camlight;
axis equal; grid on
xlabel('X'); ylabel('Y'); zlabel('Z')

If instead, you want the volume enclosed by their intersection, you can do that by specifying 'intersection' instead of 'difference'.

Again, all of this relies on external tools. The model file and scad_op() are attached. You'd still need OpenSCAD for it to work.
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Surface and Mesh Plots についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

