2

次のシステムがあるとします。

ここに画像の説明を入力

どこ:

  • Ar: xz 平面上の半径を持つ円のエッジ上の任意の場所に存在する点。
  • θ: 正の x 軸と、原点から点へのベクトルの間の角度A。これは、-PI/2 から PI/2 の範囲である必要があります。
  • B1: 円と高さ の正の x 軸の交点h1
  • B2: の高さで円と正の z 軸の交点にある点h2
  • d1B1:との間の距離A
  • d2B2:との間の距離A

仮定:

  • h1h2、およびrは既知の定数です。
  • d1d2は既知の変数です。

どうすれば見つけられますθか?

arctan2これは最終的に、 、sine、およびのかなり高速な関数を持つ組み込みシステムの C で実装されますcosine。そのため、パフォーマンスは間違いなく優先事項であり、推定値が小数点以下 3 桁まで正しければ使用できます (これは私の三角関数の精度です)。

ただし、数学的なアルゴリズムが与えられたとしても、特定の実装を解決できると確信しています。

それだけの価値があるので、私は次のようになりました:

(d1^2 - h1^2) / r = (sin(θ))^2        + (cos(θ))^2
(d2^2 - h2^2) / r = (sin(PI/4 - θ))^2 + (cos(PI/4 - θ))^2

数学的に、これは私のリーグをはるかに超えていることに気付く前

4

2 に答える 2

1

@Rhialto を採用し、追加の単純化とコーナー ケースのテスト:

// c1 is the signed chord distance A to (B1 projected to the xz plane)
// c1*c1 + h1*h1 = d1*d1
// c1 = +/- sqrt(d1*d1 - h1*h1)  (choose sign later)
// c1 = Cord(r, theta) = fabs(r*2*sin(theta/2))
// theta = asin(c1/(r*2))*2
//
// theta is < 0 when d2 > sqrt(h2*h2 + sqrt(2)*r*sqrt(2)*r)
// theta is < 0 when d2 > sqrt(h2*h2 + 2*r*r)
// theta is < 0 when d2*d2 > h2*h2 + 2*r*r

#define h1 (0.1)
#define h2 (0.25)
#define r (1.333)

#define h1Squared (h1*h1)
#define rSquared  (r*r)
#define rSquaredTimes2  (r*r*2)
#define rTimes2   (r*2)
#define d2Big (h2*h2 + 2*r*r)

// Various steps to avoid issues with d1 < 0, d2 < 0, d1 ~= h1 and theta near pi
double zashu(double d1, double d2) {
  double c1Squared = d1*d1 - h1Squared;
  if (c1Squared < 0.0)
    c1Squared = 0.0;  // _May_ be needed when in select times |d1| ~= |h1|
  double a = sqrt(c1Squared) / rTimes2;
  double theta = (a <= 1.0) ? asin(a)*2.0 : asin(1.0)*2.0; // Possible a is _just_ greater than 1.0
  if (d2*d2 > d2Big) // this could be done with fabs(d2) > pre_computed_sqrt(d2Big)
    theta = -theta;
  return theta;
}
于 2013-08-12T22:24:56.180 に答える