Draw rectangles, circles or arbitrary polygons in a m x n matrix

前端 未结 5 1390
我寻月下人不归
我寻月下人不归 2021-02-14 00:19

I want to simulate the flow around objects in two dimensions. Therefore I wrote a program in C which uses the Navier-Stokes equations to describe the motion of fluids. Now I cam

5条回答
  •  别跟我提以往
    2021-02-14 00:59

    If number of figures is not so high (e.g. less than 100) you can check for every pixel if it belongs to any polygon. You just need figure abstraction:

    /* Abstract struct for hloding figure (rectangle or elipse data)*/
    typedef struct _figure_t* figure_t;
    
    /* Pointer to pixel check algorithm implementation */
    typedef int (*is_pixel_belongs_t)(uint32_t, uint32_t, figure_t);
    
    struct _figure_t {
        is_pixel_belongs_t is_pixel_belongs;
    };
    
    /* figure implementation for rectangle */
    typedef struct _rectangle_t {
        is_pixel_belongs_t is_pixel_belongs;
        uint32_t x;
        uint32_t y;
        uint32_t width;
        uint32_t height;
    } * rectangle_t;
    
    int is_pixel_belongs_rectangle(uint32_t x, uint32_t y, rectangle_t rect) {
        int x_belongs (x >= rect->x) && (x <= (rect->x + rect->width));
        int y_belongs (y >= rect->y) && (y <= (rect->y + rect->height));
        return x_belongs && y_belongs;
    }
    
    figure_t make_rect(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
        rectangle_t result = (rectangle_t) malloc(sizeof(struct _rectangle_t));
        result->is_pixel_belongs = (is_pixel_belongs_t) is_pixel_belongs_rectangle;
        result->x = x;
        result->y = x;
        result->width  = width;
        result->height = height;
    }
    
    /* figure implementation for elipse */
    typedef struct _rectangle_t {
        is_pixel_belongs_t is_pixel_belongs;
        uint32_t x;
        uint32_t y;
        uint32_t width;
        uint32_t height;
    } * rectangle_t;
    
    /* Elipse implementation */
    /* x^2/a^2 + y^2/b^2 = 1*/
    figure_t make_elipse(uint32_t x, uint32_t y, uint32_t a, uint32_t b);
    
    
    void main() {
        #define NUM_FIGURES 10
        figure_t figures[NUM_FIGURES] = {
            make_rect(0, 0, 40, 40),
            make_elipse(256, 128, 80, 40),
            /* Add more figures*/
        }
    
        /* Initialize your image */
    
        /* For each pixel */
        for(uint32_t x = 0; x < width; ++x) {
            for(uint32_t y = 0; y < height; ++x) {
                /* For each figure check if pixel (x,y) belongs to it*/
                for(uint32_t figure_ii = 0; figure_ii < NUM_FIGURES; ++figure_ii) {
                    if (figures[figure_ii]->is_pixel_belongs(x, y)) {
                        image[x][y] = 1;
                        break;
                    }
                }
            }
        }
    }
    

    This is pretty straightforward approach and close to what you did. Inner loop by figures may affect performance, if you need to draw thousands/millions of arbitrary figures you would need to use aux structures. One option is binary space partitioning approach. I.e. organize your figures to binary tree so you can find a figure by pixel in O(log(n)) time where n is number of figures. Or you can spit your image to uniform grid and keep figures list for each tile.

提交回复
热议问题