23

すべての座標が既知の 3 つ以上のノードから基準距離が離れている空間のどこかにある未知のノードの座標を見つけたいと考えています。

この問題は、Trilateration で説明されているTrilaterationとまったく同じです。

ただ、「予備計算と最終計算」の部分がわかりません(ウィキペディアのサイト参照)。P1、P2、および P3 を見つけることができる場所がわからないので、それらの方程式を立てることができますか?

ありがとう

4

3 に答える 3

29

三辺測量は、3 つの球の交差領域の中心を見つけるプロセスです。3 つの球のそれぞれの中心点と半径がわかっている必要があります。

3 つの例の中心点 P1 [-1,1]、P2 [1,1]、および P3 [-1,-1] について考えてみましょう。最初の要件は、P1' が原点にあることです。そのため、オフセット ベクトル V [1,-1] を 3 つすべてに追加して、それに応じてポイントを調整しましょう。

P1' = P1 + V = [0, 0]
P2' = P2 + V = [2, 0]
P3' = P3 + V = [0,-2]

注: 調整されたポイントは、' (プライム) 注釈で示されます。

P2' も x 軸上にある必要があります。この場合、すでに調整されているため、調整は必要ありません。

各球の半径を 2 と仮定します。

これで、3 つの方程式 (与えられた) と 3 つの未知数 (交点の中心の X、Y、Z) ができました。

P4'x について解く:

x = (r1^2 - r2^2 + d^2) / 2d  //(d,0) are coords of P2'
x = (2^2 - 2^2 + 2^2) / 2*2
x = 1

P4'y を解く:

y = (r1^2 - r3^2 + i^2 + j^2) / 2j - (i/j)x //(i,j) are coords of P3'
y = (2^2 - 2^2 + 0 + -2^2) / 2*-2 - 0
y = -1

2D の問題では z を無視します。

P4' = [1,-1]

ここで、オフセット ベクトル V を減算して元の座標空間に変換します。

P4 = P4' - V = [0,0]

解点 P4 は、予想どおり原点にあります。

この記事の後半では、P1 が原点にない、または P2 が x 軸上にない一連の点を、これらの制約に適合するように表す方法について説明しています。代わりに翻訳と考えるのが好きですが、どちらの方法でも同じ解決策が得られます。

編集: P2' を x 軸に回転

P1 を原点に移動した後、P2' が x 軸上にない場合は、ビューで回転を実行する必要があります。

まず、例として使用する新しいベクトルをいくつか作成しましょう: P1 = [2,3] P2 = [3,4] P3 = [5,2]

最初に P1 を原点に変換する必要があることを思い出してください。いつものように、オフセット ベクトル V は -P1 です。この場合、V = [-2,-3]

P1' = P1 + V = [2,3] + [-2,-3] = [0, 0]
P2' = P2 + V = [3,4] + [-2,-3] = [1, 1]
P3' = P3 + V = [5,2] + [-2,-3] = [3,-1]

回転角度を決定するには、P2' と [1,0] (x 軸) の間の角度を見つける必要があります。

内積の等価性を使用できます。

A dot B = ||A|| ||B|| cos(theta)

B が [1,0] の場合、これは単純化できます。A ドット B は常に A の X コンポーネントであり、||B|| です。(B の大きさ) は常に 1 倍であるため、無視できます。

Ax = ||A|| になりました。cos(シータ)、これを最終的な方程式に再配置できます。

theta = acos(Ax / ||A||)

または私たちの場合:

theta = acos(P2'x / ||P2'||)

||A|| を使用して P2' の大きさを計算します。= sqrt(Ax + Ay + Az)

||P2'|| = sqrt(1 + 1 + 0) = sqrt(2)

それを差し込むと、シータを解くことができます

theta = acos(1 / sqrt(2)) = 45 degrees

次に、回転行列を使用してシーンを -45 度回転させましょう。P2'y は正で、回転行列は反時計回りに回転するため、負の回転を使用して P2 を x 軸に揃えます (P2'y が負の場合、シータを否定しないでください)。

R(theta) = [cos(theta) -sin(theta)]
           [sin(theta)  cos(theta)]

  R(-45) = [cos(-45) -sin(-45)]
           [sin(-45)  cos(-45)]

平行移動と回転の両方が行われたベクトルを示すために、ダブル プライム表記法 '' を使用します。

P1'' = [0,0] (no need to calculate this one)

