вставить больше объектов в алгоритм карты - PullRequest
0 голосов
/ 03 мая 2020

У меня есть карта размером 3000 * 3000, на этой карте много объектов, я хочу добавить больше объектов, но без их столкновения!

В настоящее время у меня 2000 объекты на карте, каждый объект имеет координаты, подобные этому:

"x1" => -1074
"x2" => -1070
"z1" => 912
"z2" => 916

, поэтому я сохраняю его в форме x1-x2, чтобы я знал ширину и высоту каждого объекта, эти координаты сохраняются в database

Поэтому я хочу добавить еще 1000 объектов со случайными координатами в базу данных, но не хочу, чтобы какой-либо из них сталкивался с другими объектами. Как это сделать?

Я использую сеялку Laravel для заполнения новых объектов, PHP язык и MySql база данных. Итак, мне интересно, я должен получить все объекты сначала из базы данных, а затем начать проверять их в PHP, или я должен делать проверки, используя MySql? могу ли я разделить их на основе координат, чтобы ускорить процесс?

мой текущий код (и это ужасно):

{
    $oilCount = 1000;
    $MrGank = $user->find(1);

    for ($i = 0 ; $i < $oilCount; $i ++)
    {
        $currentObject = $MrGank->mapObjects()->create([
            'type' => 'Oil',
            'level' => ceil(0.1 * ($i+1)),
        ]);

        $coords = $this->generateCoords();

        $j = -100;
        while ($this->checkCoordsAvailability($coords) and $j < 0)
        {
            $j++;
            $coords = $this->generateCoords();
        }

        if($j > 100)
        {
            dd("Infinitive loop");
        }

        /** @var \App\Entities\Map\MapObject $currentObject */
        $currentObject->coordinate()->create($coords);
    }

}
/**
 * @return array
 */
function generateCoords()
{
    $x1 = mt_rand(-1496,1496);
    $z1 = mt_rand(-1496,1496);

    return ["x1"=>$x1, "x2" => $x1 + 4, "z1"=>$z1, "z2"=>$z1 + 4];
}

/**
 * @param $coords
 * @return mixed
 */
function checkCoordsAvailability($coords)
{
    $MapObjectClass = addslashes(MapObject::class);
    $LandObjectClass = addslashes(\App\Entities\Land\Land::class);
    $isCollation = DB::select(
        <<<SQL
select
if((Select count(*)
from coordinates
where (objectable_type = '{$MapObjectClass}' or objectable_type = '{$LandObjectClass}')
    and (x1 between {$coords['x1']} and {$coords['x1']} + 4
    or {$coords['x1']} between  x1 and x2)
    and (z1 between {$coords['z1']} and {$coords['z1']} + 4
    or {$coords['z1']} between  z1 and z2  )) > 0,1,0) as isCollation;
SQL
    );
    return $isCollation[0];
}```

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...