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