Home > matGeom > meshes3d > intersectPlaneMesh.m

intersectPlaneMesh

PURPOSE ^

Compute the polygons resulting from plane-mesh intersection.

SYNOPSIS ^

function polys = intersectPlaneMesh(plane, v, f)

DESCRIPTION ^

 Compute the polygons resulting from plane-mesh intersection.

   POLYS = intersectPlaneMesh(P, V, F)
   Computes the intersection between a plane and a mesh. The result is a
   cell array of polygons. 
   The plane P is given as:
   P = [X0 Y0 Z0  DX1 DY1 DZ1  DX2 DY2 DZ2]
   The mesh is given as numeric array V of vertex coordinates and an array
   of (triangular) face vertex indices.


   Example
     % Intersect a cube by a plane
     [v f] = createCube; v = v * 10;
     plane = createPlane([5 5 5], [3 4 5]);
     % draw the primitives
     figure; hold on; set(gcf, 'renderer', 'opengl');
     axis([-10 20 -10 20 -10 20]); view(3);
     drawMesh(v, f); drawPlane3d(plane);
     % compute intersection polygon
     polys = intersectPlaneMesh(plane, v, f);
     drawPolygon3d(polys, 'LineWidth', 2);

     % Intersect a torus by a set of planes, and draw the results
     % first creates a torus slightly shifted and rotated
     torus = [.5 .6 .7   30 10   3 4];
     figure; drawTorus(torus, 'nTheta', 180, 'nPhi', 180);
     hold on; view (3); axis equal; light;
     % convert to mesh representation
     [v, f] = torusMesh(torus, 'nTheta', 64, 'nPhi', 64);
     % compute intersections with collection of planes
     xList = -50:5:50;
     polySet = cell(length(xList), 1);
     for i = 1:length(xList)
         x0 = xList(i);
         plane = createPlane([x0 .5 .5], [1 .2 .3]);
         polySet{i} = intersectPlaneMesh2(plane, v, f);
     end
     % draw the resulting 3D polygons
     drawPolygon3d(polySet, 'lineWidth', 2, 'color', 'k')


   See also
     meshes3d, intersectPlanes, intersectEdgePlane

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function polys = intersectPlaneMesh(plane, v, f)
0002 % Compute the polygons resulting from plane-mesh intersection.
0003 %
0004 %   POLYS = intersectPlaneMesh(P, V, F)
0005 %   Computes the intersection between a plane and a mesh. The result is a
0006 %   cell array of polygons.
0007 %   The plane P is given as:
0008 %   P = [X0 Y0 Z0  DX1 DY1 DZ1  DX2 DY2 DZ2]
0009 %   The mesh is given as numeric array V of vertex coordinates and an array
0010 %   of (triangular) face vertex indices.
0011 %
0012 %
0013 %   Example
0014 %     % Intersect a cube by a plane
0015 %     [v f] = createCube; v = v * 10;
0016 %     plane = createPlane([5 5 5], [3 4 5]);
0017 %     % draw the primitives
0018 %     figure; hold on; set(gcf, 'renderer', 'opengl');
0019 %     axis([-10 20 -10 20 -10 20]); view(3);
0020 %     drawMesh(v, f); drawPlane3d(plane);
0021 %     % compute intersection polygon
0022 %     polys = intersectPlaneMesh(plane, v, f);
0023 %     drawPolygon3d(polys, 'LineWidth', 2);
0024 %
0025 %     % Intersect a torus by a set of planes, and draw the results
0026 %     % first creates a torus slightly shifted and rotated
0027 %     torus = [.5 .6 .7   30 10   3 4];
0028 %     figure; drawTorus(torus, 'nTheta', 180, 'nPhi', 180);
0029 %     hold on; view (3); axis equal; light;
0030 %     % convert to mesh representation
0031 %     [v, f] = torusMesh(torus, 'nTheta', 64, 'nPhi', 64);
0032 %     % compute intersections with collection of planes
0033 %     xList = -50:5:50;
0034 %     polySet = cell(length(xList), 1);
0035 %     for i = 1:length(xList)
0036 %         x0 = xList(i);
0037 %         plane = createPlane([x0 .5 .5], [1 .2 .3]);
0038 %         polySet{i} = intersectPlaneMesh2(plane, v, f);
0039 %     end
0040 %     % draw the resulting 3D polygons
0041 %     drawPolygon3d(polySet, 'lineWidth', 2, 'color', 'k')
0042 %
0043 %
0044 %   See also
0045 %     meshes3d, intersectPlanes, intersectEdgePlane
0046 %
0047 
0048 % ------
0049 % Author: David Legland
0050 % e-mail: david.legland@inra.fr
0051 % Created: 2012-07-31,    using Matlab 7.9.0.529 (R2009b)
0052 % Copyright 2012 INRA - Cepia Software Platform.
0053 
0054 e = [];
0055 if isstruct(v)
0056     f = v.faces;
0057     if isfield(v, 'edges')
0058         e = v.edges;
0059     end
0060     v = v.vertices;
0061 end
0062 
0063 
0064 %% Computation of crossing edges
0065 
0066 % compute the edge list
0067 if isempty(e)
0068     e = meshEdges(f);
0069 end
0070 edges = [ v(e(:,1), :) v(e(:,2), :) ];
0071 
0072 % identify which edges cross the mesh
0073 inds = isBelowPlane(v, plane);
0074 edgeCrossInds = find(sum(inds(e), 2) == 1);
0075 
0076 % compute one intersection point for each edge
0077 intersectionPoints = intersectEdgePlane(edges(edgeCrossInds, :), plane);
0078 
0079 
0080 
0081 %% mapping edges <-> faces
0082 % identify for each face the indices of edges that intersect the plane, as
0083 % well as for each edge, the indices of the two faces around it.
0084 % We expect each face to contain either 0 or 2 intersecting edges.
0085 %
0086 
0087 nFaces = length(f);
0088 faceEdges = cell(1, nFaces);
0089 nCrossEdges = length(edgeCrossInds);
0090 crossEdgeFaces = zeros(nCrossEdges, 2);
0091 
0092 for iEdge = 1:length(edgeCrossInds)
0093     edge = e(edgeCrossInds(iEdge), :);
0094     indFaces = find(sum(ismember(f, edge), 2) == 2);
0095     
0096     if length(indFaces) ~= 2
0097         error('crossing edge %d (%d,%d) is associated to %d faces', ...
0098             iEdge, edge(1), edge(2), length(indFaces));
0099     end
0100     
0101     crossEdgeFaces(iEdge, :) = indFaces;
0102     
0103     for iFace = 1:length(indFaces)
0104         indEdges = faceEdges{indFaces(iFace)};
0105         indEdges = [indEdges iEdge]; %#ok<AGROW>
0106         faceEdges{indFaces(iFace)} = indEdges;
0107     end
0108 end
0109 
0110 
0111 %% Iterate on edges and faces to form polygons
0112 
0113 % initialize an array indicating which indices need to be processed
0114 nCrossEdges = length(edgeCrossInds);
0115 remainingCrossEdges = true(nCrossEdges, 1);
0116 
0117 % create empty cell array of polygons
0118 polys = {};
0119 
0120 % iterate while there are some crossing edges to process
0121 while any(remainingCrossEdges)
0122     
0123     % start at any edge, mark it as current
0124     startEdgeIndex = find(remainingCrossEdges, 1, 'first');
0125     currentEdgeIndex = startEdgeIndex;
0126     
0127     % mark current edge as processed
0128     remainingCrossEdges(currentEdgeIndex) = false;
0129     
0130     % initialize new set of edge indices
0131     polyEdgeInds = currentEdgeIndex;
0132 
0133     % choose one of the two faces around the edge
0134     currentFace = crossEdgeFaces(currentEdgeIndex, 1);
0135 
0136     % iterate along current face-edge couples until back to first edge
0137     while true
0138         % find the index of next crossing edge
0139         inds = faceEdges{currentFace};
0140         currentEdgeIndex = inds(inds ~= currentEdgeIndex);
0141      
0142         % mark current edge as processed
0143         remainingCrossEdges(currentEdgeIndex) = false;
0144     
0145         % find the index of the other face containing current edge
0146         inds = crossEdgeFaces(currentEdgeIndex, :);
0147         currentFace = inds(inds ~= currentFace);
0148     
0149         % check end of current loop
0150         if currentEdgeIndex == startEdgeIndex
0151             break;
0152         end
0153         
0154         % add index of current edge
0155         polyEdgeInds = [polyEdgeInds currentEdgeIndex]; %#ok<AGROW>
0156     end
0157     
0158     % create polygon, and add it to list of polygons
0159     poly = intersectionPoints(polyEdgeInds, :);
0160     polys = [polys, {poly}]; %#ok<AGROW>
0161 end

Generated on Wed 16-Feb-2022 15:10:47 by m2html © 2003-2019