[1] | 1 | function [is,S] = iscross(x1,y1,x2,y2,tol)
|
---|
| 2 | %ISCROSS - Finds whether pairs of lines cross each other
|
---|
| 3 | %
|
---|
| 4 | % [IS,S] = ISCROSS(X1,Y1,X2,Y2) where arguments X1, Y1,
|
---|
| 5 | % X2, Y2 are all 2 by N matrices are coordinates of
|
---|
| 6 | % ends of the pairs of line segments.
|
---|
| 7 | % Returns vector IS (1 by N) consisting of ones if
|
---|
| 8 | % corresponding pairs cross each other, zeros if they
|
---|
| 9 | % don't and .5 if an end of one line segment lies on
|
---|
| 10 | % another segment.
|
---|
| 11 | % Also returns a matrix S (4 by N) with each row
|
---|
| 12 | % consisting of cross products (double areas of
|
---|
| 13 | % corresponding triangles) built on the following points:
|
---|
| 14 | % (X2(1,:),Y2(1,:)),(X1(1,:),Y1(1,:)),(X2(2,:),Y2(2,:)),
|
---|
| 15 | % (X2(1,:),Y2(1,:)),(X1(2,:),Y1(2,:)),(X2(2,:),Y2(2,:))
|
---|
| 16 | % (X1(1,:),Y1(1,:)),(X2(1,:),Y2(1,:)),(X1(2,:),Y1(2,:))
|
---|
| 17 | % (X1(1,:),Y1(1,:)),(X2(2,:),Y2(2,:)),(X1(2,:),Y1(2,:))
|
---|
| 18 | % The signs of these 4 areas can be used to determine
|
---|
| 19 | % whether these lines and their continuations cross each
|
---|
| 20 | % other.
|
---|
| 21 | % [IS,S] = ISCROSS(X1,Y1,X2,Y2,TOL) uses tolerance TOL
|
---|
| 22 | % for detecting the crossings (default is 0).
|
---|
| 23 | %
|
---|
| 24 | % Copyright (c) 1995 by Kirill K. Pankratov
|
---|
| 25 | % kirill@plume.mit.edu
|
---|
| 26 | % 08/14/94, 05/18/95, 08/25/95
|
---|
| 27 |
|
---|
| 28 | % Defaults and parameters .......................
|
---|
| 29 | tol_dflt = 0; % Tolerance for area calculation
|
---|
| 30 | is_chk = 1; % Check input arguments
|
---|
| 31 |
|
---|
| 32 | % Handle input ..................................
|
---|
| 33 | if nargin==0, help iscross, return, end
|
---|
| 34 | if nargin<4 % Check if all 4 entered
|
---|
| 35 | error(' Not enough input arguments')
|
---|
| 36 | end
|
---|
| 37 | if nargin<5, tol = tol_dflt; end
|
---|
| 38 | if tol < 0, is_chk = 0; tol = 0; end
|
---|
| 39 |
|
---|
| 40 | % Check the format of arguments .................
|
---|
| 41 | if is_chk
|
---|
| 42 | [x1,y1,x2,y2] = linechk(x1,y1,x2,y2);
|
---|
| 43 | end
|
---|
| 44 |
|
---|
| 45 | len = size(x1,2);
|
---|
| 46 | o2 = ones(2,1);
|
---|
| 47 |
|
---|
| 48 | % Find if the ranges of pairs of segments intersect
|
---|
| 49 | [isx,S,A] = interval(x1,x2);
|
---|
| 50 | scx = diff(A);
|
---|
| 51 | [isy,S,A] = interval(y1,y2);
|
---|
| 52 | scy = diff(A);
|
---|
| 53 | is = isx & isy;
|
---|
| 54 |
|
---|
| 55 | % If S values are not needed, extract only those pairs
|
---|
| 56 | % which have intersecting ranges ..............
|
---|
| 57 | if nargout < 2
|
---|
| 58 | isx = find(is); % Indices of pairs to be checked
|
---|
| 59 | % further
|
---|
| 60 | x1 = x1(:,isx);
|
---|
| 61 | x2 = x2(:,isx);
|
---|
| 62 | y1 = y1(:,isx);
|
---|
| 63 | y2 = y2(:,isx);
|
---|
| 64 | is = is(isx);
|
---|
| 65 | if isempty(is), is = zeros(1,len); return, end
|
---|
| 66 | scx = scx(isx);
|
---|
| 67 | scy = scy(isx);
|
---|
| 68 | end
|
---|
| 69 |
|
---|
| 70 | % Rescale by ranges ...........................
|
---|
| 71 | x1 = x1.*scx(o2,:);
|
---|
| 72 | x2 = x2.*scx(o2,:);
|
---|
| 73 | y1 = y1.*scy(o2,:);
|
---|
| 74 | y2 = y2.*scy(o2,:);
|
---|
| 75 |
|
---|
| 76 |
|
---|
| 77 | % Calculate areas .............................
|
---|
| 78 | S = zeros(4,length(scx));
|
---|
| 79 | S(1,:) = (x2(1,:)-x1(1,:)).*(y2(2,:)-y1(1,:));
|
---|
| 80 | S(1,:) = S(1,:)-(x2(2,:)-x1(1,:)).*(y2(1,:)-y1(1,:));
|
---|
| 81 |
|
---|
| 82 | S(2,:) = (x2(1,:)-x1(2,:)).*(y2(2,:)-y1(2,:));
|
---|
| 83 | S(2,:) = S(2,:)-(x2(2,:)-x1(2,:)).*(y2(1,:)-y1(2,:));
|
---|
| 84 |
|
---|
| 85 | S(3,:) = (x1(1,:)-x2(1,:)).*(y1(2,:)-y2(1,:));
|
---|
| 86 | S(3,:) = S(3,:)-(x1(2,:)-x2(1,:)).*(y1(1,:)-y2(1,:));
|
---|
| 87 |
|
---|
| 88 | S(4,:) = (x1(1,:)-x2(2,:)).*(y1(2,:)-y2(2,:));
|
---|
| 89 | S(4,:) = S(4,:)-(x1(2,:)-x2(2,:)).*(y1(1,:)-y2(2,:));
|
---|
| 90 |
|
---|
| 91 |
|
---|
| 92 | % Find if they cross each other ...............
|
---|
| 93 | is = (S(1,:).*S(2,:)<=0)&(S(3,:).*S(4,:)<=0);
|
---|
| 94 |
|
---|
| 95 |
|
---|
| 96 | % Find very close to intersection
|
---|
| 97 | isy = min(abs(S));
|
---|
| 98 | ii = find(isy<=tol & is);
|
---|
| 99 | is(ii) = .5*ones(size(ii));
|
---|
| 100 |
|
---|
| 101 | % Output
|
---|
| 102 | if nargout < 2
|
---|
| 103 | isy = zeros(1,len);
|
---|
| 104 | isy(isx) = is;
|
---|
| 105 | is = isy;
|
---|
| 106 |
|
---|
| 107 | else
|
---|
| 108 | isy = scx.*scy;
|
---|
| 109 | ii = find(~isy);
|
---|
| 110 | isy(ii) = ones(size(ii));
|
---|
| 111 | S = S./isy(ones(4,1),:);
|
---|
| 112 |
|
---|
| 113 | end
|
---|
| 114 |
|
---|