Skip to content

Commit 2801970

Browse files
authored
Merge pull request #117 from fastalgorithms/patch-chunkerinterior
Patch chunkerinterior
2 parents e7b3bfc + 4050b3d commit 2801970

File tree

5 files changed

+72
-36
lines changed

5 files changed

+72
-36
lines changed

chunkie/@chunker/centroids.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
k = chnkr.k;
77
nch = chnkr.nch;
88
dim = chnkr.dim;
9-
[~,w] = lege.exps(k);
9+
w = chnkr.wstor;
1010
ww = repmat( (w(:)).',dim,1);
1111
wall = reshape(ww(:)*ones(1,nch),dim,k,nch);
1212

1313
ctrs = reshape(sum( (chnkr.r).*wall , 2),dim,nch)/2;
1414

15-
end
15+
end

chunkie/@chunker/flagnear_rectangle.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
% logical array. If the (i,j) entry is non zero then pts(:,i) is close
55
% to chunk j in chnkr.
66
%
7-
% Syntax: flag = flagnear(chnkr,pts,opts)
7+
% Syntax: flag = flagnear_rectangle(chnkr,pts,opts)
88
%
99
% Input:
1010
% chnkr - chunker object describing curve

chunkie/chunkerinterior.m

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -124,27 +124,16 @@
124124
useflam_final = useflam;
125125
end
126126

127-
% use bernstein ellipses and rectangles to flag problematic points
128-
%
129127

130128
eps_local = 1e-3;
131-
132-
rho = 1.2;
133-
optsflag = []; optsflag.rho = rho; optsflag.occ = 5;
134-
if grid
135-
flag = flagnear_rectangle_grid(chnkr,x,y,optsflag);
136-
else
137-
flag = flagnear_rectangle(chnkr,pts,optsflag);
138-
end
139-
129+
rho = 1.6;
140130
npoly = chnkr.k;
141131
nlegnew = chnk.ellipse_oversample(rho,npoly,eps_local);
142132
nlegnew = max(nlegnew,chnkr.k);
143133

144134
[chnkr2] = upsample(chnkr,nlegnew);
145135

146136

147-
148137
icont = false;
149138
if usefmm_final
150139
try
@@ -185,14 +174,23 @@
185174
% for points where the integral might be inaccurate:
186175
% find close boundary point and check normal direction
187176

177+
iffy = min(abs(vals1+1),abs(vals1)) > 1e-2;
178+
179+
ipt = find(iffy(:));
180+
pts_iffy = pts(:,iffy);
181+
182+
optsflag = []; optsflag.rho = rho; optsflag.occ = 5;
183+
flag = flagnear_rectangle(chnkr,pts_iffy,opts);
184+
flag2 = flagnear_rectangle(chnkr,chnkr.r(:,:),opts);
185+
flag2 = ((flag2.'*kron(speye(chnkr.nch),ones(chnkr.k,1))) > 1).';
188186

189-
nnzpt = sum(flag~=0,2);
190-
ipt = find(nnzpt);
187+
flag = (flag2*flag.').';
191188

192-
npts = numel(pts)/2;
193-
distmins = inf(npts,1);
194-
dss = zeros(2,npts);
195-
rss = zeros(2,npts);
189+
npts_iffy = numel(pts_iffy)/2;
190+
assert(npts_iffy == length(ipt));
191+
distmins = inf(npts_iffy,1);
192+
dss = zeros(2,npts_iffy);
193+
rss = zeros(2,npts_iffy);
196194

197195
k = chnkr.k;
198196
[t,~,u] = lege.exps(k);
@@ -204,7 +202,8 @@
204202
dval = chnkr.d(:,:,i);
205203
nval = chnkr.n(:,:,i);
206204
[ji] = find(flag(:,i));
207-
ptsi = pts(:,ji);
205+
206+
ptsi = pts_iffy(:,ji);
208207
nptsi = size(ptsi,2);
209208
dist2all = reshape(sum( abs(reshape(ptsi,2,1,nptsi) ...
210209
- reshape(rval,2,k,1)).^2, 1),k,nptsi);
@@ -223,9 +222,9 @@
223222
diffs = rval(:,ipti)-ptsi;
224223
dots = sum(ptsn.*diffs,1);
225224

226-
jsus = abs(dots) < 2e-1*sqrt(dist2all);
225+
jsus = abs(dots) < 0.9*sqrt(dist2all);
227226
jii = ji(jsus);
228-
[~,rs,ds,~,dist2s] = chnk.chunk_nearparam(rval,pts(:,jii),[],t,u);
227+
[~,rs,ds,~,dist2s] = chnk.chunk_nearparam(rval,pts_iffy(:,jii),[],t,u);
229228
for j = 1:length(jii)
230229
jj = jii(j);
231230
if dist2s(j) < distmins(jj)
@@ -237,6 +236,8 @@
237236
end
238237

239238
for i = 1:length(ipt)
240-
jj = ipt(i);
241-
in(jj) = (rss(:,jj)-pts(:,jj)).'*[dss(2,jj);-dss(1,jj)] > 0;
239+
if distmins(i) < inf
240+
jj = ipt(i);
241+
in(jj) = (rss(:,i)-pts_iffy(:,i)).'*[dss(2,i);-dss(1,i)] > 0;
242+
end
242243
end

devtools/test/chunkerinteriorTest.m

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
% inside a domain or not
33
%
44

5-
clearvars; close all;
65
seed = 8675309;
76
rng(seed);
8-
addpaths_loc();
97

108
doadap = false;
119

@@ -89,4 +87,46 @@
8987
targs = starfish(ttarg).*scal;
9088

9189
in = chunkerinterior(chnkr,targs,struct('axissym',true));
92-
assert(all(in(:) == (scal(:) <= 1)));
90+
assert(all(in(:) == (scal(:) <= 1)));
91+
92+
%%
93+
94+
% a stress test. previously this triggered a bug for the old version which
95+
% used the normals to determine interior points
96+
97+
amp = 0.25;
98+
scale = .3;
99+
100+
ctr = [-2;-1.6];
101+
chnkr_int= chunkerfunc(@(t) starfish(t,3,amp,ctr,pi/4,scale));
102+
chnkr_int = sort(reverse(chnkr_int));
103+
104+
a = max(vecnorm(chnkr_int.r(:,:)))*1.01;
105+
chnkr_ext = chunkerfunc(@(t) [a*cos(t(:).'); a*sin(t(:).')]);
106+
chnkr = merge([chnkr_ext,chnkr_int]);
107+
108+
% return
109+
110+
L = max(abs(chnkr.r),[],"all");
111+
x1 = linspace(-L,L,100);
112+
[xx,yy] = meshgrid(x1,x1);
113+
targs = [xx(:).'; yy(:).'];
114+
xv=[chnkr_ext.r(1,:),nan,chnkr_int.r(1,:)];
115+
yv=[chnkr_ext.r(2,:),nan,chnkr_int.r(2,:)];
116+
%tic; in0 = inpolygon(xx(:),yy(:),xv,yv); toc
117+
tt = atan2(yy-ctr(2),xx-ctr(1)) + 2*pi;
118+
st = starfish(tt(:),3,amp,[0;0],pi/4,scale);
119+
ss2 = reshape(st(1,:).^2 + st(2,:).^2,size(xx));
120+
in0 = and((xx.^2+yy.^2)<a^2, ...
121+
(xx-ctr(1)).^2 + (yy-ctr(2)).^2 > ss2);
122+
in0 = in0(:);
123+
tic; in = chunkerinterior(chnkr,{x1,x1}); toc
124+
125+
% clf
126+
% plot(chnkr,'g-o')
127+
% hold on
128+
% scatter(xx(in(:)),yy(in(:)),'bo')
129+
% scatter(xx(~in(:)),yy(~in(:)),'rx')
130+
131+
assert(all(in0 == in));
132+

devtools/test/mixedbcTest.m

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,9 @@
9393
targets = zeros(2,length(xxtarg(:)));
9494
targets(1,:) = xxtarg(:); targets(2,:) = yytarg(:);
9595

96-
start = tic; in1 = chunkerinterior(merge(cgrph.echnks(edir)),{xtarg,ytarg});
97-
in2 = chunkerinterior(reverse(merge(cgrph.echnks(eneu))),{xtarg,ytarg});
98-
t1 = toc(start);
99-
in = in1 & ~in2;
100-
out = ~in;
101-
10296
ids= chunkgraphinregion(cgrph,{xtarg,ytarg});
103-
nnz(in-(ids==2))
97+
in = ids == 2;
98+
in2 = ids == 3;
10499

105100
fprintf('%5.2e s : time to find points in domain\n',t1)
106101

0 commit comments

Comments
 (0)