CLIPLINE3D Clip a line with a box and return an edge. EDGE = clipLine3d(LINE, BOX); Clips the line LINE with the bounds given in BOX, and returns the corresponding edge. If the line lies totally outside of the box, returns a 1-by-6 row array containing only NaN's. If LINE is a N-by-6 array, with one line by row, returns the clipped edge coresponding to each line in a N-by-6 array. See also: lines3d, edges3d, createLine3d, clipRay3d
0001 function edge = clipLine3d(line, box) 0002 %CLIPLINE3D Clip a line with a box and return an edge. 0003 % 0004 % EDGE = clipLine3d(LINE, BOX); 0005 % Clips the line LINE with the bounds given in BOX, and returns the 0006 % corresponding edge. 0007 % 0008 % If the line lies totally outside of the box, returns a 1-by-6 row array 0009 % containing only NaN's. 0010 % 0011 % If LINE is a N-by-6 array, with one line by row, returns the clipped 0012 % edge coresponding to each line in a N-by-6 array. 0013 % 0014 % See also: 0015 % lines3d, edges3d, createLine3d, clipRay3d 0016 % 0017 0018 % --------- 0019 % author : David Legland 0020 % e-mail: david.legland@inra.fr 0021 % INRA - TPV URPOI - BIA IMASTE 0022 % created the 30/10/2008 from drawLine3d 0023 0024 % HISTORY 0025 % 30/10/2008 replace intersectPlaneLine by intersectLinePlane 0026 % 25/11/2008 improve test for bounds, and use more explicit code 0027 % 22/06/2009 fig bug, add support for several lines 0028 % 16/11/2010 use middle point for checking edge bounds 0029 0030 % get box limits 0031 xmin = box(1); xmax = box(2); 0032 ymin = box(3); ymax = box(4); 0033 zmin = box(5); zmax = box(6); 0034 0035 % extreme corners of the box 0036 p000 = [xmin ymin zmin]; 0037 p111 = [xmax ymax zmax]; 0038 0039 % main vectors 0040 ex = [1 0 0]; 0041 ey = [0 1 0]; 0042 ez = [0 0 1]; 0043 0044 % box faces parallel to Oxy 0045 planeZ0 = [p000 ex ey]; 0046 planeZ1 = [p111 ex ey]; 0047 0048 % box faces parallel to Oxz 0049 planeY0 = [p000 ex ez]; 0050 planeY1 = [p111 ex ez]; 0051 0052 % box faces parallel to Oyz 0053 planeX0 = [p000 ey ez]; 0054 planeX1 = [p111 ey ez]; 0055 0056 % number of lines 0057 nLines = size(line, 1); 0058 0059 % allocate memory for result 0060 edge = zeros(nLines, 6); 0061 0062 % iterate over lines to clip 0063 for i = 1:nLines 0064 0065 % compute intersection point with each plane 0066 ipZ0 = intersectLinePlane(line(i,:), planeZ0); 0067 ipZ1 = intersectLinePlane(line(i,:), planeZ1); 0068 ipY0 = intersectLinePlane(line(i,:), planeY0); 0069 ipY1 = intersectLinePlane(line(i,:), planeY1); 0070 ipX1 = intersectLinePlane(line(i,:), planeX1); 0071 ipX0 = intersectLinePlane(line(i,:), planeX0); 0072 0073 % concatenate resulting points 0074 points = [ipX0;ipX1;ipY0;ipY1;ipZ0;ipZ1]; 0075 0076 % compute position of each point on the line 0077 pos = linePosition3d(points, line(i,:)); 0078 0079 % keep only defined points 0080 ind = find(~isnan(pos)); 0081 pos = pos(ind); 0082 points = points(ind,:); 0083 0084 % sort points with respect to their position 0085 [pos, ind] = sort(pos); %#ok<ASGLU> 0086 points = points(ind, :); 0087 0088 % keep median points wrt to position. These points define the limit of 0089 % the clipped edge. 0090 nv = length(ind)/2; 0091 0092 % create resulting edge. 0093 edge(i,:) = [points(nv, :) points(nv+1, :)]; 0094 end 0095 0096 % check that middle point of the edge is contained in the box 0097 midX = mean(edge(:, [1 4]), 2); 0098 xOk = xmin <= midX & midX <= xmax; 0099 midY = mean(edge(:, [2 5]), 2); 0100 yOk = ymin <= midY & midY <= ymax; 0101 midZ = mean(edge(:, [3 6]), 2); 0102 zOk = zmin <= midZ & midZ <= zmax; 0103 0104 % if one of the bounding condition is not met, set edge to NaN 0105 edge (~(xOk & yOk & zOk), :) = NaN; 0106