Загрузка данных


#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

// Структура для хранения параметров одной ромашки
typedef struct {
    int x, y;        // Координаты центра
    int petals;      // Количество лепестков
    double scale;    // Масштаб (для разнообразия размеров)
} Daisy;

// Вспомогательная функция для случайного числа в диапазоне [min, max]
static int rand_range(int min, int max) {
    return min + rand() % (max - min + 1);
}

int main() {
    srand((unsigned)time(NULL)); // Инициализация ГСЧ для разных результатов при каждом запуске

    Display *dpy = XOpenDisplay(NULL);
    if (!dpy) { fprintf(stderr, "Ошибка: не удалось открыть дисплей\n"); return 1; }

    int screen = DefaultScreen(dpy);
    Window root = RootWindow(dpy, screen);
    int win_w = 800, win_h = 600;
    int margin = 100; // Отступ от краев, чтобы цветы не обрезались

    Window win = XCreateSimpleWindow(dpy, root, 50, 50, win_w, win_h, 1,
                                     BlackPixel(dpy, screen), WhitePixel(dpy, screen));
    XSelectInput(dpy, win, ExposureMask | KeyPressMask | StructureNotifyMask);
    XMapWindow(dpy, win);

    GC gc = XCreateGC(dpy, win, 0, NULL);
    XSetFillStyle(dpy, gc, FillSolid); // Сплошная заливка

    // Настройка цветов
    Colormap cmap = DefaultColormap(dpy, screen);
    XColor xc;
    XAllocNamedColor(dpy, cmap, "skyblue", &xc, &xc); unsigned long blue   = xc.pixel;
    XAllocNamedColor(dpy, cmap, "yellow",  &xc, &xc); unsigned long yellow = xc.pixel;
    XAllocNamedColor(dpy, cmap, "white",   &xc, &xc); unsigned long white  = xc.pixel;

    // Корректное закрытие через крестик WM
    Atom wmDelete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
    XSetWMProtocols(dpy, win, &wmDelete, 1);

    // 1. Генерируем случайное количество ромашек (около 8)
    int num_daisies = rand_range(6, 10);
    Daisy *daisies = malloc(num_daisies * sizeof(Daisy));

    for (int i = 0; i < num_daisies; i++) {
        daisies[i].x = rand_range(margin, win_w - margin);
        daisies[i].y = rand_range(margin, win_h - margin);
        daisies[i].petals = rand_range(6, 10); // Каждый цветок имеет своё кол-во лепестков
        daisies[i].scale = 0.7 + (rand() % 60) / 100.0; // Масштаб от 0.7x до 1.2x
    }

    // Буфер для вершин одного лепестка (аппроксимация эллипса)
    const int PTS_COUNT = 48;
    XPoint *pts = malloc(PTS_COUNT * sizeof(XPoint));

    XEvent ev;
    int running = 1;
    while (running) {
        XNextEvent(dpy, &ev);
        switch (ev.type) {
            case Expose:
                // Белый фон
                XSetForeground(dpy, gc, white);
                XFillRectangle(dpy, win, gc, 0, 0, win_w, win_h);

                // Отрисовка всех сгенерированных ромашек
                for (int f = 0; f < num_daisies; f++) {
                    Daisy *d = &daisies[f];
                    double s = d->scale;

                    // Базовые размеры, умноженные на масштаб цветка
                    double petal_w = 28.0 * s; // полуширина
                    double petal_h = 85.0 * s; // полувысота
                    double dist    = 75.0 * s; // расстояние от центра цветка до центра лепестка
                    int    center_r = (int)(40.0 * s);

                    // Рисуем лепестки (голубые)
                    XSetForeground(dpy, gc, blue);
                    for (int i = 0; i < d->petals; i++) {
                        double angle = (2.0 * M_PI * i) / d->petals;
                        double cos_a = cos(angle);
                        double sin_a = sin(angle);

                        // Генерация повёрнутого эллипса
                        for (int p = 0; p < PTS_COUNT; p++) {
                            double t = (2.0 * M_PI * p) / PTS_COUNT;
                            // Локальные координаты эллипса (длинная ось по X)
                            double lx = petal_h * cos(t);
                            double ly = petal_w * sin(t);
                            // Матрица поворота на угол лепестка
                            double rx = lx * cos_a - ly * sin_a;
                            double ry = lx * sin_a + ly * cos_a;
                            // Смещение к позиции цветка
                            pts[p].x = (short)(d->x + rx + dist * cos_a);
                            pts[p].y = (short)(d->y + ry + dist * sin_a);
                        }
                        // Заливка многоугольника (Convex быстрее для выпуклых фигур)
                        XFillPolygon(dpy, win, gc, pts, PTS_COUNT, Convex, CoordModeOrigin);
                    }

                    // Рисуем центр (жёлтый круг, поверх лепестков)
                    XSetForeground(dpy, gc, yellow);
                    XFillArc(dpy, win, gc, d->x - center_r, d->y - center_r,
                             center_r * 2, center_r * 2, 0, 360 * 64);
                }
                break;

            case KeyPress:
                running = 0;
                break;
            case ClientMessage:
                if (ev.xclient.data.l[0] == wmDelete) running = 0;
                break;
        }
    }

    // Очистка ресурсов
    free(pts);
    free(daisies);
    XFreeGC(dpy, gc);
    XDestroyWindow(dpy, win);
    XCloseDisplay(dpy);
    return 0;
}