C 二维数组的一维索引到较小二维数组的最近邻映射

C 二维数组的一维索引到较小二维数组的最近邻映射,c,pointers,indexing,multidimensional-array,nearest-neighbor,C,Pointers,Indexing,Multidimensional Array,Nearest Neighbor,这是C 我有两个二维数组,ArrayA和ArrayB,它们采样相同的空间。B比ArrayA对不同属性的采样频率低,因此比a小 只是尝试定义一些变量: ArrayA:SizeAX by SizeAY,通过indexA索引位置posAX,posAY ArrayB:SizeBX by SizeAY,由indexB索引位置posBX,posBY ArrayA和ArrayB是指向数组开头的指针,其中先存储X的行,然后递增Y,然后存储X的下一行(Y=1) 所以我需要从一个给定的indexA设置indexB,

这是C

我有两个二维数组,ArrayA和ArrayB,它们采样相同的空间。B比ArrayA对不同属性的采样频率低,因此比a小

只是尝试定义一些变量: ArrayA:SizeAX by SizeAY,通过indexA索引位置posAX,posAY ArrayB:SizeBX by SizeAY,由indexB索引位置posBX,posBY

ArrayA和ArrayB是指向数组开头的指针,其中先存储X的行,然后递增Y,然后存储X的下一行(Y=1)

所以我需要从一个给定的indexA设置indexB,这样它就是一个最近邻样本,与indexA的值相关联

这里是我的位置(请更正所有错误!请注意,我从索引0开始): 如果ArrayA为9x9,ArrayB为3x3: (posX,posY) posa0,0;指数=0 posb0,0;indexB=0

posA 8,0;indexA=8(第一行的末尾) posb2,0;indexB=2

posa0,1;指数=9 posb0,0;indexB=0(更接近底点)

posa0,3;指数=27 posb0,1;indexB=3

posA 8,8;indexA=80(最后一点) posb2,2;indexB=8

到目前为止,我已经: indexA=posAX+(posAY*SizeAX)

我尝试过的(当然失败了): indexB=(int)(indexA*(SizeBX*SizeBY/(SizeAX*SizeAY))+0.5)//仅对第一行和最后一个值有效。。但这显然不起作用——但我很好奇它到底是如何将两者映射在一起的,但我会在修复它之后再进行研究

我没有访问posAY或posAX的权限,只有indexA,但我应该能够使用mod和rements来分解它,对吗?还是有更有效更快的方法?A

我也试过:

indexB=(posAY*SizeBY/SizeAY)*SizeBY+(posAX*SizeBX/SizeAX)

我认为问题在于我需要分别对X和Y索引进行四舍五入,然后再使用SizeBX和SizeBY


另外需要注意的是,ArrayA和ArrayB来自更大的数据集,这两个数据集的采样空间都更大。由于矩形是任意的,ArrayA或ArrayB中可能有最接近矩形边界的点,这导致了最近的邻居究竟以何种方式抓取的其他问题。我也不知道如何解决这个问题。

你的基本意思是,你有两个不同间距的网格,覆盖同一区域,给定其中一个网格点的索引,你想在第二个网格点中找到最近的一个。像这样:

int posBX = (int)floorf((float(posAX) / float(sizeAX - 1)) * float(sizeBX - 1) + 0.5f);
int posBY = (int)floorf((float(posAY) / float(sizeAY - 1)) * float(sizeBY - 1) + 0.5f);
int indexB = posBX + posBY * sizeBX;
要从
indexA
获取
posAX
posAY

posAX = indexA % sizeAX;
posAY = indexA / sizeAX;
要执行双线性插值,请执行以下操作:

