Интерактивная визуализация действия линейного оператора
Автор
using Stipple, Stipple.ReactiveTools, StippleUI, PlotlyBase, GenieFramework
# Создание круга как набора точек
const circ_range = -1:0.05:1
const circle = [[i, j] for i in circ_range for j in circ_range if i^2 + j^2 <= 1]
const x_axis_points = findall(x -> x[1] == 0 && x[2] >= 0, circle)
const y_axis_points = findall(x -> x[2] == 0 && x[1] >= 0, circle)
const circle_matrix = Base.stack(circle)
# Функция для создания данных графика
function create_plot_data(m11::Float64, m12::Float64, m21::Float64, m22::Float64)
transformed = [m11 m12; m21 m22] * circle_matrix
[
scatter(x=transformed[1, :], y=transformed[2, :], mode="markers", name="Точки круга"),
scatter(x=transformed[1, x_axis_points], y=transformed[2, x_axis_points], name="Ось Y"),
scatter(x=transformed[1, y_axis_points], y=transformed[2, y_axis_points], name="Ось X", aspect_ratio=:equal)
]
end
# Начальные данные графика
const initial_plot_data = create_plot_data(1.0, 0.0, 0.0, 1.0)
# Макет графика
const plot_layout = PlotlyBase.Layout(
title="Линейное преобразование круга",
xaxis=attr(title="Ось X", showgrid=true, range=[-2, 2]),
yaxis=attr(title="Ось Y", showgrid=true, range=[-2, 2]),
width=600, height=550
)
# Определение приложения
@app begin
@in m11 = 1.0
@in m12 = 0.0
@in m21 = 0.0
@in m22 = 1.0
@out plot_data = initial_plot_data
@out plot_layout = plot_layout
@onchange m11, m12, m21, m22 begin
plot_data = create_plot_data(m11, m12, m21, m22)
end
end
# Пользовательский интерфейс
function ui()
sliders = [row([column([h6("m$(i)$(j)={{m$(i)$(j)}}"), slider(-2:0.1:2, Symbol("m$(i)$(j)"), color="purple")], size=3) for j in 1:2]) for i in 1:2]
[
row([
column(sliders, size=4),
column(plot(:plot_data, layout=:plot_layout))
], size=3)
]
end
@page("/", ui)