Исправь следующую проблему в этом коде:
1. При зуме с максимального отдаления srcRect сначала сдвигается в сторону курсора, пока не достигнет края, и только после этого начинает корректный зум.
2. Добавь рисование полигонов поверх карты(бэкграунда) как в коде polygon_drawer.c. Точки полигона должны устанавливаться ровно на пиксели изображения. Полигоны должны быть полупрозрачными. Цвет полигона должен задаваться случайно. напиши код рисования полигонов в файлах EProvince.c и .EProvince.h. Свяжи эти файлы с mainEditor.c

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
#include "zoom.h"

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600

int main(int argc, char *argv[])
{
    SDL_Window *window = NULL;
    SDL_Renderer *renderer = NULL;
    SDL_Texture *texture = NULL;
    SDL_Event event;
    int quit = 0;

    int image_width, image_height;

    // Initialize SDL
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
        return -1;
    }

    // Initialize SDL_image
    if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG))
    {
        printf("SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError());
        SDL_Quit();
        return -1;
    }

    // Create window
    window = SDL_CreateWindow("OpenAge Map Editor",
                              SDL_WINDOWPOS_CENTERED,
                              SDL_WINDOWPOS_CENTERED,
                              WINDOW_WIDTH,
                              WINDOW_HEIGHT,
                              SDL_WINDOW_RESIZABLE);

    if (window == NULL)
    {
        printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
        IMG_Quit();
        SDL_Quit();
        return -1;
    }

    // Create renderer
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    if (renderer == NULL)
    {
        printf("Renderer could not be created! SDL_Error: %s\n", SDL_GetError());
        SDL_DestroyWindow(window);
        IMG_Quit();
        SDL_Quit();
        return -1;
    }

    // Load image
    SDL_Surface *loadedSurface = IMG_Load("./map/world/background.png");
    if (loadedSurface == NULL)
    {
        printf("Unable to load image %s! SDL_image Error: %s\n", "./map/world/background.png", IMG_GetError());
        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(window);
        IMG_Quit();
        SDL_Quit();
        return -1;
    }

    // Create texture from surface
    texture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
    if (texture == NULL)
    {
        printf("Unable to create texture from %s! SDL Error: %s\n", "./map/world/background.png", SDL_GetError());
        SDL_FreeSurface(loadedSurface);
        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(window);
        IMG_Quit();
        SDL_Quit();
        return -1;
    }

    image_width = loadedSurface->w;
    image_height = loadedSurface->h;

    SDL_FreeSurface(loadedSurface);

    // Get initial window size
    int window_width, window_height;
    SDL_GetWindowSize(window, &window_width, &window_height);

    // Initialize zoom and camera
    init_zoom(image_width, image_height, window_width, window_height);

    // Main loop
    while (!quit)
    {
        // Event handling
        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_QUIT:
                    quit = 1;
                    break;

                case SDL_WINDOWEVENT:
                    if (event.window.event == SDL_WINDOWEVENT_RESIZED)
                    {
                        // Update window size
                        SDL_GetWindowSize(window, &window_width, &window_height);
                        set_window_size(window_width, window_height);
                    }
                    break;

                case SDL_MOUSEBUTTONDOWN:
                    if (event.button.button == SDL_BUTTON_LEFT)
                    {
                        // Start dragging
                        start_camera_drag(event.button.x, event.button.y);
                    }
                    break;

                case SDL_MOUSEBUTTONUP:
                    if (event.button.button == SDL_BUTTON_LEFT)
                    {
                        // Stop dragging
                        stop_camera_drag();
                    }
                    break;

                case SDL_MOUSEMOTION:
                    // Update camera dragging
                    update_camera_drag(event.motion.x, event.motion.y);
                    break;

                case SDL_MOUSEWHEEL:
                {
                    // Get mouse position
                    int mouse_x, mouse_y;
                    SDL_GetMouseState(&mouse_x, &mouse_y);
                    // Zoom in and out
                    if (event.wheel.y > 0)
                    {
                        zoom_in(mouse_x, mouse_y);
                    }
                    else if (event.wheel.y < 0)
                    {
                        zoom_out(mouse_x, mouse_y);
                    }
                    break;
                }

                default:
                    break;
            }
        }

        // Update zoom level
        update_zoom();

        // Get the source rectangle for rendering
        SDL_Rect src_rect = get_source_rect();

        // Set the destination rectangle (where to render the image in the window)
        SDL_Rect dst_rect;
        dst_rect.x = 0;
        dst_rect.y = 0;
        dst_rect.w = window_width;
        dst_rect.h = window_height;

        // Clear renderer
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // Black background
        SDL_RenderClear(renderer);

        // Render the texture
        SDL_RenderCopy(renderer, texture, &src_rect, &dst_rect);

        // Update screen
        SDL_RenderPresent(renderer);

        // Delay to control frame rate
        SDL_Delay(16); // Approximately 60 frames per second

    }

    // Clean up
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    IMG_Quit();
    SDL_Quit();

    return 0;

}

