0001 function loops = polygonLoops(poly, varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 tol = 1e-14;
0029
0030
0031 while length(varargin) > 1
0032 pname = varargin{1};
0033 if ~ischar(pname)
0034 error('Expect optional arguments as name-value pairs');
0035 end
0036
0037 if strcmpi(pname, 'tolerance')
0038 tol = varargin{2};
0039 else
0040 error(['Unknown parameter name: ' pname]);
0041 end
0042 varargin(1:2) = [];
0043 end
0044
0045
0046
0047
0048
0049 [inters, pos1, pos2] = polygonSelfIntersections(poly, 'tolerance', tol);
0050
0051
0052 if isempty(inters)
0053 loops = {poly};
0054 return;
0055 end
0056
0057
0058 loops = cell(0, 1);
0059
0060
0061 [positions, order] = sortrows([pos1 pos2 ; pos2 pos1]);
0062 inters = [inters ; inters];
0063 inters = inters(order, :);
0064
0065
0066
0067
0068
0069 pos0 = 0;
0070 loop = polygonSubcurve(poly, pos0, positions(1, 1));
0071 loop(end, :) = inters(1,:);
0072 vertex = inters(1,:);
0073
0074
0075 pos = positions(1, 2);
0076 positions(1, :) = [];
0077 inters(1,:) = [];
0078
0079 while true
0080
0081 ind = find(positions(:,1) > pos, 1, 'first');
0082
0083
0084 if isempty(ind)
0085 break;
0086 end
0087
0088
0089 portion = polygonSubcurve(poly, pos, positions(ind, 1));
0090
0091
0092 portion(1, :) = vertex;
0093 vertex = inters(ind, :);
0094 portion(end, :) = vertex;
0095
0096
0097 loop = [loop; portion];
0098
0099
0100 pos = positions(ind, 2);
0101
0102
0103 positions(ind, :) = [];
0104 inters(ind,:) = [];
0105 end
0106
0107
0108 loop = [loop ; polygonSubcurve(poly, pos, pos0)];
0109
0110
0111 loop(sum(loop(1:end-1,:) == loop(2:end,:) ,2)==2, :) = [];
0112 if sum(diff(loop([1 end], :)) == 0) == 2
0113 loop(end, :) = [];
0114 end
0115
0116
0117 loops{1} = loop;
0118
0119
0120
0121
0122 Nl = 1;
0123 while ~isempty(positions)
0124
0125
0126 loop = [];
0127 pos0 = positions(1, 2);
0128 pos = positions(1, 2);
0129 vertex = inters(1,:);
0130
0131 while true
0132
0133 ind = find(positions(:,1) > pos, 1, 'first');
0134
0135
0136 portion = polygonSubcurve(poly, pos, positions(ind, 1));
0137
0138
0139 portion(1, :) = vertex;
0140 vertex = inters(ind, :);
0141 portion(end, :) = vertex;
0142
0143
0144 loop = [loop ; portion];
0145
0146
0147 pos = positions(ind, 2);
0148
0149
0150 positions(ind, :) = [];
0151 inters(ind,:) = [];
0152
0153
0154 if pos == pos0
0155 break;
0156 end
0157 end
0158
0159
0160 loop(sum(loop(1:end-1,:) == loop(2:end,:) ,2)==2, :) = [];
0161 if sum(diff(loop([1 end], :))==0) == 2
0162 loop(end, :) = [];
0163 end
0164
0165
0166 Nl = Nl + 1;
0167 loops{Nl} = loop;
0168 end