Графические примитивы в dlib на языке D

Графические примитивы в dlib на языке D

dlib — это мощная и удобная библиотека для языка программирования D, предназначенная для работы с изображениями. В этой статье мы рассмотрим, как создать проект с использованием dlib, добавить зависимости, протестировать проект с примером создания изображения и реализовать основные графические примитивы, такие как линии (с использованием алгоритмов DDA и Брезенхэма), окружности, конические сечения, прямоугольники и закрашенные версии окружностей и прямоугольников. Дополнительно мы рассмотрим, как нарисовать правильный n-угольник.

Пример создания изображения

Создадим простой пример, который создаёт изображение и сохраняет его в файл.

Код для создания изображения

import dlib.image;
import dlib.image.io;

void main()
{
    // Создаем изображение размером 100x100 пикселей
    auto img = Image!(RGB, ubyte)(100, 100);

    // Заполняем изображение белым цветом
    img[] = RGB(255, 255, 255);

    // Сохраняем изображение в файл
    savePNG(img, "output.png");
}

Запустим наш проект:

dub run

В результате должен появиться файл output.png с изображением размером 100×100 пискелей, полностью заполненным белым цветом.

Реализация графических примитивов

Линии

Алгоритм DDA

void drawLineDDA(Image!(RGB, ubyte) img, int x1, int y1, int x2, int y2, RGB color)
{
    int dx = x2 - x1;
    int dy = y2 - y1;

    int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);

    float xIncrement = dx / float(steps);
    float yIncrement = dy / float(steps);

    float x = x1;
    float y = y1;

    for (int i = 0; i <= steps; i++)
    {
        img[cast(int)x, cast(int)y] = color;
        x += xIncrement;
        y += yIncrement;
    }
}

Алгоритм Брезенхэма

void drawLineBresenham(Image!(RGB, ubyte) img, int x1, int y1, int x2, int y2, RGB color)
{
    int dx = abs(x2 - x1);
    int dy = abs(y2 - y1);
    int sx = x1 < x2 ? 1 : -1;
    int sy = y1 < y2 ? 1 : -1;
    int err = dx - dy;

    while (true)
    {
        img[x1, y1] = color;

        if (x1 == x2 && y1 == y2) break;
        int e2 = 2 * err;
        if (e2 > -dy) { err -= dy; x1 += sx; }
        if (e2 < dx) { err += dx; y1 += sy; }
    }
}

Окружности

Алгоритм Брезенхэма

void drawCircle(Image!(RGB, ubyte) img, int xc, int yc, int r, RGB color)
{
    int x = 0;
    int y = r;
    int d = 3 - 2 * r;
    drawCirclePoints(img, xc, yc, x, y, color);
    while (y >= x)
    {
        x++;
        if (d > 0)
        {
            y--;
            d = d + 4 * (x - y) + 10;
        }
        else
        {
            d = d + 4 * x + 6;
        }
        drawCirclePoints(img, xc, yc, x, y, color);
    }
}

void drawCirclePoints(Image!(RGB, ubyte) img, int xc, int yc, int x, int y, RGB color)
{
    img[xc + x, yc + y] = color;
    img[xc - x, yc + y] = color;
    img[xc + x, yc - y] = color;
    img[xc - x, yc - y] = color;
    img[xc + y, yc + x] = color;
    img[xc - y, yc + x] = color;
    img[xc + y, yc - x] = color;
    img[xc - y, yc - x] = color;
}

Прямоугольники

void drawRectangle(Image!(RGB, ubyte) img, int x1, int y1, int x2, int y2, RGB color)
{
    for (int x = x1; x <= x2; x++)
    {
        img[x, y1] = color;
        img[x, y2] = color;
    }
    for (int y = y1; y <= y2; y++)
    {
        img[x1, y] = color;
        img[x2, y] = color;
    }
}

Закрашенные окружности и прямоугольники

Закрашенная окружность

void fillCircle(Image!(RGB, ubyte) img, int xc, int yc, int r, RGB color)
{
    for (int y = -r; y <= r; y++)
    {
        for (int x = -r; x <= r; x++)
        {
            if (x * x + y * y <= r * r)
            {
                img[xc + x, yc + y] = color;
            }
        }
    }
}

Закрашенный прямоугольник

void fillRectangle(Image!(RGB, ubyte) img, int x1, int y1, int x2, int y2, RGB color)
{
    for (int y = y1; y <= y2; y++)
    {
        for (int x = x1; x <= x2; x++)
        {
            img[x, y] = color;
        }
    }
}

Правильный n-угольник

import std.math : cos, sin, PI;

void drawPolygon(Image!(RGB, ubyte) img, int xc, int yc, int r, int n, RGB color)
{
    double angleStep = 2 * PI / n;
    int[] xPoints = new int[n];
    int[] yPoints = new int[n];

    for (int i = 0; i < n; i++)
    {
        xPoints[i] = xc + cast(int)(r * cos(i * angleStep));
        yPoints[i] = yc + cast(int)(r * sin(i * angleStep));
    }

    for (int i = 0; i < n; i++)
    {
        int nextIndex = (i + 1) % n;
        drawLineBresenham(img, xPoints[i], yPoints[i], xPoints[nextIndex], yPoints[nextIndex], color);
    }
}

Карпов Ярослав

Автор статьи:

Обновлено:

28.05.2024


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *