Home > matGeom > geom2d > clipLine.m

clipLine

PURPOSE ^

CLIPLINE Clip a line with a box.

SYNOPSIS ^

function edge = clipLine(line, box, varargin)

DESCRIPTION ^

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

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

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

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