Question

I need to generate 4 random numbers, each between [-45 +45] degrees. and if rand%2 = 0 then I want the result (the random number generated to be equal to -angle). Once the 4 random numbers are generated it is requires to scan these angles and find a lock (the point at which the angles meet). Also -3,-2,-1,... +3 in the loop in if statement indicate that the lock takes place within 6 degrees beamwidth. the code works. But can it be simplified? also The objective is to establish a lock between 2 points by scannin elevation and azimuth angles at both points.

  #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();
  }       
Was it helpful?

Solution 2

Integer angles in degrees? Very questionable. Something "physical" like an angle is normally best expressed as a floating-point number, so I'd first change

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

That seems to make it more difficult at first sight because neither the random-range-selection with % works anymore nor is it much use to compare floats for equality. Which is, however, a good thing, because all of this is in fact very bad practise.

If you want to keep using rand() as the random number generator (though I'd suggest std::uniform_real_distribution), write a function to do this:

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

Now you'd just do

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

Then you need to do this range-checking. That's again something to put in a dedicated function

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

Then you do this exhaustive search for locks. This could definitely be done more efficiently, but that's an algorithm issue and has nothing to do with the language. Sticking to the for loops, you can still make them look much nicer by avoiding this explicit break checking. One way is good old goto, I'd propose here you just stick it in an extra function and return when you're done

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

OTHER TIPS

BS1.lockaz = rand() % 91 - 45;
BS1.lockel = rand() % 91 - 45;
BS2.lockaz = rand() % 91 - 45;
BS2.lockel = rand() % 91 - 45;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top