(Почти) Автогенерация цветов

Приближалось восьмое марта, у меня была реализация автоматизированной отрисовки поверхностей сплайнами — почему бы не написать статью с цветами.

Получилось примерно так:

4zlpb97gt-hhkukup9zzzjh8_nq.png

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

orkhboybs3zk-9jclqrafcphfuq.png

(в конце должно быть так:)

noxjz7r33lwfieth6g-grmq11kq.png

Чтобы кубические поверхности при натяжении на остов были похожи на цветок, надо расположить точки симметрично, на окружностях, описанных вокруг центра цветка. Для решения этой задачи была применена вариация «поиска в ширину».

Присвоим всем точкам веса. Сначала крайним точкам присвоим веса 0 и 1 (два одинаковых веса не должны стоять рядом). Это будут края «лепестков», 0 — дальние, 1 — ближние («лепестки» в кавычках, потому что как такового разделения на лепестки здесь нет). Взвешиваем дальше, присваивая вес n+2 невзвешенным соседям с весом n.

Взвешенный ящик:

xpovsauczlj_osjlvt6wzkt3k5m.png

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

$r_0 > r_2 > r_4> … > r_{2n};\ \ r_1 > r_3 > … > r_{2n+1};\ \ r_0 > r_1$» /></p>

<p><br />где r — расстояние от центра цветка до точек с соответствующим весом. Четные веса отвечают за центральную часть «лепестка», нечетные — за края «лепестка».</p>

<p>Для того, чтобы располагать точки на окружностях (а не на сферах), нам так же придется случайным образом выбрать z-координаты таким образом, что z_n < r_n (если центр цветка в координатном нуле).</p>

<p><img src=

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

$если\ m_n - количество\ точек\ с\ весом\ n, то\ \alpha_n = 2\cdot \pi/m_n$


и далее координаты для i-й точки веса n, если он четный:

$x_i = \sqrt{r_n^2-z_n^2}\cdot cos(i\alpha_n)$

$y_i = \sqrt{r_n^2-z_n^2}\cdot sin(i\alpha_n)$


для нечетного:

$x_i = \sqrt{r_n^2-z_n^2}\cdot cos(i\alpha_n+\alpha_n/2)$

$y_i = \sqrt{r_n^2-z_n^2}\cdot sin(i\alpha_n+\alpha_n/2)$


Кроме того, важен порядок, в котором мы берем точки — они должны быть «соседями».

j4qccwgdkfkzckddlzjxihpn_pa.png

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

(вид сверху, изометрия, сплайны)

bfk3jqe5jsp15lsacxmp0rkc4za.png

szkb6_2fkwl8erz3svi31is5_ic.png

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

(вид ПО для сборки)

h0h8arqmhym78t82grbgaj2doz4.png

j2lxu2tqilsyew5uha5-eyozcbc.png

26eevfti1ocozz0qew5zovhqj_o.png

1m1hh10fabwhphse_xmhmf6ekqo.png

hlwysxm-kdikwbm07yr3eimk18m.png

r6wta6i7kqin2g6w8qq0cbb_nww.png

Поздравляю с международным женским днем прекрасную половину хабрасообщества! Надеюсь, вам было красиво.

© Habrahabr.ru