Сообщество Engee

Новогодняя ёлка

Автор
avatar-artpgchartpgch
Notebook

Алгоритм генерации фигуры на примере новогодней ёлки

Введение

В данном примере представлен алгоритм генерации фрактальной структуры с применением стохастического распределения точек и визуализацией на примере новогодней ёлки.

Присоединим необходимые библиотеки. В качестве графической основы используем библиотеку CairoMakie.

In [ ]:
#import Pkg 
#Pkg.add(["Random" ,"LinearAlgebra", "Colors", "FreeTypeAbstraction", "CairoMakie"])
using Random, LinearAlgebra, Colors, FreeTypeAbstraction
import CairoMakie as CM

Определим параметры фигуры.

In [ ]:
CM.set_theme!()
Random.seed!(123)
количество_точек = 6^5
количество_украшений = 50
типы_украшений = rand(1:6, количество_украшений)
индексы_украшений = randperm(количество_точек)[1:количество_украшений]

случайное_число() = rand(количество_точек)
углы = случайное_число() .* 2π
высоты = случайное_число()
радиусы = 0.4 .* (1 .- высоты)
плотность = случайное_число()
координаты_x = радиусы .* cos.(углы)
координаты_y = радиусы .* sin.(углы)

цвета_украшений = [
    CM.RGBf(1, 0, 0),
    CM.RGBf(1, 1, 0),
    CM.RGBf(1, 0, 1),
    CM.RGBf(0, 0, 1),
    CM.RGBf(0.5, 0.5, 0.5),
    CM.RGBf(0, 1, 1)
]
маркеры_украшений = [:circle, :star5, :diamond, :utriangle, :hexagon, :cross]

Отобразим фигуру в виде ёлки.

In [ ]:
ёлка = CM.Figure(backgroundcolor=CM.RGBf(0, 0, 0), size=(500, 500))
ось = CM.Axis3(ёлка[1, 1], aspect=:data, viewmode=:stretch, limits=(-0.6, 0.6, -0.6, 0.6, -0.15, 1.1), azimuth=0.0, elevation=0.0, title="")
CM.hidedecorations!(ось)
CM.hidespines!(ось)
цвета_ёлки = [CM.RGBAf(0, плотность[i]*радиусы[i]^0.45, 0, 0.97) for i in 1:количество_точек]
CM.scatter!(ось, координаты_x .* плотность, координаты_y .* плотность, высоты,
    color=цвета_ёлки,
    markersize=5,
    marker=:circle)

for i in 1:6
    индексы = индексы_украшений[типы_украшений .== i]
    if !isempty(индексы)
        CM.scatter!(ось, координаты_x[индексы], координаты_y[индексы], высоты[индексы], color=цвета_украшений[i], markersize=15, marker=маркеры_украшений[i], strokewidth=2, strokecolor=:white)
    end
end

CM.scatter!(ось, [0], [0], [1.05], color=CM.RGBf(1, 0, 0), markersize=35, marker=:star5, strokewidth=3, strokecolor=CM.RGBf(1, 1, 0.5))

количество_точек_ствола = 350
координаты_ствола_x = Float64[]
координаты_ствола_y = Float64[]
координаты_ствола_z = Float64[]

радиус_ствола = 0.025
for i in 1:количество_точек_ствола
    z = -0.1 + rand() * 0.12
    θ = rand() * 2π
    r = радиус_ствола * (0.7 + 0.6 * rand())
    push!(координаты_ствола_x, r * cos(θ))
    push!(координаты_ствола_y, r * sin(θ))
    push!(координаты_ствола_z, z)
end

CM.scatter!(ось, координаты_ствола_x, координаты_ствола_y, координаты_ствола_z,
    color=CM.RGBf(0.4, 0.25, 0.1),
    markersize=10,
    marker=:circle)

количество_снежинок = 250
координаты_снежинок_x = Float64[]
координаты_снежинок_y = Float64[]
координаты_снежинок_z = Float64[]
размеры_снежинок = Float64[]

for i in 1:количество_снежинок
    push!(координаты_снежинок_x, -1.0 + rand() * 2.0)
    push!(координаты_снежинок_y, -1.0 + rand() * 2.0)
    push!(координаты_снежинок_z, -0.2 + rand() * 1.4)
    push!(размеры_снежинок, 3 + rand() * 8)
end

цвета_снежинок = [CM.RGBAf(1, 1, 1, 0.8) for _ in 1:количество_снежинок]
CM.scatter!(ось, координаты_снежинок_x, координаты_снежинок_y, координаты_снежинок_z,
    color=цвета_снежинок,
    markersize=размеры_снежинок,
    marker=:circle)

CM.display(ёлка)
No description has been provided for this image
Out[0]:
CairoMakie.Screen{IMAGE}

Заключение

В результате выполнения скрипта появляется изображение ёлки с украшениями, окружённой хлопьями снега. Таким образом можно убедиться в том, графический дизайн возможно осуществить не только используя специализированное программное обеспечение, но и создавая скрипты в Engee.