Task: Dragon curve



C#: using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

public class DragonCurve : Form
{
    private List<int> turns;
    private double startingAngle, side;

    public DragonCurve(int iter)
    {
        Size = new Size(800, 600);
        StartPosition = FormStartPosition.CenterScreen;
        DoubleBuffered = true;
        BackColor = Color.White;

        startingAngle = -iter * (Math.PI / 4);
        side = 400 / Math.Pow(2, iter / 2.0);

        turns = getSequence(iter);
    }

    private List<int> getSequence(int iter)
    {
        var turnSequence = new List<int>();
        for (int i = 0; i < iter; i++)
        {
            var copy = new List<int>(turnSequence);
            copy.Reverse();
            turnSequence.Add(1);
            foreach (int turn in copy)
            {
                turnSequence.Add(-turn);
            }
        }
        return turnSequence;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

        double angle = startingAngle;
        int x1 = 230, y1 = 350;
        int x2 = x1 + (int)(Math.Cos(angle) * side);
        int y2 = y1 + (int)(Math.Sin(angle) * side);
        e.Graphics.DrawLine(Pens.Black, x1, y1, x2, y2);
        x1 = x2;
        y1 = y2;
        foreach (int turn in turns)
        {
            angle += turn * (Math.PI / 2);
            x2 = x1 + (int)(Math.Cos(angle) * side);
            y2 = y1 + (int)(Math.Sin(angle) * side);
            e.Graphics.DrawLine(Pens.Black, x1, y1, x2, y2);
            x1 = x2;
            y1 = y2;
        }
    }

    [STAThread]
    static void Main()
    {
        Application.Run(new DragonCurve(14));
    }
}







COBOL:          >>SOURCE FORMAT FREE

identification division.
program-id. dragon.
environment division.
configuration section.
repository. function all intrinsic.
data division.
working-storage section.
01  segment-length pic 9 value 2.
01  mark pic x value '.'.
01  segment-count pic 9999 value 513.

01  segment pic 9999.
01  point pic 9999 value 1.
01  point-max pic 9999.
01  point-lim pic 9999 value 8192.
01  dragon-curve.
    03  filler occurs 8192.
        05  ydragon pic s9999.
        05  xdragon pic s9999.

01  x pic s9999 value 1.
01  y pic S9999 value 1.

01  xdelta pic s9 value 1. 
01  ydelta pic s9 value 0.

01  x-max pic s9999 value -9999.
01  x-min pic s9999 value 9999.
01  y-max pic s9999 value -9999.
01  y-min pic s9999 value 9999.

01  n pic 9999.
01  r pic 9.

01  xupper pic s9999.
01  yupper pic s9999.

01  window-line-number pic 99.
01  window-width pic 99 value 64.
01  window-height pic 99 value 22.
01  window.
    03  window-line occurs 22.
        05  window-point occurs 64 pic x.

01  direction pic x.

procedure division.
start-dragon.

    if segment-count * segment-length > point-lim
        
        compute segment-count = point-lim / segment-length
    end-if

    perform varying segment from 1 by 1
    until segment > segment-count

        
        
        
        

        
        divide 2 into segment giving n remainder r
        perform until r <> 0
            divide 2 into n giving n remainder r
        end-perform
        divide 2 into n giving n remainder r

        
        evaluate r also xdelta also ydelta
        when 0 also 1 also 0  
        when 1 also -1 also 0 
            
            move 0 to xdelta
            move 1 to ydelta
        when 1 also 1 also 0  
        when 0 also -1 also 0 
            
            move 0 to xdelta
            move -1 to ydelta
        when 0 also 0 also 1  
        when 1 also 0 also -1 
            
            move 0 to ydelta
            move -1 to xdelta
        when 1 also 0 also 1  
        when 0 also 0 also -1 
            
            move 0 to ydelta
            move 1 to xdelta
        end-evaluate

        
        perform segment-length times
            add xdelta to x
            add ydelta to y

            move x to xdragon(point)
            move y to ydragon(point)

            add 1 to point
        end-perform

        
        compute x-max = max(x, x-max)
        compute x-min = min(x, x-min)
        compute y-max = max(y, y-max)
        compute y-min = min(y, y-min)
        move point to point-max

    end-perform

    
    
    
    
    

    move 1 to yupper xupper

    perform with test after
    until direction <> 'h' and 'j' and 'k' and 'l'

        
        
        

        
        evaluate true
        when direction = 'h' 
        and xupper > x-min + window-width
           subtract 1 from xupper
        when direction = 'j' 
        and yupper < y-max - window-height
           add 1 to yupper
        when direction = 'k' 
        and yupper > y-min + window-height
           subtract 1 from yupper
        when direction = 'l' 
        and xupper < x-max - window-width
            add 1 to xupper
        end-evaluate

        
        move spaces to window
        perform varying point from 1 by 1
        until point > point-max
            if ydragon(point) >= yupper and < yupper + window-height
            and xdragon(point) >= xupper and < xupper + window-width
                
                compute y = ydragon(point) - yupper + 1
                compute x =  xdragon(point) - xupper + 1
                move mark to window-point(y, x)
            end-if
         end-perform

         
         perform varying window-line-number from 1 by 1
         until window-line-number > window-height
             display window-line(window-line-number)
         end-perform

         
         display 'hjkl?' with no advancing
         accept direction
    end-perform

    stop run
    .
end program dragon.