function [didIntersect, Cellintel] = RatboolEls(Element1,Element2,InorUn) % didIntersect is 0 if no intersection % didIntersect is 1 if nontrivial intersection % didIntersect is 2 if Element1 is inside Element2 % didIntersect is 3 if Element2 is inside Element1 %% Important constants defining size of Elements if did_intersect_box(computeBdBxRat(Element1),computeBdBxRat(Element2)) d=2; Element1W=Element1((d+1):(d+1):end,:); Element1C=Element1; Element1C((d+1):(d+1):end,:)=[]; for i=1:size(Element1W) Element1C(((i-1)*d+1):(i*d),:)=Element1C(((i-1)*d+1):(i*d),:)./Element1W(i,:); end Element2W=Element2((d+1):(d+1):end,:); Element2C=Element2; Element2C((d+1):(d+1):end,:)=[]; for i=1:size(Element2W) Element2C(((i-1)*d+1):(i*d),:)=Element2C(((i-1)*d+1):(i*d),:)./Element2W(i,:); end numc1=size(Element1C,1)/d; numc2=size(Element2C,1)/d; n=size(Element1,2); n2=size(Element2,2); intlist=zeros(0,5); % To store all of the intersections numinters=0; for i=1:numc1 for j=1:numc2 if did_intersect_box(Element1C(((d*(i-1))+1):((d*i)),:),Element2C(((d*(j-1))+1):((d*j)),:)) [~,~,temps,tempt]=Ratbern_inter_recurse_v2(Element1((((d+1)*(i-1))+1):(((d+1)*i)),:),Element2((((d+1)*(j-1))+1):(((d+1)*j)),:),[0 1], [0 1], 10^(-31)); % temps = unique(temps) if ~isempty(temps) vals=dCR_eval(Element1(((d+1)*(i-1)+1):((d+1)*(i-1)+d+1),:),temps(:,2)); % scatter(vals(:,1),vals(:,2),800,"r."); intlist((numinters+1):(numinters+length(temps(:,2))),1:4)=[temps(:,2), tempt(:,2), repmat(i,length(temps(:,2)),1), repmat(j,length(temps(:,2)),1)]; numinters=length(temps(:,2))+numinters; end end end end inclusion=0; % if isempty(intlist) [~,IA]=uniquetol(intlist(:,1),1e-14); intlist=intlist(IA,:); numinters=size(intlist,1); % end constintlist=intlist; % This is a list of all of the intersections addedintel=0; % This is the number of segments on the current region of intersections % These variables define which intersection to start at startint=1; if numinters>0 didIntersect=1; startelem=orient(... Element1((((d+1)*(intlist(startint,3)-1))+1):(((d+1)*intlist(startint,3))),:),... Element2((((d+1)*(intlist(startint,4)-1))+1):(((d+1)*intlist(startint,4))),:),... intlist(startint,1),... intlist(startint,2)... ); if InorUn startelem=~startelem; end startc=intlist(startint,startelem+3); starts=intlist(startint,startelem+1); % if startelem Element1( % These variables change during the walking process element = startelem; % This is the current polygon k=startc; % This is the number of the current curve temps=starts; % This is the time on the current curve startnuminters=numinters;% This is the total number of intersections between the two polygons intlist(:,5)=0; % None of the intersections have been used yet ll=1; % This is the number of regions that are part of the intersection addingcurves=true; % This is a boolean to conrol whether curves are % being added or we are travelling between regions %% This is the directional walking method % Keep going until we have gone through all of the intersections and returned to an intersection while numinters>0 % Find the intersections that haven't been used yet along the % current curve in order of increasing parameter value [~,idxsort1]=sort(intlist(:,1+element)); intlist=intlist(idxsort1,:); finder=find((~intlist(:,5) & intlist(:,3+element)==k & intlist(:,1+element)>temps),1); % If there are intersections, use them to add the next curve if ~isempty(finder) if ~element Splitter1=Element1((((d+1)*(k-1))+1):(((d+1)*k)),:); else Splitter1=Element2((((d+1)*(k-1))+1):(((d+1)*k)),:); end splitpoints=[temps,intlist(finder,1+element)]; splitpoints(2)=((splitpoints(2)-splitpoints(1))./(1-splitpoints(1))); for i=1:2 Splitter1(((d+1)*(i-1)+1):((d+1)*(i+1)),:)=dC_split(Splitter1(((d+1)*(i-1)+1):((d+1)*(i)),:),splitpoints(i)); end % Check to see if we've made it back to the starting intersection of % this region. If so, then store the region, stay on the same curve, % and get to the next intersection point. if intlist(finder,3+~element)==startc && ~element==startelem && numinters0; % Orientation is found using scaled signed distance from point to line equation: % D* = (x2-x1)(y-y1) + (y2-y1)(x-x1) end function [oC1,oC2,otbds,osbds] = bern_inter_recurse_v2(C1,C2,itbds,isbds,tol) % Given two bernstein polynomials, finds their intersection points. % Input parameters % C1: This is a d by n matrix consisting of control points of all possible % intersection polynomials coming from the first original polynomial % C1: This is a d by n matrix consisting of control points of all possible % intersection polynomials coming from the first original polynomial % Output parameters % C1: A d by n matrix consisting of control points for the bernstein % polynomial of degree n of dimension d % C2: A d by n matrix consisting of control points for th % p: A list of numerically calculated intersection points (empty if none) [d,n]=size(C1); % Number of polynomials to check % w=0; % h=0; % figure('Units','normalized','Position', [.5+(w) .6+h .0675 .125]) % if w<(.5-.0675) % w=w+.0675; % else % w=.5; % h=h-.125; % end % hold off % plot_bern_poly(C1(1,:),C1(2,:),.01); % plot_bern_poly(C2(1,:),C2(2,:),.01); % drawnow % d1=point_to_line(padarray(C1,1,0,'post')',padarray(C1(:,1),1,0,'post')',padarray(C1(:,end),1,0,'post')') d1=sum(point_to_line(C1',C1(:,1)',C1(:,end)')); d2=sum(point_to_line(C2',C2(:,1)',C2(:,end)')); p1_scale=max(abs(C1(:,end)-C1(:,1))); p2_scale=max(abs(C2(:,end)-C2(:,1))); % p1_scale=1; % p2_scale=1; otbds=zeros(0,2); osbds=zeros(0,2); oC1=zeros(0,size(C1,2)); oC2=zeros(0,size(C1,2)); if (d1>tol*(p1_scale))||(d2>tol*(p2_scale)) c1s=dC_split(C1,.5); c2s=dC_split(C2,.5); intersect_bool_mat=[did_intersect_box(c1s(1:d,:),c2s(1:d,:)) did_intersect_box(c1s((d+1):(2*d),:),c2s(1:d,:)); did_intersect_box(c1s(1:d,:),c2s((d+1):(2*d),:)) did_intersect_box(c1s((d+1):(2*d),:),c2s((d+1):(2*d),:));]; if intersect_bool_mat(1,1) [temp1,temp2,tempt,temps]=bern_inter_recurse_v2(c1s(1:d,:),c2s(1:d,:), ... [itbds(1),mean(itbds)],[isbds(1),mean(isbds)],tol); oC1=[oC1;temp1]; oC2=[oC2;temp2]; otbds=[otbds;tempt]; osbds=[osbds;temps]; end if intersect_bool_mat(1,2) [temp1,temp2,tempt,temps]=bern_inter_recurse_v2(c1s((d+1):(2*d),:),c2s(1:d,:), ... [mean(itbds),itbds(2)],[isbds(1),mean(isbds)],tol); oC1=[oC1;temp1]; oC2=[oC2;temp2]; otbds=[otbds;tempt]; osbds=[osbds;temps]; end if intersect_bool_mat(2,1) [temp1,temp2,tempt,temps]=bern_inter_recurse_v2(c1s(1:d,:),c2s((d+1):(2*d),:), ... [itbds(1),mean(itbds)],[mean(isbds),isbds(2)],tol); oC1=[oC1;temp1]; oC2=[oC2;temp2]; otbds=[otbds;tempt]; osbds=[osbds;temps]; end if intersect_bool_mat(2,2) [temp1,temp2,tempt,temps]=bern_inter_recurse_v2(c1s((d+1):(2*d),:),c2s((d+1):(2*d),:), ... [mean(itbds),itbds(2)],[mean(isbds),isbds(2)],tol); oC1=[oC1;temp1]; oC2=[oC2;temp2]; otbds=[otbds;tempt]; osbds=[osbds;temps]; end else p=newton_intersect(C1(:,1),C1(:,end),C2(:,end),C2(:,1)); if all(p<(1) & p>0) && all(~isnan(p)) oC1=C1; oC2=C2; otbds=[1 itbds(1)+(itbds(2)-itbds(1))*p(1)]; osbds=[1 isbds(1)+(isbds(2)-isbds(1))*p(2)]; end end end function d = point_to_line(pt, v1, v2) % pt should be nx3 % v1 and v2 are vertices on the line (each 1x3) % d is a nx1 vector with the orthogonal distances v1 = repmat(v1,size(pt,1),1); v2 = repmat(v2,size(pt,1),1); a = v1 - v2; b = pt - v2; % d = sqrt(sum(cross(a,b,2).^2,2)) ./ sqrt(sum(a.^2,2)); d = sum(cross2d(a,b).^2,2) ./ sum(a.^2,2); end function cr = cross2d(a,b) cr = a(:,1).*b(:,2)-a(:,2).*b(:,1); end function t = newton_intersect(a,d,c,b) % Gives parameter values of intersection of two lines: a+(d-a)t and % c+(b-c)s for 0