Task: Koch curve


C++: 
#include <fstream>
#include <iostream>
#include <vector>

constexpr double sqrt3_2 = 0.86602540378444; 

struct point {
    double x;
    double y;
};

std::vector<point> koch_next(const std::vector<point>& points) {
    size_t size = points.size();
    std::vector<point> output(4*(size - 1) + 1);
    double x0, y0, x1, y1;
    size_t j = 0;
    for (size_t i = 0; i + 1 < size; ++i) {
        x0 = points[i].x;
        y0 = points[i].y;
        x1 = points[i + 1].x;
        y1 = points[i + 1].y;
        double dy = y1 - y0;
        double dx = x1 - x0;
        output[j++] = {x0, y0};
        output[j++] = {x0 + dx/3, y0 + dy/3};
        output[j++] = {x0 + dx/2 - dy * sqrt3_2/3, y0 + dy/2 + dx * sqrt3_2/3};
        output[j++] = {x0 + 2 * dx/3, y0 + 2 * dy/3};
    }
    output[j] = {x1, y1};
    return output;
}

std::vector<point> koch_points(int size, int iterations) {
    double length = size * sqrt3_2 * 0.95;
    double x = (size - length)/2;
    double y = size/2 - length * sqrt3_2/3;
    std::vector<point> points{
        {x, y},
        {x + length/2, y + length * sqrt3_2},
        {x + length, y},
        {x, y}
    };
    for (int i = 0; i < iterations; ++i)
        points = koch_next(points);
    return points;
}

void koch_curve_svg(std::ostream& out, int size, int iterations) {
    out << "<svg xmlns='http:
        << size << "' height='" << size << "'>\n";
    out << "<rect width='100%' height='100%' fill='black'/>\n";
    out << "<path stroke-width='1' stroke='white' fill='none' d='";
    auto points(koch_points(size, iterations));
    for (size_t i = 0, n = points.size(); i < n; ++i)
        out << (i == 0 ? "M" : "L") << points[i].x << ',' << points[i].y << '\n';
    out << "z'/>\n</svg>\n";
}

int main() {
    std::ofstream out("koch_curve.svg");
    if (!out) {
        std::cerr << "Cannot open output file\n";
        return EXIT_FAILURE;
    }
    koch_curve_svg(out, 600, 5);
    return EXIT_SUCCESS;
}










Ada: with Ada.Command_Line;
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Text_IO;
with PDF_Out;

procedure Koch_Curve is

   package Real_Math is
     new Ada.Numerics.Generic_Elementary_Functions (PDF_Out.Real);
   use Real_Math, PDF_Out, Ada.Command_Line, Ada.Text_IO;

   subtype Angle_Deg  is Real;
   type    Level_Type is range 0 .. 7;

   Purple : constant Color_Type := (0.7, 0.0, 0.5);
   Length : constant Real       := 400.0;
   Corner : constant Point      := (90.0, 580.0);

   Level     : Level_Type;
   Current   : Point      := (0.0, 0.0);
   Direction : Angle_Deg  := Angle_Deg'(60.0);
   Doc       : PDF_Out_File;

   procedure Koch (Level : Level_Type; Length : Real) is
   begin
      if Level = 0 then
         Current := Current + Length * Point'(Sin (Direction, 360.0),
                                              Cos (Direction, 360.0));
         Doc.Line (Corner + Current);
      else
         Koch (Level - 1, Length / 3.0);  Direction := Direction -  60.0;
         Koch (Level - 1, Length / 3.0);  Direction := Direction + 120.0;
         Koch (Level - 1, Length / 3.0);  Direction := Direction -  60.0;
         Koch (Level - 1, Length / 3.0);
      end if;
   end Koch;

begin
   if Argument_Count /= 1 then
      Put_Line ("koch_curve <level>");
      Put_Line ("  <level>   0 .. 7");
      Put_Line ("open koch.pdf to view ouput");
      return;
   end if;
   Level := Level_Type'Value (Argument (1));

   Doc.Create ("koch.pdf");
   Doc.Page_Setup (A4_Portrait);
   Doc.Margins (Margins_Type'(Left   => Cm_2_5,
                              others => One_cm));
   Doc.Color (Purple);
   Doc.Move (Corner);
   for A in 1 .. 3 loop
      Koch (Level, Length);
      Direction := Direction + 120.0;
   end loop;
   Doc.Finish_Path (Close_Path => True,
                    Rendering  => Fill,
                    Rule       => Even_Odd);
   Doc.Close;
end Koch_Curve;