Hacker News Digest

02 сентября 2025 г. в 17:32 • blog.adacore.com • ⭐ 179 • 💬 45

OriginalHN

#ada#gnat#svg#command-line#embedded-systems#mathematics#alire#adacore#hypotrochoid#xml

Introduction to Ada: a project-based exploration with rosettas

Ada в действии: рисуем розетки

Создадим консольную утилиту, генерирующую SVG-файл с анимированными розетками (гипотрохоидами, как в Spirograph™). Проект показывает, что Ada 2022 — не только для безопасно-критичных систем, но и для обычных задач.

Зачем Ada?

  • Жёсткая проверка типов и компилятор как «партнёр».
  • Читаемость вместо краткости, минимум неопределённого поведения.
  • Отлично подходит для встраиваемых, авиа-, железнодорожных и автомобильных систем.

Как работает программа

  1. Принимает параметры из командной строки.
  2. Вычисляет координаты точек кривой.
  3. Записывает XML-совместимый SVG.
  4. Открывается в любом браузере без сторонних библиотек.

Структура проекта

rosetta/
├── alire.toml          # зависимости Alire
├── src/
│   ├── rosetta.adb     # точка входа
│   ├── svg.adb/.ads  # генерация SVG
│   ├── curve.adb/.ads # математика кривой
└── Makefile

Ключевые типы

type Point is record
   X, Y : Float;
end record;

type Rosetta_Params is record
   R, r, d : Float;  -- радиусы и смещение
   Steps   : Positive;
end record;

Генерация кривой

function Hypotrochoid(P : Rosetta_Params) return Point_Array is
   Result : Point_Array(1 .. P.Steps);
   Angle  : Float := 0.0;
   Delta  : constant Float := 2.0 * Pi / Float(P.Steps);
begin
   for I in Result'Range loop
      Result(I) := (
        X => (P.R - P.r) * Cos(Angle) + P.d * Cos((P.R - P.r) / P.r * Angle),
        Y => (P.R - P.r) * Sin(Angle) - P.d * Sin((P.R - P.r) / P.r * Angle)
      );
      Angle := Angle + Delta;
   end loop;
   return Result;
end Hypotrochoid;

Создание SVG

procedure Write_SVG(Path : Point_Array; Filename : String) is
   File : File_Type;
begin
   Create(File, Out_File, Filename);
   Put_Line(File, "<svg ...>");
   Put(File, "<path d='M");
   for P of Path loop
      Put(File, Float'Image(P.X) & "," & Float'Image(P.Y) & " ");
   end loop;
   Put_Line(File, "' stroke='black' fill='none'/>");
   Put_Line(File, "</svg>");
   Close(File);
end Write_SVG;

Сборка и запуск

alr build
./bin/rosetta --R 100 --r 40 --d 80 --steps 360
# открыть rosetta.svg в браузере

Что дальше

  • Добавить CLI-парсер GNAT.Command_Line.
  • Анимировать через <animate> в SVG.
  • Портировать на микроконтроллер и выводить на дисплей.

Полный код: github.com/AdaCore/rosetta-ada-demo