Расположение квадратов на круге с минимальным диаметром

Данные n квадраты с граничной длиной l, как я могу определить минимальный радиус r круга так, чтобы я мог распределить все квадраты равномерно вдоль периметра круга без них наложение? (Ограничение: первый квадрат будет всегда располагаться в 12 часов.)

Последующий вопрос: как я могу поместить n идентичные прямоугольники с высотой h и шириной w?

example
(источник: n3rd.org)

18
задан Glorfindel 3 August 2019 в 07:08
поделиться

6 ответов

Может существовать математически хитрый способ сделать это, но я бы не знал. Я думаю, что это немного усложняется тем фактом, что геометрия различается для каждого количества квадратов; для 4 это ромб, для 5 это пятиугольник и так далее.

Я бы поместил эти квадраты на круг размером 1 единицу (слишком маленький, я знаю, несите меня), распределенный на нем поровну. Это достаточно просто, просто разделите (разделите) ваши 360 градусов на количество квадратов. Затем просто проверьте все свои квадраты на перекрытие со своими соседями; если они перекрываются, увеличьте радиус.

Вы можете сделать эту процедуру менее глупой, чем кажется, используя интеллектуальный алгоритм для достижения нужного размера. Я думаю о чем-то вроде алгоритма Ньютона: учитывая два последовательных предположения, одно из которых слишком мало, а другое слишком велико, ваше следующее предположение должно быть средним из этих двух.

Вы можете выполнять итерацию с любой точностью. Остановитесь, когда расстояние между предположениями меньше некоторой произвольной небольшой погрешности.

РЕДАКТИРОВАТЬ У меня есть решение получше:

Я думал о том, что сказать вам, если вы спросите: «Как я узнаю, перекрываются ли квадраты?» Это дало мне представление о том, как точно рассчитать размер круга за один шаг:

Поместите квадраты на слишком маленький круг. Вы знаете, как: вычислите точки на окружности, в которых ваши углы 360 / n пересекают ее, и поместите туда центр квадрата. На самом деле, вам пока не нужно размещать квадраты, для следующих шагов нужны только средние точки.

Чтобы вычислить минимальное расстояние квадрата до его соседа: Вычислите разность по X и разность по Y средних точек и возьмите их минимум. X и Y на самом деле просто косинусы и синусы на окружности.

Вам понадобится минимум любой квадрат против своего соседа (скажем, по часовой стрелке). Поэтому вам нужно обойти круг, чтобы найти самый маленький.

Минимальное (X или Y) расстояние между квадратами должно быть 1,0. Так что просто возьмите величину, обратную минимальному расстоянию, и умножьте на это размер круга. Престо, твой круг правильного размера.

РЕДАКТИРОВАТЬ

Не теряя общности, я думаю, что можно немного усовершенствовать свое решение, чтобы оно было близко к кодированию. Вот уточнение:

  • Предположим, что квадраты имеют размер 1, т.е. каждая сторона имеет длину 1 единицу. В конце концов, ваши коробки наверняка будут больше 1 пикселя, но это всего лишь вопрос масштабирования.
  • Избавьтесь от крайних случаев:

     if (n <2) throw new IllegalArgumentException ();
    если (n == 2) вернуть 0,5; // 2 квадрата точно уместятся на окружности радиуса 0.5
    
  • Начните с круга размером r 0,5, который наверняка будет слишком маленьким для любого количества квадратов> 2.

     r = 0,5;
    dmin = 1,0; // начинаем предполагать, что минимальное расстояние в порядке
    a = 2 * PI / n;
    for (p1 = 0.0; p1 <= PI; p1 + = a) {// начиная с угла 0, пробуем все точки до середины
     // (да, мы начинаем восток, а не север. не имеет значения)
    р2 = р1 + а; // следующая точка на окружности
    dx = abs (r * cos (p2) - r * cos (p1))
    dy = abs (r * sin (p2) - r * sin (p1))
    dmin = min (dmin, dx, dy)
    }
    r = r / dmin;
    

РЕДАКТИРОВАТЬ

Я превратил это в настоящий Java-код и получил для запуска нечто очень похожее на это. Код и результаты здесь: http://ideone.com/r9aiu

Я создал графический вывод с помощью GnuPlot. Мне удалось создать простые диаграммы прямоугольников, расположенных по кругу, путем вырезания и вставки наборов точек из вывода в файл данных, а затем запуска

plot '5.dat' with boxxyerrorbars

.5 в файле serve размер ящиков ... ленивое, но рабочее решение. 0,5 применяется к обеим сторонам от центра, поэтому коробки в конечном итоге имеют размер 1,0.

Увы, мой алгоритм не работает . Это делает радиусы слишком большими, поэтому коробки располагаются намного дальше друг от друга, чем необходимо. Даже уменьшение в 2 раза (в некоторых местах могло быть ошибкой использование 0,5) не помогло.

Простите, я сдаюсь. Может быть, мой подход можно спасти, но он работает не так, как я, хотя мог бы. : (


РЕДАКТИРОВАТЬ

Ненавижу сдаваться.Я собирался оставить свой компьютер, когда подумал о способе спасти свой алгоритм:

Алгоритм регулировал меньшее расстояний X или Y, чтобы оно было не менее 1. Это легко продемонстрировать. просто глупо.Когда у вас много ящиков, то на восточном и западном краях круга у вас есть ящики, уложенные почти прямо друг на друга, причем их X очень близко друг к другу, но они защищены от соприкосновения за счет наличия достаточного расстояния Y между их.

Итак ... чтобы выполнить эту работу, вы должны масштабировать максимум dx и dy так, чтобы (для всех случаев) как минимум радиус (или это был двойной радиус?).

Исправленный код находится здесь: http://ideone.com/EQ03g http://ideone.com/VRyyo

Повторно протестирован в GnuPlot, он создает красивые маленькие кружочки прямоугольников, где иногда просто 1 или 2 коробки ровно соприкасаются. Проблема решена! :)