float bx = (float(posAX) / float(sizeAX - 1)) * float(sizeBX - 1);
float by = (float(posAY) / float(sizeAY - 1)) * float(sizeBY - 1);
int x = min(int(floorf(bx)), sizeBX - 2); //x + 1 must be <= sizeBX - 1
int y = min(int(floorf(by)), sizeBY - 2); //y + 1 must be <= sizeBY - 1
float s = bx - float(x);
float t = by - float(y);
float v[4];
v[0] = arrayB[x + y * sizeBX];
v[1] = arrayB[x + 1 + y * sizeBX];
v[2] = arrayB[x + (y + 1) * sizeBX];
v[3] = arrayB[x + 1 + (y + 1) * sizeBX];
float result = (v[0] * (1.0f - s) + v[1] * s) * (1.0f - t) +
               (v[2] * (1.0f - s) + v[3] * s) * t;
float bx=(float(posAX)/float(sizeAX-1))*float(sizeBX-1);
浮点数=(浮点数(posAY)/浮点数(sizeAY-1))*浮点数(sizeBY-1);

int x=最小值(int(floorf(bx)),sizeBX-2//x+1一定是你选择了一些令人反感的名字,但至少它们是被定义的

我想你想在[0…1]x[0…1]实坐标空间中通过(x,y);也就是说,A的右下角应该从B的右下角获取值,同样,对于中上左等,这意味着您应该将数组中点的外部边缘视为[0…1]x[0…1]框边缘的0宽度点采样值;i、 e.如果您有一个3x3阵列,则在(0.5,0.5)处有一个点,其余点沿一条边

我假设你的2d B数组中有实值,所以插值是有意义的;因为数组的大小不同

这是一个从a出发的计划

ArrayB中的indexA->(posAX,posAY)->(x,y)->(fracBX,fracBY)->(通过最近邻插值)值

重要提示:(fracBX,fracBY)是[0…SizeBX-1]x[0…SizeBY-1]框中的实值坐标

让我们一步一步来。假设我理解您的意思,值在内存中的顺序是左->右,上->下(英文阅读),就像标准的C数组一样。然后:

unsigned posAX=indexA%SizeAX;
unsigned posAY=indexA/SizeAX;
现在,让我们映射到(x,y):


现在,到(fracBX,fracBY),0I几乎就在那里,但是在决定把-1放在哪里时遇到了问题!谢谢关于最后一部分该怎么做有什么线索吗?我担心在某些情况下,它可能选择了错误的点,但可能它实际上是这样自动处理自己的?下面我稍微复杂一点的答案执行最近邻插值,在SizeBX除以SizeAX和SizeBY平均除以SizeAY的情况下应该是一致的。嗯,你的意思是区域
A
和区域
B
的界限不一定一致吗?我假设你的答案是正确的(我没有检查);你只是到了最近的地方。我计算了
B
中四个最近点的平均值。例如,
A
是一个3乘4的数组,
B
是11乘5的数组。换句话说,我认为与
A
@wrang-wrang相比,
B
的水平和垂直分辨率可能会有不同的比率。我理解你的双线性插值,我的评论是针对OP的评论。感谢你的回答,billinear插值可能是我接下来的一步!!如果
unsigned intBY=(unsigned)fracBY
(SizeBY-1)
(边界上的posAY
)完全相同,则此插值不起作用。在本例中,您将对数组外部的行
SizeBY
进行采样。(请检查我的答案了解另一个版本)在这种情况下,alpha将为0,因此只使用上/左地址。我同意这需要小心,但我很小心。
double x=posAX/(SizeAX-1.0); // we get double division when we subtract by 1.0
double y=posAY/(SizeAY-1.0);
double fracBX=x*(SizeBX-1);
double fracBY=y*(SizeBY-1);
unsigned intBX=(unsigned)fracBX;
double aBX=fracBX-intBX;
unsigned intBY=(unsigned)fracBY;
double aBY=fracBY-intBY;
double *bv=ArrayB+(intBX*sizeBY)+intBY;
#define INTERP(alpha,v1,v2) ((1-alpha)*v1+alpha*v2)
#define INTERPI(alpha,i1,i2) (alpha>0 ? INTERP(alpha,bv[i1],bv[i2] : bv[i1])
double v0=INTERPI(aBX,0,1);
double value=fracBY>0 ? INTERP(aBY,v0,INTERPI(aBX,sizeBY,sizeBY+1)) : v0;