2014-11-27 2 views
1

Я думаю, что это лучше всего объяснить с каким-то псевдо-кодом:C++: Проверьте значение всех свойств объекта в векторе

std::vector<Yes> objs; 
//The Yes Class constructor: Yes(x,y) 
//Let's imagine I instantiated this vector with one object somewhere appropriately 

void inSomeFunction() 
{ 
    for(int i = 0; i < 20; ++i) 
    { 
     int randX = rand() % mapWidth; 
     int randY = rand() % mapHeight; 

     for(int j = 0; j < objs.size(); ++j) 
     { 
     if(randX > x + threshold, for all objects in my vector && randY > y + threshold, for all objects in my vector) 
     { 
      objs.push_back(Yes(randX,randY)); 
     } 
     } 
    } 
} 

Так что есть окно, размеры которого mapWidth и mapHeight и я в основном только пытаясь сделать 20 объектов, которые не перекрывают друг друга в плоскости xy.

Я также хочу убедиться, что randX и randY не перекрываются, а также на некотором расстоянии от всех других существующих объектов. Итак, скажем, мой порог = 20, тогда я хочу убедиться, что randX и randY не содержатся с кругом радиуса 20, окружающим любой/весь существующий объект (ы) в векторе.

Пример для ясности: сначала Да объект находится в (x, y) = (10,20) и мой порог = 20, я хочу создать второй объект, принимая randX и randY в качестве параметров, и вставляю его в свой вектор; однако я хочу убедиться, что точка (randX, randY) не лежит в круге радиуса 20 и центрирована на (10,20), которая является координатами моего первого объекта. Программа может либо генерировать другое случайное (x, y), либо просто генерировать randX и randY, чтобы соответствовать условиям, которые я хочу, но мне нужно, чтобы они проверяли это для всех объектов в моем векторе, когда я создаю больше объектов.

Я хочу знать, как это сделать? Также для большей ясности это для игры. Я пытаюсь создать несколько зданий на двумерной карте, но я, очевидно, не хочу, чтобы они перекрывались или были близки друг к другу. Как я могу это сделать?

+0

Что вы думаете? Я не вижу вопросительного знака. – Blacktempel

+0

Извинения, два последних абзаца - мои вопросы, что я хочу знать, как выполнить то, что я описал в этих параграфах. – rawa

ответ

1

Я бы разбил это на более мелкие функции.
Что-то вроде этого:

bool overlaps(const Yes& thing, int x, int y) 
{ 
    // See if (x, y) overlaps 'thing' in whichever way is appropriate. 
} 

bool overlaps_any(const std::vector<Yes>& things, int x, int y) 
{ 
    for (const Yes& thing : things) 
    { 
     if (overlaps(thing, x, y)) 
     { 
     return true; 
     } 
    } 
    return false; 
} 

void inSomeFunction(std::vector<Yes>& objs) 
{ 
    for(int i = 0; i < 20; ++i) 
    { 
     int x = 0; 
     int y = 0; 
     do { 
     x = rand() % mapWidth; 
     y = rand() % mapHeight; 
     } while (overlaps_any(objs, x, y)); 
     objs.push_back(Yes(x,y)); 
    } 
} 

Есть, возможно, более эффективные способы, но так как вы только генерировать карту один раз, я бы не беспокоиться об эффективности на данный момент.

+0

Хм, что может быть более эффективным способом? Поскольку я не планирую создавать только 20 объектов, это, скорее всего, будет в тысячах. – rawa

+0

Также вы не могли бы объяснить синтаксис выше немного больше? Почему перекрытия принимают «Да и вещь» в качестве аргумента? Я вообще не понимаю функцию overlaps_any. Почему вы также устанавливаете все эти входные аргументы в качестве констант? – rawa

0

Вот как пройти через вектор. Вы можете сравнить элементы с вашими значениями.

std::vector<Object> objs; 

void inSomeFunction() 
{ 
    for (int i = 0; i < 20; ++i) 
    { 
     int randX = rand() % mapWidth; 
     int randY = rand() % mapHeight; 

     for (std::vector<Object>::iterator itrObj = objs.begin(); itrObj != objs.end(); ++itrObj) 
     { 
      //Here you can access with operator -> the members of the class 
      //itrObj->x 
      //Or 
      //(*itrObj).x 
      //This is how you iterate through a std::vector<T> 
      // 
      //Do stuff with the values here 
      // 
      //If you do not wish to change the members 
      //of the class Object stored in this vector and only compare them 
      //use a const_iterator instead of iterator 
     } 
    } 

Это способ проверить, если он находится в пределах досягаемости:

struct Window 
{ 
    Window (int x, int y, int width, int height) 
     : x(x) 
     , y(y) 
     , width(width) 
     , height(height) 
    {} 
    int x; 
    int y; 
    int width; 
    int height; 
}; 

struct Position 
{ 
    Position (int x, int y) 
     : x(x) 
     , y(y) 
    {} 
    int x; 
    int y; 
}; 

bool IsWithinRange (const Window &Range, const Position &Check) 
{ 
    int r_x   = Range.x, 
     r_y   = Range.y, 
     r_width  = Range.width, 
     r_height = Range.height, 
     r_max_x  = r_width + r_x, 
     r_max_y  = r_height + r_y; 

    if (Check.x >= r_x && Check.x <= r_max_x) 
     if (Check.y >= r_y && Check.y <= r_max_y) 
      return true; 
    return false; 
} 

Я не уверен, как структурирован ваш класс Object, но я уверен, что вы можете сделать небольшие изменения.

+0

Это даже не близко к запросу, запрошенному OP – ravi

+0

Даже не понятно, что хочет OP.'Я предполагаю, что вы хотите' – Blacktempel

+0

---- Обновлено ---- – Blacktempel

0

Я собираюсь выйти на конечность здесь, основываясь на том, что я читаю. Не лучший способ, но это просто. Трудно сказать, не зная своего проекта. Но если вы дадите нам свой полный проект, мы скажем, что вы сократите, как вы уже сделали. Итак, я бы предположил, что вы в лучшем случае получите спекулятивные ответы.

Тем не менее, идея:

Создать массив 2D булевой макс-х и макс-у вы можете иметь. Для каждого объекта это займет пространство x, y в этом массиве, установив значения в значение true. Затем вы можете проверить, что-то слишком близко, или если оно уже используется, сканируя так далеко от заданного случайного значения.

Смежные вопросы