(Эти изображения шире, чем высокие, потому что GnuPlot не знал, что мне нужен пропорциональный макет. Только представьте, что все работы сжаты в квадратную форму :))

12
ответ дан 30 November 2019 в 09:11
поделиться

Я бы вычислил верхнюю границу минимального радиуса, работая с кругами, охватывающими квадраты, вместо самих квадратов.

Мои результаты вычислений:

Rmin <= X / (sqrt (2) * sin (180 / N))

Где: X - длина стороны квадрата, а N - необходимое количество квадратов.

Я предполагаю, что круги расположены так, что их центры попадают на окружность большого круга.

- РЕДАКТИРОВАТЬ -

Используя идею Дэйва в комментарии ниже, мы также можем вычислить хорошую нижнюю границу, считая, что круги находятся внутри квадратов (таким образом, имея радиус X / 2). Эта граница:

Rmin> = X / (2 * sin (180 / N))

4
ответ дан 30 November 2019 в 09:11
поделиться

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

И, что касается вашего последующего вопроса: Я предлагаю вам решить задачу для квадратов с длиной стороны min(h,w) на окружности, затем преобразовать квадраты в прямоугольники, а окружность в эллипс с эксцентриситетом h/w (или w/h).

1
ответ дан 30 November 2019 в 09:11
поделиться

Я бы решил ее так:

Чтобы найти связь между радиусом r и длиной l, давайте проанализируем безразмерное представление

  • возьмем центры на окружности (x1,y1)...(xn,yn)
  • из каждого центра возьмем нижний правый угол i-го квадрата и верхний левый угол i+1-го квадрата
  • две точки должны иметь либо равные x, либо равные y, в зависимости от того, что дает меньший l
  • процедура должна быть повторена для каждого центра, и тот, который дает наименьший l, является окончательным решением.

Это оптимальное решение, которое можно решить в терминах r = f(l). Решение может быть адаптировано к прямоугольникам путем корректировки формул для xLR[i] и yUL[i+1].

Постараюсь дать некоторый псевдокод.

EDIT:
. В процедуре есть ошибка, нижний правый и верхний левый не являются необходимыми ближайшими точками для двух соседних квадратов/прямоугольников.

0
ответ дан 30 November 2019 в 09:11
поделиться

Предположим, вы решили задачу для 3 или 4 квадратов.

Если у вас есть n > = 5 квадратов, и вы поместите один квадрат вверху круга, у вас будет другой квадрат, который попадет в первый квадрант декартовой плоскости, концентричной с вашим кругом.

Задача состоит в том, чтобы найти такой радиус r для круга, чтобы левая сторона круга рядом с верхним кругом и правая сторона верхнего круга не пересекались друг с другом. .

Координата x правой стороны верхнего круга равна x1 = L / 2, где L - сторона квадрата.Координата x левой стороны окружности рядом с верхней составляет x2 = r cos a - L / 2, где r - радиус, а a - угол между каждой парой квадратных центров ( a = 360 / n градусов).

Итак, нам нужно решить x1 <= x2 , что приводит к

r > = L / cos a .

L и a известны, так что мы закончили: -)

0
ответ дан 30 November 2019 в 09:11
поделиться

Вы начинаете с произвольного круга (например, с диаметром (* n l) ) и равномерно размещаете квадраты по окружности.Затем вы проходите через каждую пару соседних квадратов и:

  • вычисляете прямую, соединяющую их средние точки,
  • вычисляете пересечение этой линии со сторонами промежуточных квадратов (M1 и M2 - средние точки, S1 и S2 - соответствующие пересечения со стороной квадрата:

      S2 S1
    M1 -------------- * ---------- * --------------- M2
    
    ------------------------
    | |
    | |
    | |
    | |
    | M1 |
    | \ |
    | \ |
    | ------- * ------- + --------
    | | \ | |
    | | \ | |
    ------- + --------- * ------ |
     | \ |
     | M2 |
     | |
     | |
     | |
     | |
     -------------------------
    
  • вычислите масштабный коэффициент, необходимый для того, чтобы S1 и S2 упали вместе (просто отношение суммы M1-S1 и S2-M2 к M1-M2), и

, наконец, масштабируйте круг на максимум найденные масштабные коэффициенты.

Редактировать: Это точное решение. Тем не менее, немного подумав, можно еще оптимизировать это для скорости:

  • Вам нужно сделать это только для квадратов, ближайших к 45 ° (если n четное), соответственно. 45 ° и 135 ° (если n нечетное; на самом деле, вы можете доказать, что необходим только один из них).
  • Для больших n оптимальное расстояние между квадратами на окружности быстро приближается к длине диагонали квадрата. Таким образом, вы можете предварительно вычислить масштабные коэффициенты для нескольких малых n (до дюжины или около того), а затем получить достаточно хорошее приближение с диагональю.
0
ответ дан 30 November 2019 в 09:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: