CLIPLINE Clip a line with a box. EDGE = clipLine(LINE, BOX); LINE is a straight line given as a 4 element row vector: [x0 y0 dx dy], with (x0 y0) being a point of the line and (dx dy) a direction vector, BOX is the clipping box, given by its extreme coordinates: [xmin xmax ymin ymax]. The result is given as an edge, defined by the coordinates of its 2 extreme points: [x1 y1 x2 y2]. If line does not intersect the box, [NaN NaN NaN NaN] is returned. Function works also if LINE is a N-by-4 array, if BOX is a Nx4 array, or if both LINE and BOX are N-by-4 arrays. In these cases, EDGE is a N-by-4 array. Example line = [30 40 10 0]; box = [0 100 0 100]; res = clipLine(line, box) res = 0 40 100 40 See also lines2d, boxes2d, edges2d clipEdge, clipRay, clipLine3d
0001 function edge = clipLine(line, box, varargin) 0002 %CLIPLINE Clip a line with a box. 0003 % 0004 % EDGE = clipLine(LINE, BOX); 0005 % LINE is a straight line given as a 4 element row vector: [x0 y0 dx dy], 0006 % with (x0 y0) being a point of the line and (dx dy) a direction vector, 0007 % BOX is the clipping box, given by its extreme coordinates: 0008 % [xmin xmax ymin ymax]. 0009 % The result is given as an edge, defined by the coordinates of its 2 0010 % extreme points: [x1 y1 x2 y2]. 0011 % If line does not intersect the box, [NaN NaN NaN NaN] is returned. 0012 % 0013 % Function works also if LINE is a N-by-4 array, if BOX is a Nx4 array, 0014 % or if both LINE and BOX are N-by-4 arrays. In these cases, EDGE is a 0015 % N-by-4 array. 0016 % 0017 % 0018 % Example 0019 % line = [30 40 10 0]; 0020 % box = [0 100 0 100]; 0021 % res = clipLine(line, box) 0022 % res = 0023 % 0 40 100 40 0024 % 0025 % See also 0026 % lines2d, boxes2d, edges2d 0027 % clipEdge, clipRay, clipLine3d 0028 % 0029 0030 % ------ 0031 % Author: David Legland 0032 % E-mail: david.legland@inrae.fr 0033 % Created: 2007-08-27, using Matlab 7.4.0.287 (R2007a) 0034 % Copyright 2007-2024 INRA - Cepia Software Platform 0035 0036 % adjust size of two input arguments 0037 nLines = size(line, 1); 0038 nBoxes = size(box, 1); 0039 if nLines == 1 && nBoxes > 1 0040 line = repmat(line, nBoxes, 1); 0041 elseif nBoxes == 1 && nLines > 1 0042 box = repmat(box, nLines, 1); 0043 elseif nLines ~= nBoxes 0044 error('bad sizes for input'); 0045 end 0046 0047 % allocate memory 0048 nLines = size(line, 1); 0049 edge = zeros(nLines, 4); 0050 0051 % main loop on lines 0052 for i = 1:nLines 0053 % extract limits of the box 0054 xmin = box(i, 1); 0055 xmax = box(i, 2); 0056 ymin = box(i, 3); 0057 ymax = box(i, 4); 0058 0059 % use direction vector for box edges similar to direction vector of the 0060 % line in order to reduce computation errors 0061 delta = hypot(line(i,3), line(i,4)); 0062 0063 % compute intersection with each edge of the box 0064 px1 = intersectLines(line(i,:), [xmin ymin delta 0]); % lower edge 0065 px2 = intersectLines(line(i,:), [xmax ymin 0 delta]); % right edge 0066 py1 = intersectLines(line(i,:), [xmax ymax -delta 0]); % upper edge 0067 py2 = intersectLines(line(i,:), [xmin ymax 0 -delta]); % left edge 0068 0069 % remove undefined intersections (case of lines parallel to box edges) 0070 points = [px1 ; px2 ; py1 ; py2]; 0071 points = points(isfinite(points(:,1)), :); 0072 0073 % sort points according to their position on the line 0074 pos = linePosition(points, line(i,:)); 0075 [pos, inds] = sort(pos); %#ok<ASGLU> 0076 points = points(inds, :); 0077 0078 % create clipped edge by using the two points in the middle 0079 ind = size(points, 1)/2; 0080 inter1 = points(ind,:); 0081 inter2 = points(ind+1,:); 0082 edge(i, 1:4) = [inter1 inter2]; 0083 0084 % check that middle point of the edge is contained in the box 0085 midX = mean(edge(i, [1 3])); 0086 xOk = xmin <= midX && midX <= xmax; 0087 midY = mean(edge(i, [2 4])); 0088 yOk = ymin <= midY && midY <= ymax; 0089 0090 % if one of the bounding condition is not met, set edge to NaN 0091 if ~(xOk && yOk) 0092 edge (i,:) = NaN; 0093 end 0094 end