0

これはCにあります。

同じ空間をサンプリングする 2 つの 2D 配列 ArrayA と ArrayB があります。B は ArrayA とは異なる属性をサンプリングする頻度が ArrayA よりも低いため、A よりも小さくなります。

いくつかの変数を定義してみます。

ArrayA と ArrayB は、配列の先頭へのポインタです。最初に X の行が格納され、次に Y がインクリメントされ、X の次の行が格納されます (Y=1)。

そのため、指定された indexA から indexB を設定して、indexA の値に関連付ける最近傍サンプルにする必要があります。

ここに私がいます (エラーがあれば修正してください! インデックス 0 から開始していることに注意してください): indexA = 0 posB 0,0; インデックスB = 0

posA 8,0; indexA = 8 (最初の行の終わり) posB 2,0; インデックス B = 2

posA 0,1; indexA = 9 posB 0,0; indexB = 0 (まだ底点に近い)

posA 0,3; indexA = 27 posB 0,1; インデックスB = 3

posA 8,8; indexA = 80 (最後のポイント) posB 2,2; インデックス B = 8

これまでのところ、indexA = posAX + (posAY * SizeAX) があります。

私が試したこと (そしてもちろん失敗しました): indexB = (int) (indexA * (SizeBX * SizeBY / (SizeAX * SizeAY)) + 0.5) // 最初の行と最後の値に対してのみ機能するように見えます..しかしこれは明らかに機能しません - しかし、2つをどのように正確にマッピングするかについては興味がありますが、修正後に調べます..

posAY や posAX にはアクセスできず、indexA だけでしたが、mod と剰余を使用して分解できるはずですよね? または、より効率的なより高速な方法はありますか?あ

私もこれを試しました:

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

問題は、X インデックスと Y インデックスを別々に丸め、その後 SizeBX と SizeBY を使用する必要があることだと思いますか?

追加の注意点として、ArrayA と ArrayB は、どちらもより大きな空間をサンプリングするより大きなデータ セットから取得されます。四角形は任意であるため、ArrayA または ArrayB のいずれかが四角形の境界に最も近い点を持つ可能性があり、最も近い隣人が実際にグラブしている方法に関する他の問題につながります。これに対処する方法についてもわかりません。

4

2 に答える 2

0

あなたが本質的に意味することは、同じ領域をカバーする間隔が異なる2つのグリッドがあり、そのうちの1つにグリッドポイントのインデックスが与えられ、2番目に最も近いものを見つけたいということです。このような:

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;

を取得するposAXposAYindexA:

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;
于 2009-12-18T20:56:26.150 に答える
0

これらはあなたが選んだ反抗的な名前ですが、少なくともそれらは定義されています。

[0...1]x[0...1] の実座標空間で (x,y) を通過したいと思います。つまり、A の右下は B の右下から値を取得する必要があり、同様に左上の中央なども取得する必要があります。これは、配列内のポイントの外側の端を幅 0 と考える必要があることを意味します。ポイントは、[0...1]x[0...1] ボックスの端で値をサンプリングします。つまり、3x3 配列の場合、(0.5,0.5) に 1 つのポイントがあり、残りはエッジに沿っています。

補間するのが理にかなっているように、2d B 配列には実際の値があると仮定します。配列のサイズが異なるため

ここから行くためのスキームは次のとおりです

indexA -> (posAX,posAY) -> (x,y) -> (fracBX,fracBY) -> (最近傍補間による) ArrayB の値

重要: (fracBX,fracBY) はボックス [0...SizeBX-1]x[0...SizeBY-1] 内の実数値座標です。

一歩ずつ進んでいきましょう。私があなたを理解していると仮定すると、値は、標準の C 配列と同じように、左から右、上から下 (英語で読む) の順序でメモリに格納されます。それで:

unsigned posAX=indexA%SizeAX;
unsigned posAY=indexA/SizeAX;

次に、(x,y) にマップします。

double x=posAX/(SizeAX-1.0); // we get double division when we subtract by 1.0
double y=posAY/(SizeAY-1.0);

ここで、(fracBX,fracBY) に、ここで 0<=fracBX<=SizeBX および 0<=fracBY<=SizeBY:

double fracBX=x*(SizeBX-1);
double fracBY=y*(SizeBY-1);

ここで、B 配列内の (最大 4 つの) 最も近い整数ポイント間を補間するには、次のようにします。

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;

値はあなたの答えです。小数位置 aBX と aBY が 0 であることのチェックは、配列の末尾から離れた値にアクセスするのを防ぐために必要です (値が 0 で乗算されて無視されても、セグメンテーション違反が発生する可能性があります)。または、必要以上に行/列を1つ多く割り当てることで、物事を簡素化できます。

bv[0] は ArrayB[intBX][intBY]、bv[1] は 1 つ右、bv[sizeBY] は 1 つ下、bv[sizeBY+1] は 1 つ下と右です。(aBX,aBY) は [0...1]x[0...1] 内の別のポイントですが、今回は ArrayB 内のこれらの 4 つの隣接ポイントによって境界付けられています。

于 2009-12-18T21:06:42.590 に答える