/[MITgcm]/MITgcm_contrib/gael/matlab_class/gcmfaces_misc/gcmfaces_quadmap.m
ViewVC logotype

Annotation of /MITgcm_contrib/gael/matlab_class/gcmfaces_misc/gcmfaces_quadmap.m

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Wed Apr 8 17:50:10 2015 UTC (10 years, 3 months ago) by gforget
Branch: MAIN
CVS Tags: checkpoint65x, checkpoint65r, checkpoint65p, checkpoint65q, checkpoint65v, checkpoint65w, checkpoint65t, checkpoint65u, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, HEAD
- gcmfaces_interp_coeffs.m : compute bilinear interpolation weights.
- gcmfaces_polygonangle.m : compute sum of polygon interior angles.
- gcmfaces_quadmap.m : compute bilinear interpolation coefficients.

1 gforget 1.1 function [ow]=gcmfaces_quadmap(px,py,ox,oy);
2     %[ow]=gcmfaces_quadmap(px,py,x,y);
3     %object: compute bilinear interpolation coefficients for x(i,:),y(i,:)
4     % in px(i,:),py(i,:) by remapping x(i,:),y(i,:) along with the
5     % px(i,:),py(i,:) quadrilateral to the 0-1,0-1 square.
6     %inputs: px,py are Mx4 matrices where each line specifies one quad
7     %(optional) ox,oy are MxP position matrices
8     %outputs: pw are the MxPx4 bilinear interpolation weights
9    
10     doDisplay=0;
11     if nargin==0;
12     %the following test case is based upon https://www.particleincell.com/2012/quad-interpolation/
13     %(see end of routine for alternatives)
14     px = [-1, 8, 13, -4];
15     py = [-1, 3, 11, 8];
16     ox=0; oy=6;
17     doDisplay=1;
18     end;
19    
20     if nargin==2; ox=[]; oy=[]; end;
21    
22     %solve linear problem for a,b vectors (knowing px,py)
23     % logical (l,m) to physical (x,y) mapping is then
24     % x=a(1)+a(2)*l+a(3)*m+a(2)*l*m;
25     % y=b(1)+b(2)*l+b(3)*m+b(2)*l*m;
26     % A=[1 0 0 0;1 1 0 0;1 1 1 1;1 0 1 0]; AI = inv(A);
27     % AI=[1 0 0 0;-1 1 0 0;-1 0 0 1; 1 -1 1 -1];
28     % a = AI*px';
29     % b = AI*py';
30     tmp1=px(:,1);
31     tmp2=-px(:,1)+px(:,2);
32     tmp3=-px(:,1)+px(:,4);
33     tmp4=px(:,1)-px(:,2)+px(:,3)-px(:,4);
34     a=[tmp1 tmp2 tmp3 tmp4];
35     %
36     tmp1=py(:,1);
37     tmp2=-py(:,1)+py(:,2);
38     tmp3=-py(:,1)+py(:,4);
39     tmp4=py(:,1)-py(:,2)+py(:,3)-py(:,4);
40     b=[tmp1 tmp2 tmp3 tmp4];
41    
42     %chose between the two mapping solutions dep. on sum of interior angles
43     [angsum]=gcmfaces_polygonangle(px,py);
44     sgn=NaN*px(:,1);
45     ii=find(abs(angsum-360)<1e-3); sgn(ii)=1;
46     ii=find(abs(angsum+360)<1e-3); sgn(ii)=-1;
47     ii=find(isnan(angsum));
48     if length(ii)>0;
49     warning('edge point was found');
50     keyboard;
51     end;
52    
53     %solve non-linear problem for pl,pm (knowing px,py,a,b)
54     % physical (x,y) to logical (l,m) mapping
55     %
56     % quadratic equation coeffs, aa*mm^2+bb*m+cc=0
57     if ~isempty(ox);
58     x=[px ox]; y=[py oy];
59     else;
60     x=px; y=py;
61     end;
62     a=reshape(a,[size(a,1) 1 size(a,2)]); a=repmat(a,[1 size(x,2) 1]);
63     b=reshape(b,[size(b,1) 1 size(b,2)]); b=repmat(b,[1 size(x,2) 1]);
64     sgn=repmat(sgn,[1 size(x,2)]);
65     %
66     aa = a(:,:,4).*b(:,:,3) - a(:,:,3).*b(:,:,4);
67     bb = a(:,:,4).*b(:,:,1) -a(:,:,1).*b(:,:,4) + a(:,:,2).*b(:,:,3) ...
68     - a(:,:,3).*b(:,:,2) + x.*b(:,:,4) - y.*a(:,:,4);
69     cc = a(:,:,2).*b(:,:,1) -a(:,:,1).*b(:,:,2) + x.*b(:,:,2) - y.*a(:,:,2);
70     %compute m = (-b+sqrt(b^2-4ac))/(2a)
71     det = sqrt(bb.*bb - 4.*aa.*cc);
72     pm = (-bb+sgn.*det)./(2.*aa);
73     %compute l by substitution in equation system
74     pl = (x-a(:,:,1)-a(:,:,3).*pm)./(a(:,:,2)+a(:,:,4).*pm);
75    
76     ow=[];
77     if ~isempty(ox);
78     tmp1=(1-pl(:,5:end)).*(1-pm(:,5:end));
79     tmp2=pl(:,5:end).*(1-pm(:,5:end));
80     tmp3=pl(:,5:end).*pm(:,5:end);
81     tmp4=(1-pl(:,5:end)).*pm(:,5:end);
82     ow=cat(3,tmp1,tmp2,tmp3,tmp4);
83     end;
84    
85     if doDisplay;
86     cols='brgm';
87     %
88     figureL;
89     %plot original quad and obs
90     subplot(1,2,1);
91     plot([px px(1)],[py py(1)],'k-','LineWidth',2); hold on;
92     for pp=1:4;
93     plot(px(pp),py(pp),[cols(pp) '.'],'MarkerSize',64);
94     end;
95     aa=axis; aa(1)=aa(1)-1; aa(2)=aa(2)+1; aa(3)=aa(3)-1; aa(4)=aa(4)+1; axis(aa);
96     grid on; plot(ox,oy,'k.','MarkerSize',64);
97     %
98     subplot(1,2,2);
99     plot([pl(1:4) pl(1)],[pm(1:4) pm(1)],'k-','LineWidth',2); hold on;
100     for pp=1:4; plot(pl(pp),pm(pp),[cols(pp) '.'],'MarkerSize',64); end;
101     aa=axis; aa(1)=aa(1)-1; aa(2)=aa(2)+1; aa(3)=aa(3)-1; aa(4)=aa(4)+1; axis(aa);
102     grid on; plot(pl(5:end),pm(5:end),'k.','MarkerSize',64);
103     end;
104    
105     %swap px and py:
106     % ppx=px; ppy=py;
107     % px=ppy; py=ppx;
108     %
109     %shift quad corners:
110     % nn=0;
111     % px=circshift(px,[0 nn]);
112     % py=circshift(py,[0 nn]);
113     %
114     %flip quad corners (see sum of interior angles):
115     % ppx=flipdim(px,2); ppy=flipdim(py,2);
116     % px=ppx; py=ppy;
117     %
118     %test cases for x,y locations:
119     % ox=0; oy=6;%inside point : sum(ang2)=+-360
120     % ox=(px(1)+px(2))/2; oy=(py(1)+py(2))/2;%edge limit case : sum(ang2)=+-180
121     % ox=(px(1)+px(4))/2; oy=(py(1)+py(4))/2;%edge limit case : sum(ang2)=-180
122     % ox=px(1); oy=py(1);%corner limit case : sum(ang2)=NaN
123     % ox=0; oy=12;%outside point : sum(ang2)=0

  ViewVC Help
Powered by ViewVC 1.1.22