//zoom.c
#include "zoom.h"
#include <math.h> // Для функции fabs()

static float zoom_level = 1.0f;
static float zoom_target = 1.0f;
static float zoom_speed = 0.1f;
static const float initial_zoom_speed = 0.5f; // Стартовая скорость зума
static const float min_zoom_speed = 0.1f;     // Минимальная скорость зума
static const float zoom_factor = 1.1f;        // Zoom increment factor

// Image and window dimensions
static int image_width = 0;
static int image_height = 0;
static int window_width = 0;
static int window_height = 0;

// Camera properties
static float camera_x = 0.0f;
static float camera_y = 0.0f;

static int dragging = 0;
static int prev_mouse_x = 0;
static int prev_mouse_y = 0;

// Variables for zooming around cursor
static int is_zooming = 0;
static float cursor_world_x = 0.0f;
static float cursor_world_y = 0.0f;
static int cursor_screen_x = 0;
static int cursor_screen_y = 0;

// Initialize zoom and camera settings
void init_zoom(int img_width, int img_height, int win_width, int win_height)
{
    zoom_level = 1.0f;
    zoom_target = 1.0f;
    image_width = img_width;
    image_height = img_height;
    window_width = win_width;
    window_height = win_height;
    camera_x = 0.0f;
    camera_y = 0.0f;
}

// Zoom functions
void zoom_in(int mouse_x, int mouse_y)
{
    // Store the world coordinates under the cursor
    cursor_world_x = camera_x + (float)mouse_x / zoom_level;
    cursor_world_y = camera_y + (float)mouse_y / zoom_level;
    cursor_screen_x = mouse_x;
    cursor_screen_y = mouse_y;

    zoom_target *= zoom_factor;
    is_zooming = 1;
    zoom_speed = initial_zoom_speed;
}

void zoom_out(int mouse_x, int mouse_y)
{
    // Store the world coordinates under the cursor
    cursor_world_x = camera_x + (float)mouse_x / zoom_level;
    cursor_world_y = camera_y + (float)mouse_y / zoom_level;
    cursor_screen_x = mouse_x;
    cursor_screen_y = mouse_y;

    zoom_target /= zoom_factor;
    is_zooming = 1;
    zoom_speed = initial_zoom_speed;
}

void update_zoom()
{
    // Smoothly interpolate towards the target zoom level
    float prev_zoom_level = zoom_level;
    zoom_level += (zoom_target - zoom_level) * zoom_speed;

    // Decrease zoom_speed gradually
    if (is_zooming)
    {
        zoom_speed *= 0.9f; // Decrease zoom_speed
        if (zoom_speed < min_zoom_speed)
        {
            zoom_speed = min_zoom_speed;
            is_zooming = 0; // Stop decreasing zoom_speed
        }

        // Adjust camera position to keep the cursor world position under the cursor
        camera_x = cursor_world_x - (float)cursor_screen_x / zoom_level;
        camera_y = cursor_world_y - (float)cursor_screen_y / zoom_level;
    }

    // Clamp zoom level
    if (zoom_level < 0.1f)
    {
        zoom_level = 0.1f;
        zoom_target = 0.1f;
    }
    if (zoom_level > 10.0f)
    {
        zoom_level = 10.0f;
        zoom_target = 10.0f;
    }
}

// Camera drag functions
void start_camera_drag(int mouse_x, int mouse_y)
{
    dragging = 1;
    prev_mouse_x = mouse_x;
    prev_mouse_y = mouse_y;
}

void stop_camera_drag()
{
    dragging = 0;
}

void update_camera_drag(int mouse_x, int mouse_y)
{
    if (dragging)
    {
        // Calculate the difference in mouse movement
        int delta_x = mouse_x - prev_mouse_x;
        int delta_y = mouse_y - prev_mouse_y;

        // Update the camera position inversely to the mouse movement
        camera_x -= delta_x / zoom_level;
        camera_y -= delta_y / zoom_level;

        // Update previous mouse position
        prev_mouse_x = mouse_x;
        prev_mouse_y = mouse_y;
    }
}

// Window resize handling
void set_window_size(int win_width, int win_height)
{
    window_width = win_width;
    window_height = win_height;
}

// Getters
float get_zoom_level()
{
    return zoom_level;
}

