How to extract intersection between two 3D shapes
19 views (last 30 days)
Show older comments
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 Comments
Joseph Olson
on 21 Feb 2022
Seems like the inShape function is what you want!
https://www.mathworks.com/matlabcentral/answers/496500-intersection-volume-of-two-3d-alphashapes
Answers (1)
DGM
on 21 Jun 2025
Moved: DGM
on 21 Jun 2025
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 Comments
See Also
Categories
Find more on Surface and Mesh Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
