0

それぞれ [-45 +45] 度の間の 4 つの乱数を生成する必要があります。rand%2 = 0 の場合、結果が必要です (生成された乱数は -angle に等しくなります)。4 つの乱数が生成されたら、これらの角度をスキャンしてロック (角度が交わる点) を見つける必要があります。また、if ステートメントのループ内の -3、-2、-1、... +3 は、ロックが 6 度のビーム幅内で行われることを示します。コードは機能します。しかし、それは単純化できますか?また、目的は、両方のポイントで仰角と方位角をスキャンすることにより、2 つのポイント間にロックを確立することです。

  #include <iostream>
  #include <conio.h>
  #include <time.h>
  using namespace std;

  class Cscan
  {
    public:
    int gran, lockaz, lockel;

  };

  int main()
  {
     srand (time(NULL));
    int az1, az2, el1, el2, j, k;


    BS1.lockaz = rand() % 46;
    BS1.lockel = rand() % 46;
    BS2.lockaz = rand() % 46;
    BS2.lockel = rand() % 46;

    k = rand() % 2;
    if(k == 0)
            k = -1;
    BS1.lockaz = k*BS1.lockaz;

    k = rand() % 2;
    if(k == 0)
            k = -1;
    BS1.lockel = k*BS1.lockel;

            k = rand() % 2;
    if(k == 0)
            k = -1;
    BS2.lockaz = k*BS2.lockaz;

    k = rand() % 2;
    if(k == 0)
            k = -1;
    BS2.lockel = k*BS2.lockel;

    for(az1=-45; az1<=45; az1=az1+4)
    {
            for(el1=-45; el1<=45; el1=el1+4)
            {
                    for(az2=-45; az2<=45; az2=az2+4)
                    {
                            for(el2=-45; el2<=45; el2=el2+4)
                            {

           if((az1==BS1.lockaz-3||az1==BS1.lockaz-2||az1==BS1.lockaz-1||az1==BS1.lockaz||az1==BS1.lockaz+1||az1==BS1.lockaz+2||az1==BS1.lockaz+3)&&

           (az2==BS2.lockaz-3||az2==BS2.lockaz-2||az2==BS2.lockaz-1||az2==BS2.lockaz||az2==BS2.lockaz+1||az2==BS2.lockaz+2||az2==BS2.lockaz+3)&&

           (el1==BS1.lockel-3||el1==BS1.lockel-2||el1==BS1.lockel-1||el1==BS1.lockel||el1==BS1.lockel+1||el1==BS1.lockel+2||el1==BS1.lockel+3)&&

            (el2==BS2.lockel-3||el2==BS2.lockel-2||el2==BS2.lockel-1||el2==BS2.lockel||el2==BS2.lockel+1||el2==BS2.lockel+2||el2==BS2.lockel+3))
                                    {      
             cout << "locked \n" << BS1.lockaz << " " << BS1.lockel << " " << BS2.lockaz << " " << BS2.lockel <<endl
              < az1 << " " << el1 << " " << az2 << " " << el2 << endl;
                                                    k = 1;
                                            break;
                                    }
                                    if(k==1)
                                            break;
                            }
                            if(k==1)
                                    break;
                    }
                    if(k==1)
                            break;
            }
            if(k==1)
                    break;
    }
    _getch();
  }       
4

2 に答える 2

2
BS1.lockaz = rand() % 91 - 45;
BS1.lockel = rand() % 91 - 45;
BS2.lockaz = rand() % 91 - 45;
BS2.lockel = rand() % 91 - 45;
于 2012-11-20T10:39:08.897 に答える
1

度単位の整数角度? 非常に疑わしい。角度のような「物理的な」ものは、​​通常、浮動小数点数として表現するのが最適なので、最初に変更します

typedef double angle;

struct Cscan {  // why class? This is clearly POD
  int gran; //I don't know what gran is. Perhaps this should also be floating-point.
  angle lockaz, lockel;
};

%random-range-selection が機能しなくなったり、float が等しいかどうかを比較するのにあまり使用されなかったりするため、一見したところ、それがより難しくなっているように見えます。しかし、これは良いことです。なぜなら、これは実際には非常に悪い習慣だからです。

rand()乱数ジェネレーターとして使用し続けたい場合(私はお勧めしますがstd::uniform_real_distribution)、これを行う関数を作成します。

const double pi = 3.141592653589793;  // Let's use radians internally, not degrees.
const angle rightangle = pi/2.;      //  It's much handier for real calculations.

inline angle deg2rad(angle dg) {return dg * rightangle / 90.;}

angle random_in_sym_rightangle() {
  return rightangle * ( ((double) rand()) / ((double) RAND_MAX) - .5 );
}

今、あなたはただやります

BS1.lockaz = random_in_sym_rightangle();
BS1.lockel = random_in_sym_rightangle();
BS2.lockaz = random_in_sym_rightangle();
BS2.lockel = random_in_sym_rightangle();

次に、この範囲チェックを行う必要があります。これも専用の関数に入れるものです

bool equal_in_margin(angle theta, angle phi, angle margin) {
  return (theta > phi-margin && theta < phi+margin);
}

次に、ロックを徹底的に検索します。これは間違いなくもっと効率的に行うことができますが、それはアルゴリズムの問​​題であり、言語とは何の関係もありません。ループに固執すると、forこの明示的なブレーク チェックを回避することで、ループの見栄えを良くすることができます。1つの方法は古き良きものgotoです。ここでは、それを追加の関数に貼り付けて、完了したら戻ることを提案します

#define TRAVERSE_SYM_RIGHTANGLE(phi) \
  for ( angle phi = -pi/4.; phi < pi/4.; phi += deg2rad(4) )

int lock_k  // better give this a more descriptive name
      ( const Cscan& BS1, const Cscan& BS2, int k ) {
  TRAVERSE_SYM_RIGHTANGLE(az1) {
    TRAVERSE_SYM_RIGHTANGLE(el1) {
      TRAVERSE_SYM_RIGHTANGLE(az2) {
        TRAVERSE_SYM_RIGHTANGLE(el2) {
          if( equal_in_margin( az1, BS1.lockaz, deg2rad(6.) )
               && equal_in_margin( el1, BS1.lockel, deg2rad(6.) )
               && equal_in_margin( az2, BS1.lockaz, deg2rad(6.) )
               && equal_in_margin( el2, BS2.lockel, deg2rad(6.) ) ) {
            std::cout << "locked \n" << BS1.lockaz << " " << BS1.lockel << " " << BS2.lockaz << " " << BS2.lockel << '\n'
               << az1 << " " << el1 << " " << az2 << " " << el2 << std::endl;
            return 1;
          }
        }
      }
    }
  }
  return k;
}
于 2012-11-20T11:38:06.673 に答える