@Thanatomatic, I just had finished testing the result. It works, almost. Some problem in the mismatching face, it isn’t continuous like the other one which is not acceptable, and two, it doesn’t match. I will try with the other approach to see if it gets anywhere. Continuous output is more important on the mismatching face. In the case of no solution to this problem, I think this still can be a new filter for gmic.
Test Code
$ sp cat +rep_powertweak 55%,60%
rep_powertweak:
f "begin(
const ww=w-1;
const hh=h-1;
const cx=ww/2;
const cy=hh/2;
const pc=.5;
const px=.5+$1*.5;
const py=1-(.5+$2*.5);
const pc_px=ww*px;
const pc_py=hh*py;
const inc_x1=(pc_py-cy)/pc_px;
const inc_x2=(pc_py-cy)/(ww-pc_px);
const inc_y1=(pc_px-cx)/pc_py;
const inc_y2=(pc_px-cx)/(hh-pc_py);
xcross(a,b)=a[0]*b[1]-a[1]*b[0];
invBilinear(p,a,b,c,d)=(
e = b-a;
f = d-a;
g = a-b+c-d;
h = p-a;
k2 = xcross( g, f );
k1 = xcross( e, f ) + xcross( h, g );
k0 = xcross( h, e );
if(abs(k2)<0.001,
[(h[0]*k1+f[0]*k0)/(e[0]*k1-g[0]*k0),-k0/k1];
,
m = k1*k1 - 4.0*k0*k2;
if(m<0.0,[-1,-1],
m = sqrt( m );
ik2 = 0.5/k2;
v = (-k1 - m)*ik2;
u = (h[0] - f[0]*v)/(e[0] + g[0]*v);
v = (-k1 + m)*ik2;
u = (h[0] - f[0]*v)/(e[0] + g[0]*v);
[u,v];
);
);
);
);
xp=x/w;
yp=y/h;
side_y=x<pc_px?(y+inc_x1*(pc_px-x))>pc_py:(y+inc_x2*(x-pc_px))>pc_py;
side_x=y<pc_py?(x+inc_y1*(pc_py-y))>pc_px:(x+inc_y2*(y-pc_py))>pc_px;
side=side_y*2+side_x;
p=[xp,yp];
uv_s0=invBilinear(p,[0,0],[.5,0],[px,py],[0,.5]);
uv_s1=invBilinear(p,[.5,0],[1,0],[1,.5],[px,py]);
uv_s2=invBilinear(p,[0,.5],[px,py],[.5,1],[0,1]);
uv_s3=invBilinear(p,[px,py],[1,.5],[1,1],[.5,1]);
uv_s0=[uv_s0[0]*cx, uv_s0[1]*cy];
uv_s1=[uv_s1[0]*cx+cx,uv_s1[1]*cy];
uv_s2=[uv_s2[0]*cx, uv_s2[1]*cy+cy];
uv_s3=[uv_s3[0]*cx+cx,uv_s3[1]*cy+cy];
side==3?I(uv_s3[0],uv_s3[1],0,1,3):
side==2?I(uv_s2[0],uv_s2[1],0,1,3):
side==1?I(uv_s1[0],uv_s1[1],0,1,3):
I(uv_s0[0],uv_s0[1],0,1,3);
"
EDIT: Another test image