Как я могу (несколько) равномерно распределить SVG-фигуры динамического размера внутри холста? - PullRequest
1 голос
/ 27 декабря 2011

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

Это веб-страница, которая будет содержать холст SVG (размером 920px W x 450px H), содержащий 20-40 «круглых» изображений (то есть они могут быть просто квадратными изображениями, обрезанными кружком). Размер изображений, вероятно, будет варьироваться от около 50 до около 200 пикселей в диаметре, каждое из которых будет динамически устанавливаться в этом диапазоне на основе данных из API. Это в основном динамическая визуализация данных, поэтому практически все ее аспекты должны быть настраиваемыми / динамическими.

Я думаю, что самой сложной проблемой является то, как распределить эти изображения в пределах заданной области холста, учитывая, что они будут различаться по размеру и должны казаться равномерно / случайным образом распределенными (т. Е. Они не должны совпадать с сетка, быть сгруппированы вместе, или быть в группах одинаковых размеров). Это нормально, если они слегка перекрываются. Вот быстрый набросок того, как это должно выглядеть в идеале (каждый серый кружок представляет изображение):

https://skitch.com/troywarr/gwj14/adobe-fireworks-cs5

FWIW, я планировал использовать Raphaël в качестве библиотеки SVG; У меня также будет jQuery , и, возможно, я могу использовать любые другие библиотеки по мере необходимости. Это должно быть кросс-браузерной совместимостью обратно с IE7.

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

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 31 января 2012

Вот как бы я занялся этим:

Сначала определите процент экрана, который будет заполнен кружками, и количество отображаемых кружков. Вы можете использовать это для определения среднего радиуса каждого круга, используя площадь формулы круга - например, учитывая x кругов, каким должен быть средний радиус всех кругов, чтобы покрыть y% моего контейнера. Затем вы можете решить, насколько вы хотите, чтобы радиус изменялся, то есть +/- 50%. Если количество кругов не очень мало, вы должны получить хороший результат - статистически, то есть.

Тогда я бы разделил экран на прямоугольную сетку - я знаю, что это не то, что вы хотите, просто будьте терпеливы :) Размеры сетки рассчитываются по количеству кругов, например. 16 кругов будут хорошо вписываться в сетку 4х4. Количество кружков может быть меньше количества ячеек, но не намного меньше.

Я бы тогда выбрал случайную координату x, y внутри каждой ячейки сетки в качестве центра моего круга. Я бы также оставил отступ около 25% по краям, чтобы мой круг не находился слишком близко к краю.

Затем вы можете проверить наложение - отношение (r1 + r2) / расстояния между центральными точками окружности будет равно 1, если круги касаются, будет меньше 1, если они не совпадают, и больше 1, если они перекрываются. Соотношение 1,1 является небольшим совпадением; соблюдайте ограничение здесь - точно такие же центры приводят к расстоянию 0 и ошибке деления на 0.

Одна вещь, о которой следует беспокоиться, но этого не должно произойти, если вы не выберете очень высокий начальный процент покрытия или число, если число кружков намного меньше числа ячеек. Если у всех ячеек, смежных с данной ячейкой, есть круги, близкие к краям этих ячеек, особенно если они перекрывают край, может не хватить места (даже с перекрытием круга) для круга текущей ячейки. Это можно проверить и обработать, уменьшив радиус или отодвинув круг ...

ПРИМЕЧАНИЕ: если количество желаемых кругов не совсем соответствует вашей квадратной (или прямоугольной) сетке, просто случайно оставьте некоторые ячейки пустыми ...

1 голос
/ 17 марта 2014

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

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

Я встроил множество «факторов выдумки» - границы радиуса круга, смещение от центра, максимальное перекрытие с соседними ячейками и т. Д. - но, как бы я ни настраивал свои настройки, вы все равно всегда могли сказать, что сетка была за макетом; круги выровнены настолько, что выглядят скорее как шаткий узор в горошек, а не как действительно случайная коллекция кругов.

Итак, я перешел на более грубый подход.

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

Затем я применил свою математику для определения размера кругов по мере необходимости (короче говоря, самые большие круги представляли значение 100%, а самые маленькие представляли значение 0%; остальные размеры были соответственно изменены в зависимости от того, где они попали в спектр. ).

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

  1. Поместите круг в случайные координаты.
  2. Поместите следующий круг в случайные координаты.
  3. Если последний круг перекрывает первый более чем на X пикселей (настраиваемый параметр), поместите его в новый набор случайных координат.
  4. Продолжайте шаг # 3 до Y раз (еще один настраиваемый параметр), пока вы не поместите еще один круг.
  5. Если вы не можете поместить круг в Y раз, очистите холст, уменьшите максимальный радиус круга на Z пикселей (еще один настраиваемый параметр) и начните сначала.

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

Вы можете увидеть готовый продукт здесь:

http://www.eonline.com/news/2012_sag_awards/heatgauge

Вне сезона, поэтому перейдите на вкладку «Общий вид» в верхней части основного окна, чтобы увидеть совокупную статистику (и, следовательно, полный холст кругов).

...