P2'' = [1 cos(-45) - 1 sin(-45)] = [sqrt(2)] = [1.414]
       [1 sin(-45) + 1 cos(-45)] = [0]       = [0]

P3'' = [3 cos(-45) - (-1) sin(-45)] = [sqrt(2)]    = [ 1.414]
       [3 sin(-45) + (-1) cos(-45)] = [-2*sqrt(2)] = [-2.828]

これで、P1''、P2''、および P3'' を使用して P4'' を解くことができます。P4'' に逆回転を適用して P4' を取得し、次に逆平行移動を適用して中心点である P4 を取得します。

回転を元に戻すには、P4'' を R(-theta) で乗算します。この場合は R(45) です。移動を元に戻すには、オフセット ベクトル V を減算します。これは、P1 を追加するのと同じです (最初に V として -P1 を使用したと仮定します)。

于 2013-04-23T18:39:24.693 に答える
0

これは、私が 3D プリンターのファームウェアで使用するアルゴリズムです。座標系の回転を回避しますが、最善ではない場合があります。

三辺測量の問題には 2 つの解決策があります。2 番目のものを取得するには、二次方程式の解の "- sqrtf" を "+ sqrtf" に置き換えます。

十分なプロセッサ パワーとメモリがあれば、浮動小数点数の代わりに倍精度数を使用できることは明らかです。

// Primary parameters
float anchorA[3], anchorB[3], anchorC[3];               // XYZ coordinates of the anchors

// Derived parameters
float Da2, Db2, Dc2;
float Xab, Xbc, Xca;
float Yab, Ybc, Yca;
float Zab, Zbc, Zca;
float P, Q, R, P2, U, A;

...

inline float fsquare(float f) { return f * f; }

...

// Precompute the derived parameters - they don't change unless the anchor positions change.
Da2 = fsquare(anchorA[0]) + fsquare(anchorA[1]) + fsquare(anchorA[2]);
Db2 = fsquare(anchorB[0]) + fsquare(anchorB[1]) + fsquare(anchorB[2]);
Dc2 = fsquare(anchorC[0]) + fsquare(anchorC[1]) + fsquare(anchorC[2]);
Xab = anchorA[0] - anchorB[0];
Xbc = anchorB[0] - anchorC[0];
Xca = anchorC[0] - anchorA[0];
Yab = anchorA[1] - anchorB[1];
Ybc = anchorB[1] - anchorC[1];
Yca = anchorC[1] - anchorA[1];
Zab = anchorB[2] - anchorC[2];
Zbc = anchorB[2] - anchorC[2];
Zca = anchorC[2] - anchorA[2];
P = (  anchorB[0] * Yca
     - anchorA[0] * anchorC[1]
     + anchorA[1] * anchorC[0]
     - anchorB[1] * Xca
    ) * 2;
P2 = fsquare(P);
Q = (  anchorB[1] * Zca
     - anchorA[1] * anchorC[2]
     + anchorA[2] * anchorC[1]
     - anchorB[2] * Yca
    ) * 2;  

R = - (  anchorB[0] * Zca
       + anchorA[0] * anchorC[2]
       + anchorA[2] * anchorC[0]
       - anchorB[2] * Xca
      ) * 2;
U = (anchorA[2] * P2) + (anchorA[0] * Q * P) + (anchorA[1] * R * P);
A = (P2 + fsquare(Q) + fsquare(R)) * 2;

...

// Calculate Cartesian coordinates given the distances to the anchors (La, Lb and Lc)
// First calculate PQRST such that x = (Qz + S)/P, y = (Rz + T)/P.
// P, Q and R depend only on the anchor positions, so they are pre-computed
const float S = - Yab * (fsquare(Lc) - Dc2)
                - Yca * (fsquare(Lb) - Db2)
                - Ybc * (fsquare(La) - Da2);
const float T = - Xab * (fsquare(Lc) - Dc2)
                + Xca * (fsquare(Lb) - Db2)
                + Xbc * (fsquare(La) - Da2);

// Calculate quadratic equation coefficients
const float halfB = (S * Q) - (R * T) - U;
const float C = fsquare(S) + fsquare(T) + (anchorA[1] * T - anchorA[0] * S) * P * 2 + (Da2 - fsquare(La)) * P2;

// Solve the quadratic equation for z
float z = (- halfB - sqrtf(fsquare(halfB) - A * C))/A;

// Substitute back for X and Y
float x = (Q * z + S)/P;
float y = (R * z + T)/P;
于 2017-11-27T18:46:20.990 に答える