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.
193 lines
6.1 KiB
193 lines
6.1 KiB
function new_edges = splitEdges( edges )
|
|
% splitEdges: split line segments (=edges) into smaller ones based on
|
|
% intersections between them
|
|
%
|
|
% isIntersect.m, intersectEdges.m, isPointOnEdge.m are used.
|
|
% isIntersect.m - algorithm (www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/)
|
|
% intersectEdges.m, isPointOnEdge.m are written by David Legland (https://github.com/mattools/matGeom)
|
|
%
|
|
% input:
|
|
% edges - N-by-4 array, storing N line segments.
|
|
% Each line segment (edges(i,:)) is given by coordinates
|
|
% of two points : [x1 y1 x2 y2].
|
|
%
|
|
% example:
|
|
%
|
|
% edges = [ 0 0 5 0; 2 0 4 0; 1 5 1 -3; 1 5 3 -2 ];
|
|
% new_edges = splitEdges( edges );
|
|
% drawEdge( new_edges, 'linewidth', 1.5 );
|
|
%
|
|
% Written by Jiexian Ma at SUNY Binghamton (mjx0799@gmail.com)
|
|
%
|
|
|
|
% find intersection between edges
|
|
pi_cell = edgexedge( edges );
|
|
% sort intersections (pi_cell) on individual edge
|
|
pi_cell = sortPoint( pi_cell );
|
|
|
|
% sort 2 node in each edge
|
|
edges = sortNode( edges );
|
|
% break up each edge by intersections on them
|
|
new_edges = breakEdges( edges, pi_cell );
|
|
|
|
end
|
|
|
|
|
|
function pi_cell = edgexedge( edges )
|
|
% find intersection between edges
|
|
% pi_cell - cell column vector, record intersections
|
|
% pi_cell{i} - n-by-2 array, save x y data of intersections on edges(i,:)
|
|
|
|
% point of intersection between edges
|
|
pi_cell = cell( size(edges,1), 1 ); % cell array
|
|
% pi_cell{i} - n by 2 array, save x y data
|
|
|
|
TOLERANCE = 10^(-10); % for ismembertol
|
|
|
|
% find intersection between edges
|
|
for i = 1: size(edges,1)-1
|
|
for j = i+1: size(edges,1)
|
|
|
|
e1 = edges( i, : );
|
|
e2 = edges( j, : );
|
|
|
|
if ~ isIntersect( e1, e2 )
|
|
% case of no intersect by isIntersect.m
|
|
xyi = [NaN NaN];
|
|
else
|
|
% find intersection between two edges using
|
|
% intersectEdges.m
|
|
% 0-2 points
|
|
xyi = intersectEdges( e1, e2, TOLERANCE );
|
|
end
|
|
|
|
node1 = e1( [1 2] );
|
|
node2 = e1( [3 4] );
|
|
node3 = e2( [1 2] );
|
|
node4 = e2( [3 4] );
|
|
|
|
if all( isnan(xyi) ) % case of no intersect: xyi = [NaN NaN]
|
|
% do nothing
|
|
else % case of intersect
|
|
|
|
if all( isinf(xyi) ) % case of intersect but colinear edges
|
|
% xyi = [inf inf]
|
|
% find out intersects (colinear case)
|
|
% using isPointOnEdge.m
|
|
xytemp = [];
|
|
if isPointOnEdge( node1, e2, TOLERANCE )
|
|
xytemp = [ xytemp; node1];
|
|
end
|
|
if isPointOnEdge( node2, e2, TOLERANCE )
|
|
xytemp = [ xytemp; node2];
|
|
end
|
|
if isPointOnEdge( node3, e1, TOLERANCE )
|
|
xytemp = [ xytemp; node3];
|
|
end
|
|
if isPointOnEdge( node4, e1, TOLERANCE )
|
|
xytemp = [ xytemp; node4];
|
|
end
|
|
xyi = xytemp;
|
|
end
|
|
|
|
% exclude the original nodes, and save xyi
|
|
% compare xyi with the nodes of edge1
|
|
ind1 = ~ismembertol( xyi, [node1;node2], TOLERANCE,'ByRows',true);
|
|
% store non-node xyi
|
|
pi_cell{i} = [ pi_cell{i}; xyi( ind1, : ) ];
|
|
|
|
% compare xyi with the nodes of edge2
|
|
ind2 = ~ismembertol( xyi, [node3;node4], TOLERANCE,'ByRows',true);
|
|
% store non-node xyi
|
|
pi_cell{j} = [ pi_cell{j}; xyi( ind2, : ) ];
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
|
|
function pi_cell = sortPoint( pi_cell )
|
|
% sort intersections in pi_cell
|
|
|
|
for i = 1: length( pi_cell )
|
|
temp = unique( pi_cell{i}, 'rows' );
|
|
|
|
% sort intersections
|
|
if size( temp, 1 ) > 1
|
|
if temp(1,1) ~= temp(2,1)
|
|
% sort points according to x
|
|
[ ~, ind ] = sort( temp(:,1) );
|
|
temp = temp( ind, : );
|
|
else
|
|
% sort points according to y
|
|
[ ~, ind ] = sort( temp(:,2) );
|
|
temp = temp( ind, : );
|
|
end
|
|
end
|
|
|
|
pi_cell{i} = temp;
|
|
end
|
|
end
|
|
|
|
function edges = sortNode( edges )
|
|
% sort 2 node in each edge
|
|
|
|
for i = 1: size( edges, 1 )
|
|
temp = [ edges(i,1:2); edges(i,3:4)];
|
|
|
|
% sort
|
|
if temp(1,1) ~= temp(2,1)
|
|
% sort points according to x
|
|
[ ~, ind ] = sort( temp(:,1) );
|
|
temp = temp( ind, : );
|
|
else
|
|
% sort points according to y
|
|
[ ~, ind ] = sort( temp(:,2) );
|
|
temp = temp( ind, : );
|
|
end
|
|
|
|
edges( i, : ) = [ temp(1,:) temp(2,:) ];
|
|
end
|
|
end
|
|
|
|
function new_edges = breakEdges( edges, pi_cell )
|
|
% break up edges
|
|
|
|
% total number of edges after breaking up
|
|
sum_len = 0;
|
|
for i = 1: length( pi_cell )
|
|
sum_len = sum_len + size( pi_cell{i}, 1 ) + 1;
|
|
end
|
|
|
|
new_edges = zeros( sum_len, 4 );
|
|
k = 1; % index for new_edges
|
|
|
|
for i = 1: length( pi_cell )
|
|
if size( pi_cell{i}, 1 ) == 0
|
|
% no intection on this edge
|
|
new_edges(k,:) = edges(i,:); % do nothing
|
|
k = k + 1;
|
|
|
|
elseif size( pi_cell{i}, 1 ) == 1
|
|
% 1 intection on this edge
|
|
new_edges(k,:) = [ edges(i,1:2) pi_cell{i}(1,1:2) ];
|
|
k = k + 1;
|
|
|
|
new_edges(k,:) = [ pi_cell{i}(end,1:2) edges(i,3:4) ];
|
|
k = k + 1;
|
|
|
|
elseif size( pi_cell{i}, 1 ) > 1
|
|
% >1 intection on this edge
|
|
for j = 1: size( pi_cell{i}, 1 ) - 1
|
|
new_edges(k,:) = [ pi_cell{i}(j,1:2) pi_cell{i}(j+1,1:2) ];
|
|
k = k + 1;
|
|
end
|
|
|
|
new_edges(k,:) = [ edges(i,1:2) pi_cell{i}(1,1:2) ];
|
|
k = k + 1;
|
|
|
|
new_edges(k,:) = [ pi_cell{i}(end,1:2) edges(i,3:4) ];
|
|
k = k + 1;
|
|
end
|
|
end
|
|
end
|