You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
4.5 KiB
148 lines
4.5 KiB
function b = isPointOnEdge(point, edge, varargin)
|
|
%ISPOINTONEDGE Test if a point belongs to an edge.
|
|
%
|
|
% Usage
|
|
% B = isPointOnEdge(POINT, EDGE)
|
|
% B = isPointOnEdge(POINT, EDGE, TOL)
|
|
%
|
|
% Description
|
|
% B = isPointOnEdge(POINT, EDGE)
|
|
% with POINT being [xp yp], and EDGE being [x1 y1 x2 y2], returns TRUE if
|
|
% the point is located on the edge, and FALSE otherwise.
|
|
%
|
|
% B = isPointOnEdge(POINT, EDGE, TOL)
|
|
% Specify an optilonal tolerance value TOL. The tolerance is given as a
|
|
% fraction of the norm of the edge direction vector. Default is 1e-14.
|
|
%
|
|
% B = isPointOnEdge(POINTARRAY, EDGE)
|
|
% B = isPointOnEdge(POINT, EDGEARRAY)
|
|
% When one of the inputs has several rows, return the result of the test
|
|
% for each element of the array tested against the single parameter.
|
|
%
|
|
% B = isPointOnEdge(POINTARRAY, EDGEARRAY)
|
|
% When both POINTARRAY and EDGEARRAY have the same number of rows,
|
|
% returns a column vector with the same number of rows.
|
|
% When the number of rows are different and both greater than 1, returns
|
|
% a Np-by-Ne matrix of booleans, containing the result for each couple of
|
|
% point and edge.
|
|
%
|
|
% Examples
|
|
% % create a point array
|
|
% points = [10 10;15 10; 30 10];
|
|
% % create an edge array
|
|
% vertices = [10 10;20 10;20 20;10 20];
|
|
% edges = [vertices vertices([2:end 1], :)];
|
|
%
|
|
% % Test one point and one edge
|
|
% isPointOnEdge(points(1,:), edges(1,:))
|
|
% ans =
|
|
% 1
|
|
% isPointOnEdge(points(3,:), edges(1,:))
|
|
% ans =
|
|
% 0
|
|
%
|
|
% % Test one point and several edges
|
|
% isPointOnEdge(points(1,:), edges)'
|
|
% ans =
|
|
% 1 0 0 1
|
|
%
|
|
% % Test several points and one edge
|
|
% isPointOnEdge(points, edges(1,:))'
|
|
% ans =
|
|
% 1 1 0
|
|
%
|
|
% % Test N points and N edges
|
|
% isPointOnEdge(points, edges(1:3,:))'
|
|
% ans =
|
|
% 1 0 0
|
|
%
|
|
% % Test NP points and NE edges
|
|
% isPointOnEdge(points, edges)
|
|
% ans =
|
|
% 1 0 0 1
|
|
% 1 0 0 0
|
|
% 0 0 0 0
|
|
%
|
|
%
|
|
% See also
|
|
% edges2d, points2d, isPointOnLine
|
|
%
|
|
|
|
% ---------
|
|
% author : David Legland
|
|
% INRA - TPV URPOI - BIA IMASTE
|
|
% created the 31/10/2003.
|
|
%
|
|
|
|
% HISTORY
|
|
% 11/03/2004 change input format: edge is [x1 y1 x2 y2].
|
|
% 17/01/2005 if test N edges with N points, return N boolean.
|
|
% 21/01/2005 normalize test for colinearity, so enhance precision
|
|
% 22/05/2009 rename to isPointOnEdge, add psb to specify tolerance
|
|
% 26/01/2010 fix bug in precision computation
|
|
% 04/10/2010 fix a bug, and clean up code
|
|
% 28/10/2010 fix bug to have N results when input is N points and N
|
|
% edges, add support for arrays with different numbers of rows, and
|
|
% update doc.
|
|
% 2011-06-15 rewrites by using less memory, and avoiding repmat when psb
|
|
|
|
|
|
% extract computation tolerance
|
|
tol = 1e-14;
|
|
if ~isempty(varargin)
|
|
tol = varargin{1};
|
|
end
|
|
|
|
% number of edges and of points
|
|
nPoints = size(point, 1);
|
|
nEdges = size(edge, 1);
|
|
|
|
% adapt size of inputs if needed, and extract elements for computation
|
|
if nPoints == nEdges
|
|
% When the number of points and edges is the same, the one-to-one test
|
|
% will be computed, so there is no need to repeat matrices
|
|
dx = edge(:,3) - edge(:,1);
|
|
dy = edge(:,4) - edge(:,2);
|
|
lx = point(:,1) - edge(:,1);
|
|
ly = point(:,2) - edge(:,2);
|
|
|
|
elseif nPoints == 1
|
|
% one point, several edges
|
|
dx = edge(:, 3) - edge(:, 1);
|
|
dy = edge(:, 4) - edge(:, 2);
|
|
lx = point(ones(nEdges, 1), 1) - edge(:, 1);
|
|
ly = point(ones(nEdges, 1), 2) - edge(:, 2);
|
|
|
|
elseif nEdges == 1
|
|
% several points, one edge
|
|
dx = (edge(3) - edge(1)) * ones(nPoints, 1);
|
|
dy = (edge(4) - edge(2)) * ones(nPoints, 1);
|
|
lx = point(:, 1) - edge(1);
|
|
ly = point(:, 2) - edge(2);
|
|
|
|
else
|
|
% Np points and Ne edges:
|
|
% Create an array for each parameter, so that the result will be a
|
|
% Np-by-Ne matrix of booleans (requires more memory, and uses repmat)
|
|
|
|
x0 = repmat(edge(:, 1)', nPoints, 1);
|
|
y0 = repmat(edge(:, 2)', nPoints, 1);
|
|
dx = repmat(edge(:, 3)', nPoints, 1) - x0;
|
|
dy = repmat(edge(:, 4)', nPoints, 1) - y0;
|
|
|
|
lx = repmat(point(:, 1), 1, nEdges) - x0;
|
|
ly = repmat(point(:, 2), 1, nEdges) - y0;
|
|
end
|
|
|
|
% test if point is located on supporting line
|
|
b1 = abs(lx.*dy - ly.*dx) ./ (dx.*dx + dy.*dy) < tol;
|
|
|
|
% compute position of point with respect to edge bounds
|
|
% use different tests depending on line angle
|
|
ind = abs(dx) > abs(dy);
|
|
t = zeros(size(dx));
|
|
t(ind) = lx( ind) ./ dx( ind);
|
|
t(~ind) = ly(~ind) ./ dy(~ind);
|
|
|
|
% check if point is located between edge bounds
|
|
b = t >- tol & t-1 < tol & b1;
|
|
|