Skip to content

Commit

Permalink
🔨 feat(lib): Working interpolation
Browse files Browse the repository at this point in the history
TODO: work on edge cases and formatting
  • Loading branch information
worthant committed Nov 12, 2024
1 parent d28627f commit 2c3a5a3
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 12 deletions.
2 changes: 2 additions & 0 deletions lib/cli.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ defmodule InterpolationCli.CLI do
end

defp read_input do
# IO.write("> ")

case IO.gets("") do
:eof ->
:ok
Expand Down
7 changes: 3 additions & 4 deletions lib/input_handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ defmodule InterpolationCli.InputHandler do
def handle_cast({:add_point, point}, state) do
new_state = [point | state] |> Enum.sort_by(fn {x, _y} -> x end)

# Проверяем, есть ли достаточно точек для интерполяции
# Передаём последние две точки для интерполяции
if length(new_state) >= 2 do
# Отправляем последние две точки для линейной интерполяции
[p1, p2 | _] = new_state
InterpolationCli.LinearInterpolator.interpolate([p1, p2])
last_two_points = Enum.take(new_state, -2)
InterpolationCli.LinearInterpolator.interpolate(last_two_points)
end

{:noreply, new_state}
Expand Down
25 changes: 20 additions & 5 deletions lib/linear_interpolator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,29 @@ defmodule InterpolationCli.LinearInterpolator do
end

@impl true
def handle_cast({:interpolate, [{x1, y1}, {x2, y2}]}, frequency) do
# Генерируем промежуточные точки
step = (x2 - x1) / frequency
xs = Enum.map(0..frequency, fn i -> x1 + i * step end)
def handle_cast({:interpolate, points}, frequency) do
# Получаем последние две точки для интерполяции
[{x1, y1}, {x2, y2}] = Enum.take(points, -2)

# Шаг интерполяции
step = 1.0

# Диапазон интерполяции от x1 до x2 с заданным шагом
xs = Stream.iterate(x1, &(&1 + step)) |> Enum.take_while(&(&1 <= x2 + step))
ys = Enum.map(xs, fn x -> y1 + (y2 - y1) / (x2 - x1) * (x - x1) end)
results = Enum.zip(xs, ys)
# Отправляем результаты в OutputHandler

# Форматированный вывод диапазона с округлением
range_start = Float.round(x1, 2)
range_end = Float.round(x2 + step, 2)

IO.puts("")
IO.puts(
"Линейная (идем от точки #{range_start} с шагом #{step}, покрывая все введенные X (#{range_end} < #{Float.round(x2, 2)})):"
)

InterpolationCli.OutputHandler.output(results)

{:noreply, frequency}
end

Expand Down
10 changes: 7 additions & 3 deletions lib/output_handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ defmodule InterpolationCli.OutputHandler do

@impl true
def handle_cast({:output, results}, state) do
Enum.each(results, fn {x, y} ->
IO.puts("#{Float.round(x, 3)}\t#{Float.round(y, 3)}")
end)
xs = Enum.map_join(results, "\t", fn {x, _} -> Float.round(x, 2) end)
ys = Enum.map_join(results, "\t", fn {_, y} -> Float.round(y, 2) end)

# Вывод X и Y координат
IO.puts(xs)
IO.puts(ys)
IO.puts("")

{:noreply, state}
end
Expand Down

0 comments on commit 2c3a5a3

Please sign in to comment.