Мне нужно сгенерировать 4 случайных числа, каждое между [-45 +45] градусами. и если rand% 2 = 0, то я хочу, чтобы результат (случайное число было сгенерировано равным -angle). После того, как сгенерированы 4 случайных числа, необходимо отсканировать эти углы и найти замок (точку, в которой встречаются углы). Также -3, -2, -1, … +3 в цикле в операторе if указывают, что блокировка происходит в пределах ширины луча 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();
}
Целые углы в градусах? Очень сомнительно Что-то «физическое», например, угол, обычно лучше всего выражать числом с плавающей запятой, поэтому я бы сначала изменил
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;
}
BS1.lockaz = rand() % 91 - 45;
BS1.lockel = rand() % 91 - 45;
BS2.lockaz = rand() % 91 - 45;
BS2.lockel = rand() % 91 - 45;