SDL_Rect get_source_rect()
{
    SDL_Rect src_rect;

    // Calculate the aspect ratio of the window
    float window_aspect_ratio = (float)window_width / (float)window_height;

    // Calculate the visible width and height based on zoom level
    float visible_width = window_width / zoom_level;
    float visible_height = window_height / zoom_level;

    // Adjust visible area to maintain aspect ratio
    float adjusted_width = visible_width;
    float adjusted_height = visible_height;

    float current_aspect_ratio = visible_width / visible_height;

    if (current_aspect_ratio > window_aspect_ratio)
    {
        // Width is too big compared to height, adjust width
        adjusted_width = visible_height * window_aspect_ratio;
    }
    else if (current_aspect_ratio < window_aspect_ratio)
    {
        // Height is too big compared to width, adjust height
        adjusted_height = visible_width / window_aspect_ratio;
    }

    visible_width = adjusted_width;
    visible_height = adjusted_height;

    // Ensure visible dimensions do not exceed image dimensions
    if (visible_width > image_width)
    {
        visible_width = (float)image_width;
        visible_height = visible_width / window_aspect_ratio;
    }

    if (visible_height > image_height)
    {
        visible_height = (float)image_height;
        visible_width = visible_height * window_aspect_ratio;
    }

    // Adjust camera position to ensure src_rect is within image boundaries
    float max_camera_x = image_width - visible_width;
    float max_camera_y = image_height - visible_height;

    if (camera_x < 0)
        camera_x = 0;
    if (camera_x > max_camera_x)
        camera_x = max_camera_x;

    if (camera_y < 0)
        camera_y = 0;
    if (camera_y > max_camera_y)
        camera_y = max_camera_y;

    src_rect.x = (int)camera_x;
    src_rect.y = (int)camera_y;
    src_rect.w = (int)visible_width;
    src_rect.h = (int)visible_height;

    return src_rect;
}

//zoom.h
#ifndef ZOOM_H
#define ZOOM_H

#include <SDL2/SDL.h>

// Initialize zoom and camera settings
void init_zoom(int image_width, int image_height, int window_width, int window_height);

// Zoom controls
void zoom_in(int mouse_x, int mouse_y);
void zoom_out(int mouse_x, int mouse_y);
void update_zoom();

// Camera controls
void start_camera_drag(int mouse_x, int mouse_y);
void stop_camera_drag();
void update_camera_drag(int mouse_x, int mouse_y);

// Window resize handling
void set_window_size(int window_width, int window_height);

// Getters
float get_zoom_level();
SDL_Rect get_source_rect();

#endif // ZOOM_H

//polygon_drawer.c
#include <SDL2/SDL.h>
#include <SDL2/SDL2_gfxPrimitives.h>

#define MAX_POINTS 1000

int main(int argc, char *argv[])
{
    SDL_Window *window;
    SDL_Renderer *renderer;
    SDL_Event event;
    int quit = 0;
    int numPoints = 0;
    Sint16 vx[MAX_POINTS];
    Sint16 vy[MAX_POINTS];

    // Initialize SDL
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init failed: %s\n", SDL_GetError());
        return 1;
    }

    // Create window and renderer
    if (SDL_CreateWindowAndRenderer(800, 600, SDL_WINDOW_SHOWN, &window, &renderer) < 0)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateWindowAndRenderer failed: %s\n", SDL_GetError());
        SDL_Quit();
        return 1;
    }

    SDL_SetWindowTitle(window, "Interactive Polygon Drawer");

    // Main loop
    while (!quit)
    {
        // Event handling
        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
            case SDL_QUIT:
                quit = 1;
                break;
            case SDL_MOUSEBUTTONDOWN:
                if (event.button.button == SDL_BUTTON_LEFT)
                {
                    // Add point
                    if (numPoints < MAX_POINTS)
                    {
                        vx[numPoints] = event.button.x;
                        vy[numPoints] = event.button.y;
                        numPoints++;
                    }
                }
                break;
            default:
                break;
            }
        }

        // Clear renderer
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // Black background
        SDL_RenderClear(renderer);

        // Draw filled polygon if we have at least 3 points
        if (numPoints >= 3)
        {
            filledPolygonRGBA(renderer, vx, vy, numPoints, 255, 0, 0, 255); // Red filled polygon
        }

        // Draw points
        for (int i = 0; i < numPoints; i++)
        {
            filledCircleRGBA(renderer, vx[i], vy[i], 3, 0, 255, 0, 255); // Green points
        }

        // Present renderer
        SDL_RenderPresent(renderer);

        // Delay to limit frame rate
        SDL_Delay(16); // Approximately 60 frames per second
    }

    // Clean up
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}