0

我需要生成 4 个随机数,每个随机数在 [-45 +45] 度之间。如果 rand%2 = 0 那么我想要结果(生成的随机数等于 -angle)。一旦生成了 4 个随机数,就需要扫描这些角度并找到一个锁(角度相交的点)。if 语句中循环中的 -3,-2,-1,... +3 表示锁定发生在 6 度波束宽度内。代码有效。但是可以简化吗?目标也是通过扫描两个点的仰角和方位角在两个点之间建立锁定。

  #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;
};

乍一看,这似乎使它变得更加困难,因为带有随机范围选择的随机范围选择%不再有效,也没有太多用处来比较浮点数是否相等。然而,这是一件好事,因为所有这些实际上都是非常糟糕的做法。

如果您想继续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循环,您仍然可以通过避免这种显式的中断检查来使它们看起来更好。一种方法很老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 回答