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