Мне нужно построить изображения внутри круга на сетке.
Смотрите картинку ниже сетки / круга.
Зелёный кружок — это контейнер, снаружи не должно быть изображений.
Смотрите пример ниже. Фиолетовые квадраты = не размещены, желтые квадраты = размещены (так как они находятся внутри зеленого круга, и они будут соответствовать).
Цветные квадраты представляют изображения, которые будут размещены.
Квадраты 50х50. В то время как сеточные плитки имеют размер 100х100.
В настоящее время моя программа будет генерировать круг, сетку и отмечать X внутри каждой плитки сетки, независимо от того, находится ли она внутри круга контейнера.
Ниже приведен пример работы программы и размещения изображений.
Как я мог бы работать, если изображение поместилось бы внутри плитки, которая находится внутри круга.
Плитка не должна быть на 100% внутри круга. Смотрите второе изображение. Смотрите плитку внизу в центре. Плитка слегка выступает из круга, но изображение 50х50 все еще может поместиться внутри плитки.
Пожалуйста, смотрите функцию ниже, которая размещает X внутри каждой сетки.
public function placeImages()
{
$boxes = 5;
$circumference = 700;
$width = ($circumference / $boxes);
$this->grid = array(
array(
'width' =>
array(
'x1' => 0,
'y1' => 0,
'x2' => 700,
'y2' => 0,
),
'height' =>
array(
'x1' => 0,
'y1' => 0,
'x2' => 0,
'y2' => 700,
),
),
array(
'width' =>
array(
'x1' => 0,
'y1' => 140,
'x2' => 700,
'y2' => 140,
),
'height' =>
array(
'x1' => 140,
'y1' => 0,
'x2' => 140,
'y2' => 700,
),
),
array(
'width' =>
array(
'x1' => 0,
'y1' => 280,
'x2' => 700,
'y2' => 280,
),
'height' =>
array(
'x1' => 280,
'y1' => 0,
'x2' => 280,
'y2' => 700,
),
),
array(
'width' =>
array(
'x1' => 0,
'y1' => 420,
'x2' => 700,
'y2' => 420,
),
'height' =>
array(
'x1' => 420,
'y1' => 0,
'x2' => 420,
'y2' => 700,
),
),
array(
'width' =>
array(
'x1' => 0,
'y1' => 560,
'x2' => 700,
'y2' => 560,
),
'height' =>
array(
'x1' => 560,
'y1' => 0,
'x2' => 560,
'y2' => 700,
),
),
array(
'width' =>
array(
'x1' => 0,
'y1' => 700,
'x2' => 700,
'y2' => 700,
),
'height' =>
array(
'x1' => 700,
'y1' => 0,
'x2' => 700,
'y2' => 700,
),
),
);
//This removes the grid item for the bottom and right lines, not needed within the loop.
array_pop($this->grid);
foreach ($this->grid as $grid) {
$x = $grid['width']['x1'];
$y = $grid['width']['y1'];
for ($j = 0; $j < $boxes; $j++) {
$this->drawLine($x, $y, ($x + $width), ($y + $width), '#ff3200');
$this->drawLine(($x + $width), $y, $x, ($y + $width), '#ff3200');
//50 × 50 = Image size
$imageX = floor($x + ($width - 50) / 2);
$imageY = floor($y + ($width - 50) / 2);;$image = Image::make(base_path('test.png'))->opacity(50);
$this->image->insert($image, 'top-left', $imageX, $imageY);
$x = $x + $width;
}
}
}
Приведенный выше код является упрощенной версией моей программы. Массив сетки генерируется динамически, но я не думаю, что это имеет значение для этого вопроса.
Это уравнение удовлетворяет всякий раз, когда точка находится внутри круга:
(x — center_x) ^ 2 + (y — center_y) ^ 2 < радиус ^ 2
Поэтому вы должны проверить это перед вставкой изображения.
Для всех углов вы должны отметить только один из них, в зависимости от того, на какой четверти графика вы находитесь. е. верхняя правая четверть, image_x будет $ x, image_y будет $ y (без учета ширины и деления на 2). Для нижней левой четверти — $ x, $ -y.
Более подробно, проверка границ. Учитывая, что круг расположен в точке (0,0) и имеет радиус 700:
$bounding_x = $x;
$bounding_y = $y;
if($x > 0)
$bounding_x += width;
if($x < 0)
$bounding_x -= width;
if($y > 0)
$bounding_y += width;
if($y < 0)
$bounding_y -= width;
if ($bounding_x*$bounding_x + $bounding_y*$bounding_y < 490000)
//....insert image
Основная теория для определения, находится ли квадрат внутри круга, состоит в проверке, все ли его четыре угла попадают в круг. Это верно как для ваших плиток, так и для заполнителей изображений.
Свойства круга
Вам нужно сначала найти радиус (r) и центр (cx, cy). Если мы считаем, что ваш верхний правый угол равен (0, 0), то:
radius = circumference / (pi * 2) //considering 2(pi)r = circumference
cx, cy = (r, -r) //your center is r away from the top-right
обнаружения
Теперь вы должны пройти через ваш массив и посмотреть, все ли углы всех плиток попадают в круг. Давайте посмотрим, как определить, попадает ли одна точка в круг.
function withinCircle(x, y) {
return ((r - x)*(r - x) + (y - r)*(y - r) < r * r) ;
}
Функция проверяет, если x
или же y
координата точки находится вне радиуса. То, что ваш круг находится в диапазоне 270-360 от плоскости, считается признаком.
Вы можете проверить, находятся ли углы квадратов внутри круга.
если одна вершина квадрата равна (a, b),
Вы не сможете построить это sqrt (a ^ 2 + b ^ 2)> радиус.
Предполагается, что центр круга имеет координаты (0,0), если это не так, а круг имеет координаты (x, y), нам нужно переместить все точки на (-x, -y), в этом случае тест:
sqrt ((a-x) ^ 2 + (b-y) ^ 2)> радиус.
Я предполагаю, что круг определяется ограничительной рамкой (0,0)->(2r,2r)
и пусть квадрат будет (x1,y1)->(x2,y2)
,
Эффективный способ выполнить тест — проверить, что самый дальний от центра угол находится внутри круга.
if (x1 < r) dx= r - x1; else dx= x2 - r;
if (y1 < r) dy= r - y1; else dy= y2 - r;
if dx * dx + dy * dy <= r * r
// Wholly inside