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@inra.fr 0033 % Created: 2007-08-27, using Matlab 7.4.0.287 (R2007a) 0034 % Copyright 2010 INRA - Cepia Software Platform. 0035 0036 % HISTORY 0037 % 2010-05-16 rewrite using intersectLines, add precision management 0038 % 2010-08-03 fix bugs (thanks to Reto Zingg) 0039 % 2010-08-06 remove management of EPS by checking edge midpoint (thanks 0040 % again to Reto Zingg) 0041 0042 % adjust size of two input arguments 0043 nLines = size(line, 1); 0044 nBoxes = size(box, 1); 0045 if nLines == 1 && nBoxes > 1 0046 line = repmat(line, nBoxes, 1); 0047 elseif nBoxes == 1 && nLines > 1 0048 box = repmat(box, nLines, 1); 0049 elseif nLines ~= nBoxes 0050 error('bad sizes for input'); 0051 end 0052 0053 % allocate memory 0054 nLines = size(line, 1); 0055 edge = zeros(nLines, 4); 0056 0057 % main loop on lines 0058 for i = 1:nLines 0059 % extract limits of the box 0060 xmin = box(i, 1); 0061 xmax = box(i, 2); 0062 ymin = box(i, 3); 0063 ymax = box(i, 4); 0064 0065 % use direction vector for box edges similar to direction vector of the 0066 % line in order to reduce computation errors 0067 delta = hypot(line(i,3), line(i,4)); 0068 0069 % compute intersection with each edge of the box 0070 px1 = intersectLines(line(i,:), [xmin ymin delta 0]); % lower edge 0071 px2 = intersectLines(line(i,:), [xmax ymin 0 delta]); % right edge 0072 py1 = intersectLines(line(i,:), [xmax ymax -delta 0]); % upper edge 0073 py2 = intersectLines(line(i,:), [xmin ymax 0 -delta]); % left edge 0074 0075 % remove undefined intersections (case of lines parallel to box edges) 0076 points = [px1 ; px2 ; py1 ; py2]; 0077 points = points(isfinite(points(:,1)), :); 0078 0079 % sort points according to their position on the line 0080 pos = linePosition(points, line(i,:)); 0081 [pos, inds] = sort(pos); %#ok<ASGLU> 0082 points = points(inds, :); 0083 0084 % create clipped edge by using the two points in the middle 0085 ind = size(points, 1)/2; 0086 inter1 = points(ind,:); 0087 inter2 = points(ind+1,:); 0088 edge(i, 1:4) = [inter1 inter2]; 0089 0090 % check that middle point of the edge is contained in the box 0091 midX = mean(edge(i, [1 3])); 0092 xOk = xmin <= midX && midX <= xmax; 0093 midY = mean(edge(i, [2 4])); 0094 yOk = ymin <= midY && midY <= ymax; 0095 0096 % if one of the bounding condition is not met, set edge to NaN 0097 if ~(xOk && yOk) 0098 edge (i,:) = NaN; 0099 end 0100 end