//欧几里得算法 求两个数a、b的最大公约数
function gcd(a,b){
return b===0?a:gcd(b,a%b)
}
//获取一个位置的相似度
function getOneSame(x,y,rect1,rect2){
let endn,n,i;
const arrX=[]
const arrXF=[]
endn=(x+1)*rect2.width;
n=x*rect2.width;
i=parseInt(n/rect1.width);
while(n<endn){
arrX.push(i)
i++;
const pren=n;
n=Math.min(i*rect1.width,endn)
arrXF.push(n-pren)
}
const arrY=[]
const arrYF=[]
endn=(y+1)*rect2.height
n=y*rect2.height;
i=parseInt(n/rect1.height);
while(n<endn){
arrY.push(i)
i++;
const pren=n;
n=Math.min(i*rect1.height,endn)
arrYF.push(n-pren)
}
const k = y*rect1.width + x;
let fz=0;
let fm=rect2.width*rect2.height;
arrY.forEach(function (y2,ny) {
arrX.forEach(function (x2,nx) {
const k2 = y2*rect2.width + x2;
if(rect1.data[k]===rect2.data[k2]){
fz=fz+arrYF[ny]*arrXF[nx];
}
})
})
return [fz,fm]
}
//获取相似度
function getSameByRect(rect1,rect2){
let fArr;
let fm=rect1.width*rect1.height;
for(let y=0;y<rect1.height;y++){
for(let x=0;x<rect1.width;x++){
const arr=getOneSame(x,y,rect1,rect2)
if(!fArr){
fArr=arr;
}else{
fArr[0]=fArr[0]*arr[1]+fArr[1]*arr[0];
fArr[1]=fArr[1]*arr[1];
const g=gcd(fArr[0],fArr[1])
fArr[0]=fArr[0]/g;
fArr[1]=fArr[1]/g;
}
}
}
fArr[1]=fArr[1]*fm;
return fArr[0]/fArr[1]
}
function getSquareRect(rect1) {
if(rect1.width>rect1.height){
const top=(rect1.width-rect1.height)>>1;
const bottom=rect1.height+top;
const nRect1={
width:rect1.width,
height:rect1.width,
data:[]
}
console.log(top,bottom)
for(let y=0;y<nRect1.height;y++){
for(let x=0;x<nRect1.width;x++){
if(y<top){
nRect1.data.push(undefined);
}else if(y<bottom){
nRect1.data.push(rect1.data[(y-top)*rect1.width+x]);
}else{
nRect1.data.push(undefined);
}
}
}
return nRect1;
}else if(rect1.width<rect1.height){
const top=(rect1.height-rect1.width)>>1;
const bottom=rect1.width+top;
const nRect1={
width:rect1.height,
height:rect1.height,
data:[]
}
console.log(top,bottom)
for(let y=0;y<nRect1.height;y++){
for(let x=0;x<nRect1.width;x++){
if(x<top){
nRect1.data.push(undefined);
}else if(x<bottom){
nRect1.data.push(rect1.data[y*rect1.width+(x-top)]);
}else{
nRect1.data.push(undefined);
}
}
}
return nRect1;
}
return rect1;
}
function getSimilarityByRect(rect1,rect2) {
const nrect1=getSquareRect(rect1)
const nrect2=getSquareRect(rect2)
const same=getSameByRect(nrect1,nrect2)
return 1-same;
}
const dis=getSimilarityByRect({
width:2,
height:1,
data:[1,0]
},{
width:3,
height:1,
data:[1,1,0]
})
console.log(dis)