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@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

Generated on Thu 21-Nov-2024 11:30:22 by m2html © 2003-2022