Task: Hilbert curve


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

struct Point {
    int x, y;

    
    void rot(int n, bool rx, bool ry) {
        if (!ry) {
            if (rx) {
                x = (n - 1) - x;
                y = (n - 1) - y;
            }
            std::swap(x, y);
        }
    }
};

Point fromD(int n, int d) {
    Point p = { 0, 0 };
    bool rx, ry;
    int t = d;
    for (int s = 1; s < n; s <<= 1) {
        rx = ((t & 2) != 0);
        ry = (((t ^ (rx ? 1 : 0)) & 1) != 0);
        p.rot(s, rx, ry);
        p.x += (rx ? s : 0);
        p.y += (ry ? s : 0);
        t >>= 2;
    }
    return p;
}

std::vector<Point> getPointsForCurve(int n) {
    std::vector<Point> points;
    for (int d = 0; d < n * n; ++d) {
        points.push_back(fromD(n, d));
    }
    return points;
}

std::vector<std::string> drawCurve(const std::vector<Point> &points, int n) {
    auto canvas = new char *[n];
    for (size_t i = 0; i < n; i++) {
        canvas[i] = new char[n * 3 - 2];
        std::memset(canvas[i], ' ', n * 3 - 2);
    }

    for (int i = 1; i < points.size(); i++) {
        auto lastPoint = points[i - 1];
        auto curPoint = points[i];
        int deltaX = curPoint.x - lastPoint.x;
        int deltaY = curPoint.y - lastPoint.y;
        if (deltaX == 0) {
            
            int row = std::max(curPoint.y, lastPoint.y);
            int col = curPoint.x * 3;
            canvas[row][col] = '|';
        } else {
            
            int row = curPoint.y;
            int col = std::min(curPoint.x, lastPoint.x) * 3 + 1;
            canvas[row][col] = '_';
            canvas[row][col + 1] = '_';
        }
    }

    std::vector<std::string> lines;
    for (size_t i = 0; i < n; i++) {
        std::string temp;
        temp.assign(canvas[i], n * 3 - 2);
        lines.push_back(temp);
    }
    return lines;
}

int main() {
    for (int order = 1; order < 6; order++) {
        int n = 1 << order;
        auto points = getPointsForCurve(n);
        std::cout << "Hilbert curve, order=" << order << '\n';
        auto lines = drawCurve(points, n);
        for (auto &line : lines) {
            std::cout << line << '\n';
        }
        std::cout << '\n';
    }
    return 0;
}






Python: iterations = 7
stroke_len = 600
angle_deg = 90
axiom = 'L'
sentence = axiom
rules = {
    'L': '+RF-LFL-FR+',
    'R': '-LF+RFR+FL-',
}

def setup():
    size(700, 700)
    global xo, yo
    xo, yo = 50, height - 50
    strokeWeight(1)
    noFill()
    generate(iterations)

def draw():
    background(0)
    translate(xo, yo)
    plot(radians(angle_deg))

def generate(n):
    global stroke_len, sentence
    for _ in range(n):
        stroke_len *= 0.5
        next_sentence = ''
        for c in sentence:
            next_sentence += rules.get(c, c)
        sentence = next_sentence

def plot(angle):
    for c in sentence:
        if c == 'F':
            stroke(255)
            line(0, 0, 0, -stroke_len)
            translate(0, -stroke_len)
        elif c == '+':
            rotate(angle)
        elif c == '-':
            rotate(-angle)

def keyPressed():
    global angle_deg, xo, yo, stroke_len
    if key == '-':
        angle_deg -= 5
        print(angle_deg)
    if str(key) in "=+":
        angle_deg += 5
        print(angle_deg)
    if key == 'a':
        stroke_len *= 2
    if key == 'z':
        stroke_len /= 2
    if keyCode == LEFT:
        xo -= 50
    if keyCode == RIGHT:
        xo += 50
    if keyCode == UP:
        yo -= 50
    if keyCode == DOWN:
        yo += 50