Mercurial > hg > human-echolocation
view private/EDB1SorRgeo.m @ 18:2d5f50205527 jabuilder_int tip
Escape the trailing backslash as well
author | Chris Cannam |
---|---|
date | Tue, 30 Sep 2014 16:23:00 +0100 |
parents | 90220f7249fc |
children |
line wrap: on
line source
function outputfile = EDB1SorRgeo(eddatafile,outputfile,pointcoords,typeofcoords,difforder,nedgesubs) % EDB1SorRgeo - Calculates some source- or receiver-related geometrical parameters. % Calculates some source- or receiver-related geometrical parameters % based on corners,edges and planes in an eddata-file % and on a list of source/receiver coordinates. % The output is saved in a .mat-file. % % Input parameters: % eddatafile (optional) The .mat file with the corner,edge and plane data. % If it is not specified, a file opening window is presented. % outputfile (optional) The .mat file where the output data will be stored. % If it is not specified, an automatic file name is constructed % using the same filename stem as the eddatafile, but ending with '_srdata'. % pointcoords Matrix, [nrec,3], of source or receiver coordinates. % typeofcoords 'S' or 'R' - specifying if the point coordinates are sources % or receivers. This determines what the output data in the output % file will be called. % difforder The highest order of diffraction that will be calculated. % nedgesubs (optional) The number of subdivisions that each edge will be % subdivided into for visibility/obstruction tests. Default: 2 % NB! When nedgesubs = 2, the two end points will be checked. % SHOWTEXT (global) An integer value; if it is 4 or higher, then messages will be printed on the % screen during calculations. % Output parameters: % outputfile The name of the outputfile, generated either automatically or specified as % an input parameter. % % Data in the outputfile: % sources/receivers (renamed) copy of the input parameter 'pointcoords' % visplanesfroms/visplanesfromr Matrix, [nplanes,nsources]/[nplanes/nreceivers] % with integer values 0-5: % 0 means S/R behind a plane which is reflective or totabs % 1 means S/R is aligned with a plane, but outside it % 2 means S/R is in front of a plane which is reflective % 3 means S/R is in front of a plane which is totabs % 4 means S/R is inside a plane which is reflective % 5 means S/R is inside a plane which is totabs % vispartedgesfroms/vispartedgesfromr Matrix, [nedges,nsources]/[nedges/nreceivers] % with integer values 0-2^nedgesubs-1 indicating % part-visibility of the edge. % soutsidemodel/routsidemodel List, [nsources,1]/[nreceivers,1], with values % 1 or 0 indicating whether the S/R is outside (1) % the model or not (0). % NB! Only simple tests are done, so an S/R could still % be outside the model even if the value here is 0. % % NB! The text on the screeen, and in the code refers to 'R' or 'receivers' but it should be S or R. % % Uses the functions EDB1strpend, EDB1infrontofplane, EDB1poinpla, % EDB1getedgepoints, EDB1checkobstr_pointtoedge % % ---------------------------------------------------------------------------------------------- % This file is part of the Edge Diffraction Toolbox by Peter Svensson. % % The Edge Diffraction Toolbox is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by the Free Software % Foundation, either version 3 of the License, or (at your option) any later version. % % The Edge Diffraction Toolbox is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS % FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. % % You should have received a copy of the GNU General Public License along with the % Edge Diffraction Toolbox. If not, see <http://www.gnu.org/licenses/>. % ---------------------------------------------------------------------------------------------- % Peter Svensson (svensson@iet.ntnu.no) 060601 % % outputfile = EDB1SorRgeo(eddatafile,outputfile,pointcoords,typeofcoords,difforder,nedgesubs); global SHOWTEXT geomacc = 1e-10; if nargin < 6 nedgesubs = 2; if nargin < 4 error('ERROR: The input parameter pointcoords must be specified') end else if isempty(nedgesubs), nedgesubs = 2; end end typeofcoords = lower(typeofcoords(1)); if typeofcoords~='r' & typeofcoords~='s' error(['ERROR: The input parameter typeofcoords must have the value S or R']) end %--------------------------------------------------------------- % If no eddatafile was specified, present a file opening window if exist('eddatafile')~=1 eddatafile = ''; end if isempty(eddatafile) [eddatafile,filepath] = uigetfile('*.mat','Please select the eddatafile'); [filepath,temp1,temp2] = fileparts(filepath); if ~isstr(eddatafile) return end [temp1,filestem,temp2] = fileparts(eddatafile); eddatafile = [[filepath,filesep],filestem,'.mat']; else [filepath,filestem,fileext] = fileparts(eddatafile); eddatafile = [[filepath,filesep],filestem,'.mat']; end %--------------------------------------------------------------- % If no output file was specified, construct an automatic file name if exist('outputfile')~=1 outputfile = ''; end if isempty(outputfile) filestem = EDB1strpend(filestem,'_eddata'); outputfile = [[filepath,filesep],filestem,'_rdata.mat']; end %--------------------------------------------------------------- eval(['load ',eddatafile]) clear cornerinfrontofplane [ncorners,slask] = size(corners); [nplanes,slask] = size(planecorners); maxncornersperplane = double(max(ncornersperplanevec)); [nedges,slask] = size(edgecorners); [nreceivers,slask] = size(pointcoords); [n1,n2] = size(canplaneobstruct); if n2>1 canplaneobstruct = canplaneobstruct.'; end totalmodelmin = min(minvals); totalmodelmax = max(maxvals); zerosvecE1 = zeros(nedges,1); zerosvec1P = zeros(1,nplanes); onesvec1R = uint8(ones(1,nreceivers)); onesvec1ES = ones(1,nedgesubs); onesvecP1 = ones(nplanes,1); onesvec1Max = ones(1,maxncornersperplane); %################################################################## %################################################################## %################################################################## % % PLANE RELATED PARAMETERS % %################################################################## activeplanelist = find(reflfactors ~= 0); totabsplanelist = find(reflfactors == 0); ntotabsplanes = length(totabsplanelist); nthinplanes = length(find(planeisthin)); if SHOWTEXT >= 3 if lower(typeofcoords(1)) == 'r' disp(' Checking visible planes from R') else disp(' Checking visible planes from S') end end %-------------------------------------------------------------- % % visplanesfromr [nplanes,nrec] uint8 % % 0 means S/R behind a plane which is reflective or totabs % 1 means S/R is aligned with a plane % 2 means S/R is in front of a plane which is reflective % 3 means S/R is in front of a plane which is totabs % 4 means S/R is inside a plane which is reflective % 5 means S/R is inside a plane which is totabs % % We can call EDB1infrontofplane with a single call by extracting receiver % numbers and plane numbers for the [nplanes,nsources] matrix. % % EDB1infrontofplane returns -1 for behind, 0 for in-plane with and 1 for in % front of so if we add the value 1 we get close to the final value we want % to have. Another modification is to give totabs planes the value 3 % instead of 2. A last modification is to find which S/R are inside the % plane. iv = [1:nplanes*nreceivers].'; if nreceivers < 256 colnumb = uint8(ceil(iv/nplanes)); % This is the receiver number elseif nreceivers < 65536 colnumb = uint16(ceil(iv/nplanes)); % This is the receiver number else colnumb = uint32(ceil(iv/nplanes)); % This is the receiver number end if nplanes < 256 rownumb = uint8(iv - (double(colnumb)-1)*nplanes); % This is the plane number elseif nplanes < 65536 rownumb = uint16(iv - (double(colnumb)-1)*nplanes); % This is the plane number else rownumb = uint32(iv - (double(colnumb)-1)*nplanes); % This is the plane number end clear iv visplanesfromr = EDB1infrontofplane(pointcoords(colnumb,:),planenvecs(rownumb,:),corners(planecorners(rownumb,1),:),corners(planecorners(rownumb,2),:)) + 1; clear rownumb colnumb if ntotabsplanes > 0 colvec = [0:nreceivers-1]*nplanes; iv = uint32(totabsplanelist(:,onesvec1R) + colvec(ones(ntotabsplanes,1),:)); visplanesfromr(iv) = uint8(visplanesfromr(iv) + (visplanesfromr(iv)==2)); clear iv colvec visplanesfromr = uint8(visplanesfromr); end % For all the planes that the S/R are aligned with % check if the S/R is inside or outside the plane. % % We can call EDB1poinpla with a single call by extracting S/R coordinates % (=colnumb) and planenumbers (=rownumb). ivec_visR1 = find(visplanesfromr==1); if ~isempty(ivec_visR1) if nreceivers < 256 colnumb = uint8(ceil(ivec_visR1/nplanes)); % This is the receiver number elseif nreceivers < 65536 colnumb = uint16(ceil(ivec_visR1/nplanes)); % This is the receiver number else colnumb = uint32(ceil(ivec_visR1/nplanes)); % This is the receiver number end if nplanes < 256 rownumb = uint8(ivec_visR1 - (double(colnumb)-1)*nplanes); % This is the plane number elseif nplanes < 65536 rownumb = uint16(ivec_visR1 - (double(colnumb)-1)*nplanes); % This is the plane number else rownumb = uint32(ivec_visR1 - (double(colnumb)-1)*nplanes); % This is the plane number end hitvec = find(EDB1poinpla(pointcoords(colnumb,:),rownumb,minvals,maxvals,planecorners,corners,ncornersperplanevec,planenvecs)); if ~isempty(hitvec) visplanesfromr(ivec_visR1(hitvec)) = uint8(ones(size(hitvec))*4); if ntotabsplanes > 0 insidetotabsplane = (reflfactors(rownumb(hitvec))==0); ivec2 = find(insidetotabsplane); if ~isempty(ivec2) visplanesfromr(ivec_visR1(hitvec(ivec2))) = uint8(ones(size(hitvec(ivec2)))*5); end end ivec_visR1(hitvec) = []; if nthinplanes > 0 insidethinplane = planeisthin(rownumb(hitvec)); ivec2 = find(insidethinplane); if ~isempty(ivec2) recinthinplane = colnumb(hitvec(ivec2)); thinplanenumber = rownumb(hitvec(ivec2)); error(['ERROR: R number ',int2str(double(recinthinplane(:).')),' has been placed exactly on the thin plane ',int2str(double(thinplanenumber(:).')),... ' so it is undefined which side of the plane the R is. Move the R a short distance away']) end end end end visplanesfromr = reshape(visplanesfromr,nplanes,nreceivers); %-------------------------------------------------------------- % % routsidemodel (0 or 1, size [1,nrec]) % % We make a simple check: if the S/R is outside the big cube defined by all % the planes, and we have an interior problem, then S/R must be outside the % model. routsidemodel = uint8(zeros(1,nreceivers)); if int_or_ext_model == 'i' ivec = find(pointcoords(:,1)<totalmodelmin(1) | pointcoords(:,2)<totalmodelmin(2) | pointcoords(:,3)<totalmodelmin(3) | ... pointcoords(:,1)>totalmodelmax(1) | pointcoords(:,2)>totalmodelmax(2) | pointcoords(:,3)>totalmodelmax(3)); if ~isempty(ivec) routsidemodel(ivec) = ones(size(ivec)); end routsidemodel = uint8(routsidemodel); % If we have a convex model, then the obstruction check is turned off % so we must check here if the source/receiver is inside. if sum(closwedangvec<pi) == 0 nplanesvisible = sum(sign(visplanesfromr)); ivec = find(nplanesvisible < nplanes); if ~isempty(ivec) routsidemodel(ivec) = ones(size(ivec)); end end end %################################################################## %################################################################## %################################################################## % % EDGE RELATED PARAMETERS % %################################################################## if difforder == 0 if typeofcoords=='r' vispartedgesfromr = []; receivers = pointcoords; Varlist = [' visplanesfromr receivers ']; Varlist = [Varlist,' vispartedgesfromr routsidemodel ']; eval(['save ',outputfile,Varlist]) return else vispartedgesfroms = []; sources = pointcoords; visplanesfroms = visplanesfromr; soutsidemodel = routsidemodel; Varlist = [' visplanesfroms sources ']; Varlist = [Varlist,' vispartedgesfroms soutsidemodel ']; eval(['save ',outputfile,Varlist]) return end end closwedlargerthanpi = closwedangvec>pi; closwedsmallerthanpi = closwedangvec<pi; if SHOWTEXT >= 3 if lower(typeofcoords(1)) == 'r' disp(' Checking which edges are seen from R') else disp(' Checking which edges are seen from S') end end nbigcombs = nplanes*nreceivers; %-------------------------------------------------------------- % % visedgesfromr [nedges,nrec] uint8 % % 6 Edge belongs to a plane which is aligned with R and thin and % rigid (but R is not inside the plane) % 5 Edge belongs to a plane which is aligned with R and not thin % % These can be derived from the cases where visplanesfromr = 1 visedgesfromr = uint8(ones(nedges,nreceivers)); if ~isempty(ivec_visR1) if nreceivers < 256 colnumb = uint8(ceil(ivec_visR1/nplanes)); % This is the receiver number elseif nreceivers < 65536 colnumb = uint16(ceil(ivec_visR1/nplanes)); % This is the receiver number else colnumb = uint32(ceil(ivec_visR1/nplanes)); % This is the receiver number end if nplanes < 256 rownumb = uint8(ivec_visR1 - (double(colnumb)-1)*nplanes); % This is the plane number elseif nplanes < 65536 rownumb = uint16(ivec_visR1 - (double(colnumb)-1)*nplanes); % This is the plane number else rownumb = uint32(ivec_visR1 - (double(colnumb)-1)*nplanes); % This is the plane number end % Divide these lists into two categories: thin planes and non-thin % planes. iv2 = find(planeisthin(rownumb)); if ~isempty(iv2) colnumb_thin = colnumb(iv2); rownumb_thin = rownumb(iv2); colnumb(iv2) = []; rownumb(iv2) = []; else colnumb_thin = []; rownumb_thin = []; end if ~isempty(colnumb) % Select all the edges that are connected to these planes if nedges < 256 edgeselection = uint8(edgesatplane(rownumb,1:maxncornersperplane)); elseif nedges < 65536 edgeselection = uint16(edgesatplane(rownumb,1:maxncornersperplane)); else edgeselection = uint32(edgesatplane(rownumb,1:maxncornersperplane)); end if length(rownumb) > 1 maxcols = sum(sign(sum(double(edgeselection)))); else maxcols = sum(sign(double(edgeselection))); end edgeselection = edgeselection(:,1:maxcols); colnumb = colnumb(:,ones(1,maxcols)); indexvec = uint32(double(edgeselection) + (double(colnumb)-1)*nedges); indexvec(find(edgeselection==0)) = []; visedgesfromr(indexvec) = uint8(5*ones(size(indexvec))); end if ~isempty(colnumb_thin) % Select all the edges that are connected to these planes if nedges < 256 edgeselection = uint8(edgesatplane(rownumb_thin,1:maxncornersperplane)); elseif nedges < 65536 edgeselection = uint16(edgesatplane(rownumb_thin,1:maxncornersperplane)); else edgeselection = uint32(edgesatplane(rownumb_thin,1:maxncornersperplane)); end if length(rownumb_thin) > 1 maxcols = sum(sign(sum(edgeselection))); else maxcols = sum(sign(edgeselection)); end edgeselection = edgeselection(:,1:maxcols); colnumb_thin = colnumb_thin(:,ones(1,maxcols)); indexvec = uint32(double(edgeselection) + (double(colnumb_thin)-1)*nedges); indexvec(find(edgeselection==0)) = []; visedgesfromr(indexvec) = uint8(6*ones(size(indexvec))); end end % 4 Edge belongs to a plane which the S/R is inside % and the plane is totabs % 3 Edge belongs to a plane which the S/R is inside % and the plane has indents % 2 Edge belongs to a plane which the S/R is inside % and the plane has no indents % % These can be derived from the cases where visplanesfromr = 4 and 5 ivec = find(visplanesfromr==5); if ~isempty(ivec) colnumb = ceil(ivec/nplanes); % This is the receiver number if nreceivers < 256 colnumb = uint8(ceil(ivec/nplanes)); % This is the receiver number elseif nreceivers < 65536 colnumb = uint16(ceil(ivec/nplanes)); % This is the receiver number else colnumb = uint32(ceil(ivec/nplanes)); % This is the receiver number end rownumb = ivec - (double(colnumb)-1)*nplanes; % This is the plane number if nplanes < 256 rownumb = uint8(ivec - (double(colnumb)-1)*nplanes); % This is the plane number elseif nplanes < 65536 rownumb = uint16(ivec - (double(colnumb)-1)*nplanes); % This is the plane number else rownumb = uint32(ivec - (double(colnumb)-1)*nplanes); % This is the plane number end clear ivec % Select all the edges that are connected to these planes if nedges < 256 edgeselection = uint8(edgesatplane(rownumb,1:maxncornersperplane)); elseif nedges < 65536 edgeselection = uint16(edgesatplane(rownumb,1:maxncornersperplane)); else edgeselection = uint32(edgesatplane(rownumb,1:maxncornersperplane)); end if length(rownumb) > 1 maxcols = sum(sign(sum(edgeselection))); else maxcols = sum(sign(edgeselection)); end edgeselection = edgeselection(:,1:maxcols); colnumb = colnumb(:,ones(1,maxcols)); indexvec = uint32(double(edgeselection) + (double(colnumb)-1)*nedges); indexvec(find(edgeselection==0)) = []; visedgesfromr(indexvec) = uint8(4*ones(size(indexvec))); end ivec = find(visplanesfromr==4); if ~isempty(ivec) if nreceivers < 256 colnumb = uint8(ceil(ivec/nplanes)); % This is the receiver number elseif nreceivers < 65536 colnumb = uint16(ceil(ivec/nplanes)); % This is the receiver number else colnumb = uint32(ceil(ivec/nplanes)); % This is the receiver number end if nplanes < 256 rownumb = uint8(ivec - (double(colnumb)-1)*nplanes); % This is the plane number elseif nplanes < 65536 rownumb = uint16(ivec - (double(colnumb)-1)*nplanes); % This is the plane number else rownumb = uint32(ivec - (double(colnumb)-1)*nplanes); % This is the plane number end clear ivec % Divide these lists into two categories: planes with indents and % planes without iv2 = find(planehasindents(rownumb)); if ~isempty(iv2) colnumb_ind = colnumb(iv2); rownumb_ind = rownumb(iv2); colnumb(iv2) = []; rownumb(iv2) = []; else colnumb_ind = []; rownumb_ind = []; end if ~isempty(colnumb) % Select all the edges that are connected to these planes % edgeselection = edgesatplane(rownumb,1:maxncornersperplane); if nedges < 256 edgeselection = uint8(edgesatplane(rownumb,1:maxncornersperplane)); elseif nedges < 65536 edgeselection = uint16(edgesatplane(rownumb,1:maxncornersperplane)); else edgeselection = uint32(edgesatplane(rownumb,1:maxncornersperplane)); end if length(rownumb) > 1 maxcols = sum(sign(sum(double(edgeselection)))); else maxcols = sum(sign(double(edgeselection))); end edgeselection = edgeselection(:,1:maxcols); colnumb = colnumb(:,ones(1,maxcols)); indexvec = uint32(double(edgeselection) + (double(colnumb)-1)*nedges); indexvec(find(edgeselection==0)) = []; visedgesfromr(indexvec) = uint8(2*ones(size(indexvec))); end if ~isempty(colnumb_ind) % Select all the edges that are connected to these planes edgeselection = edgesatplane(rownumb,1:maxncornersperplane); if length(rownumb) > 1 maxcols = sum(sign(sum(edgeselection))); else maxcols = sum(sign(edgeselection)); end edgeselection = edgeselection(:,1:maxcols); colnumb_ind = colnumb_ind(:,ones(1,maxcols)); indexvec = uint32(edgeselection + (colnumb_ind-1)*nedges); indexvec(find(edgeselection==0)) = []; visedgesfromr(indexvec) = uint8(3*ones(size(indexvec))); end end % 0 R can never see the edge because it is behind the edge-planes. % NB! If the closwedang > pi, then it is enough if R is behind % one plane. If the closwedang <= pi, then R must be behind both % planes in order not to see the edge. ivec = find(visplanesfromr==0); if ~isempty(ivec) if nreceivers < 256 colnumb = uint8(ceil(ivec/nplanes)); % This is the receiver number elseif nreceivers < 65536 colnumb = uint16(ceil(ivec/nplanes)); % This is the receiver number else colnumb = uint32(ceil(ivec/nplanes)); % This is the receiver number end if nplanes < 256 rownumb = uint8(ivec - (double(colnumb)-1)*nplanes); % This is the plane number elseif nplanes < 65536 rownumb = uint16(ivec - (double(colnumb)-1)*nplanes); % This is the plane number else rownumb = uint32(ivec - (double(colnumb)-1)*nplanes); % This is the plane number end clear ivec % Select all the edges that are connected to these planes if nedges < 256 edgeselection = uint8(edgesatplane(rownumb,1:maxncornersperplane)); elseif nedges < 65536 edgeselection = uint16(edgesatplane(rownumb,1:maxncornersperplane)); else edgeselection = uint32(edgesatplane(rownumb,1:maxncornersperplane)); end if length(rownumb) > 1 maxcols = sum(sign(sum(double(edgeselection)))); else maxcols = sum(sign(double(edgeselection))); end edgeselection = edgeselection(:,1:maxcols); colnumb = colnumb(:,ones(1,maxcols)); ntot2 = length(rownumb)*maxcols; indexvec = uint32(double(edgeselection) + (double(colnumb)-1)*nedges); indexvec = reshape(indexvec,ntot2,1); edgeselection = reshape(edgeselection,ntot2,1); iv2 = find(edgeselection==0); indexvec(iv2) = []; edgeselection(iv2) = []; ntot2 = ntot2 - length(iv2); [indexvec,sortvec] = sort(indexvec); edgeselection = edgeselection(sortvec); clear sortvec markdoubles = [edgeselection(1:ntot2-1)==edgeselection(2:ntot2)]; markdoubles = sign([markdoubles;0] + [0;markdoubles]); iv2 = uint32(find(markdoubles)); clear markdoubles visedgesfromr(indexvec(iv2)) = 0; indexvec(iv2) = []; edgeselection(iv2) = []; iv2 = uint32(find(closwedangvec(edgeselection)<=pi)); indexvec(iv2) = []; visedgesfromr(indexvec) = 0; clear indexvec end clear edgeselection iv2 %################################################################## % % Mask out edges that should be switched off mask = (ones(nedges,1)); mask(offedges) = mask(offedges) & 0; visedgesfromr = uint8(double(visedgesfromr).*mask(:,onesvec1R)); clear onesvec1R %################################################################## %################################################################## %################################################################## % % CHECK OBSTRUCTION OF R-TO-EDGE PATHS % % vispartedgesfromr 0-2^nedgesubs-1, [nedges,nrec] % telling which segments of an edge that % are visible % % A. If visedgesfromr = 6 then check aligned-plane obstructions % If OK, set visedgesfromr = 1 (check ordinary obst.) % If not OK, set visedgesfromr = 0 % % B. If visedgesfromr = 3 then check within-plane obstructions % Set visedgesfromr = 0 and % set vispartedgesfromr = 0-full % % C. If visedgesfromr = 2 then % Set visedgesfromr = 0 and % set vispartedgesfromr = Full % % D. If visedgesfromr = 1 then check ordinary obstructions % Set visedgesfromr = 0 and % set vispartedgesfromr = 0-full edgedividervec = [0:nedgesubs-1].'; weightvec = 2.^edgedividervec; maxvisibilityval = 2^nedgesubs-1; if SHOWTEXT >= 3 if lower(typeofcoords(1)) == 'r' disp([' Checking for obstructing planes between R and edges']) else disp([' Checking for obstructing planes between S and edges']) end end if nedgesubs<8 vispartedgesfromr = uint8(zeros(size(visedgesfromr))); elseif nedgesubs<16 vispartedgesfromr = uint16(zeros(size(visedgesfromr))); else vispartedgesfromr = uint32(zeros(size(visedgesfromr))); end %################################################################## % % The receiver related quantities iv = uint32(find(visedgesfromr>=5)); if ~isempty(iv) disp(' We check aligned-edge obstructions') % All edges must be checked vs all other edges? % Make subdivision of edges. If a line from R to edge segments % pass through a plane that is constructed by an edge and perpendicular to % the studied plane, then that edge is obstructing. combnumbers = double(iv); recnumbers = ceil(combnumbers/nedges); if nedges < 256 edgenumbers = uint8(combnumbers - (recnumbers-1)*nedges); elseif nedges < 65536 edgenumbers = uint16(combnumbers - (recnumbers-1)*nedges); else edgenumbers = uint32(combnumbers - (recnumbers-1)*nedges); end nedgesperreceiver = histc(recnumbers,[1:nreceivers]); iv1 = find(nedgesperreceiver >= 2); if isempty(iv1) visedgesfromr(iv) = ones(size(iv)); else disp([' Several edges are in-plane with the receiver']) disp([' If possible, move the receivers a little bit']) [uniquerecs,exampleindex] = unique(recnumbers); for jj = 1:length(uniquerecs) problemrec = uniquerecs(jj); iv1 = find(recnumbers==problemrec); disp(' ') disp(' Receiver with coordinates') disp([' ',num2str(pointcoords(problemrec,1)),' ',num2str(pointcoords(problemrec,2)),' ',num2str(pointcoords(problemrec,3))]) disp(' is aligned with edges') numvec = [int2str(edgenumbers(iv1(1))),' ',int2str(edgenumbers(iv1(2)))]; for kk = 3:length(iv1) numvec = [numvec,' ', int2str(edgenumbers(iv1(kk)))]; end disp([' ',numvec]) end error('ERROR: Obstruction check of aligned-edges not implemented yet!') end end iv = uint32(find(visedgesfromr==3)); if ~isempty(iv) disp(' We check within-plane obstructions') visedgesfromr(iv) = zeros(size(iv)); error('ERROR: Obstruction check of within-same-plane-edges not implemented yet!') end iv = uint32(find(visedgesfromr==2)); if ~isempty(iv) disp(' Edge fully visible') visedgesfromr(iv) = zeros(size(iv)); vispartedgesfromr(iv) = maxvisibilityval*ones(size(iv)); end iv = uint32(find(visedgesfromr==4)); if ~isempty(iv) disp(' Edge in totabs plane') visedgesfromr(iv) = zeros(size(iv)); vispartedgesfromr(iv) = zeros(size(iv)); end % Below is the main part of the obstruction test. In the matrix % visedgesfromr, values 1 indicate that edge-receiver combos should be % tested. visedgesfromr has the size [nedges,nreceivers]. iv = uint32(find(visedgesfromr==1)); if ~isempty(iv) visedgesfromr(iv) = zeros(size(iv)); combnumbers = double(iv); clear iv % combnumbers is a list of the "combined" values for edge and receiver. if nreceivers < 256 recnumbers = uint8(ceil(combnumbers/nedges)); elseif nreceivers < 65536 recnumbers = uint16(ceil(combnumbers/nedges)); else recnumbers = uint32(ceil(combnumbers/nedges)); end if nedges < 256 edgenumbers = uint8(combnumbers - (double(recnumbers)-1)*nedges); elseif nedges < 65536 edgenumbers = uint16(combnumbers - (double(recnumbers)-1)*nedges); else edgenumbers = uint32(combnumbers - (double(recnumbers)-1)*nedges); end combnumbers = uint32(combnumbers); ncombs = length(recnumbers); ntot = ncombs*nplanes; % Mark, in a big matrix, which planes can at all obstruct. % Planes that can obstruct must be seen by the receiver or the edge but % not both - because then they would be on the same side! % NB! Also totabs planes can obstruct. % The big matrix will have nedges*nplanes rows. The vector planenumb % will have values such as [1 1 1 1... 2 2 2 2 .....] iv = [1:ncombs*nplanes].'; % Plane number is given by the col no. if nplanes < 256 planenumb = uint8(ceil(iv/ncombs)); elseif nplanes < 65536 planenumb = uint16(ceil(iv/ncombs)); else planenumb = uint32(ceil(iv/ncombs)); end indexvec = planenumb; % The rownumber will simply have values [1 2 3... N 1 2 3 ... N 1 2 3 % ... N] where N is the number of combinations. if ncombs < 256 rownumber = uint8(iv - (double(planenumb)-1)*ncombs); elseif ncombs < 65536 rownumber = uint16(iv - (double(planenumb)-1)*ncombs); else rownumber = uint32(iv - (double(planenumb)-1)*ncombs); end clear planenumb iv % The peak in the memory need might be after the two indexvec lines % below % indexvec2 will point to the right location in an [nplanes,nedges] matrix % indexvec will point to the right location in an [nplanes,nreceivers] matrix indexvec2 = uint32(double(indexvec) + (double(edgenumbers(rownumber))-1)*nplanes); indexvec = uint32(double(indexvec) + (double(recnumbers(rownumber))-1)*nplanes); clear rownumber % The big matrix checkplane, size [1,ncombs*nplanes], will contain the % value 1 if a plane should be checked for obstruction. % The index order of checkplane is: % [Plane1&comb1 Plane1&comb2 Plane1&comb3 ...] where comb1 is the first % combination of receiver and edge in the recnumbers & edgenumbers % lists. % Only planes that are seen by the S/R *or* the edge, but not both % should be checked for obstruction!! % We remove combinations where: % ... S/R is aligned with a plane (visplanesfromr == 1) % ... edge belongs to a plane or is aligned with a plane (edgeseesplane <0) % ... S/R is behind and edge is behind a plane (visplanesfromr == 0 & edgeseesplane == 0) % ... S/R is in front of and edge is in front of a plane ( (visplanesfromr == 2 | visplanesfromr == 3) & edgeseesplane == 1) % % Comment 050116 (PS): % We would actually need a matrix called planeseesedge. Here we use % edgeseesplane instead, and it is not completely clear if that works % fine. checkplane = (visplanesfromr(indexvec)~=1) & (edgeseesplane(indexvec2)>=0) & not(visplanesfromr(indexvec)==0 & edgeseesplane(indexvec2)==0 ) & not( (visplanesfromr(indexvec)==2 | visplanesfromr(indexvec)==3) & edgeseesplane(indexvec2)==1 ); if size(checkplane,1) > size(checkplane,2) checkplane = checkplane.'; end if size(checkplane,1) == 1 | size(checkplane,2) == 1 checkplane = reshape(checkplane,ncombs,nplanes); end clear indexvec indexvec2 edgeseesplane % If there are some R-edge combos that have no planes to check % obstruction for, we can mark those combos ("combsnottocheck") as fully visible. % % The remaining ones ("combstocheck") still need to be checked. [n1,n2] = size(checkplane); if n1 < 65536 combstocheck = uint16(find( sum(checkplane.') )); elseif n1 < 4e9 combstocheck = uint32(find( sum(checkplane.') )); end combsnottocheck = [1:ncombs]; combsnottocheck(combstocheck) = []; if ~isempty(combsnottocheck) vispartedgesfromr(combnumbers(combsnottocheck)) = maxvisibilityval*ones(size(combsnottocheck)); end if ~isempty(combstocheck) checkplane = checkplane(combstocheck,:); recnumbers = recnumbers(combstocheck); maxrec = max(recnumbers); if maxrec < 256 recnumbers = uint8(recnumbers); elseif maxrec < 65536 recnumbers = uint16(recnumbers); else recnumbers = uint32(recnumbers); end edgenumbers = edgenumbers(combstocheck); combnumbers = combnumbers(combstocheck); ncombs = length(combstocheck); % Now, checkplane is a matrix of size [ncombs,nplanes] where each % row corresponds to one path (from one receiver to one edge) that needs % an obstruction check. For that row, checkplane has the value 1 for % each plane that needs to be checked. % % Expand all edges into their edge segment/subdivision % We treat all the little edge subdivisions as separate edges nposs = ncombs*nedgesubs; expandedrecnumbers = recnumbers(:,onesvec1ES); clear recnumbers expandedrecnumbers = reshape(expandedrecnumbers.',nposs,1); expandedcombnumbers = combnumbers(:,onesvec1ES); clear combnumbers expandedcombnumbers = reshape(expandedcombnumbers.',nposs,1); if nposs < 65536 okcombs = uint16(zeros(size(expandedrecnumbers))); elseif nposs < 4e9 okcombs = uint32(zeros(size(expandedrecnumbers))); end [tocoords,expandededgeweightlist,expandededgenumbers] = EDB1getedgepoints(edgestartcoords(edgenumbers,:),... edgeendcoords(edgenumbers,:),edgelengthvec(edgenumbers,:),nedgesubs,1); expandededgenumbers = edgenumbers(expandededgenumbers); [nonobstructedpaths,nobstructions,edgehits,cornerhits] = EDB1checkobstr_pointtoedge(pointcoords,expandedrecnumbers,tocoords,reshape(repmat(checkplane.',[nedgesubs,1]),nplanes,nposs).',planeseesplane,... planeeqs,planenvecs,minvals,maxvals,planecorners,corners,ncornersperplanevec,rearsideplane); clear checkplane planeseesplane expandedcombnumbers = expandedcombnumbers(nonobstructedpaths); expandededgeweightlist = expandededgeweightlist(nonobstructedpaths); expandedrecnumbers = expandedrecnumbers(nonobstructedpaths); expandededgenumbers = expandededgenumbers(nonobstructedpaths); % Pack all non-obstructed edge segments together and add their weights together test = [double(expandedrecnumbers) double(expandededgenumbers)]; ncombs = length(expandedrecnumbers); dtest = diff([0;prod( double(test(1:ncombs-1,:)==test(2:ncombs,:)).' ).']); ivremove = find(dtest==1); while ~isempty(ivremove) expandededgeweightlist(ivremove+1) = double(expandededgeweightlist(ivremove+1)) + double(expandededgeweightlist(ivremove)); expandededgeweightlist(ivremove) = []; expandedrecnumbers(ivremove) = []; expandededgenumbers(ivremove,:) = []; test = [double(expandedrecnumbers) double(expandededgenumbers)]; ncombs = length(expandedrecnumbers); dtest = diff([0;prod( double(test(1:ncombs-1,:)==test(2:ncombs,:)).' ).']); ivremove = find(dtest==1); end indexvec = uint32(nedges*(double(expandedrecnumbers)-1)+double(expandededgenumbers)); vispartedgesfromr(indexvec) = expandededgeweightlist; clear indexvec end end %---------------------------------------------------------------------------- % % SAVE THE VARIABLES % %-------------------------------------------------------------------------- if typeofcoords=='r' receivers = pointcoords; Varlist = [' visplanesfromr receivers ']; Varlist = [Varlist,' vispartedgesfromr routsidemodel ']; eval(['save ',outputfile,Varlist]) return else sources = pointcoords; visplanesfroms = visplanesfromr; vispartedgesfroms = vispartedgesfromr; soutsidemodel = routsidemodel; Varlist = [' visplanesfroms sources ']; Varlist = [Varlist,' vispartedgesfroms soutsidemodel ']; eval(['save ',outputfile,Varlist]) return end