У меня есть карта размером 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];
}```