zoukankan      html  css  js  c++  java
  • [OpenGL] 不规则区域的填充算法

    不规则区域的填充算法

    一、简单递归

    利用Dfs实现简单递归填充。
    核心代码:

     1 // 简单深度搜索填充 (四连通)
     2 void DfsFill(int x, int y)
     3 {
     4     if (x < 0 || y < 0 || x>23 || y>23)
     5     {
     6         return;
     7     }
     8     if (a[x][y] == 0)
     9     {
    10         a[x][y] = 2;
    11         DfsFill(x - 1, y);
    12         DfsFill(x + 1, y);
    13         DfsFill(x, y - 1);
    14         DfsFill(x, y + 1);
    15     }
    16 }
    二、扫描线种子填充算法(四连通)
    1. 种子点(x,y)入栈。 
    2. 栈顶元素(x,y)出栈作为种子点。
    3. 从种子点(x,y)开始沿着扫描线向左右两个方向逐个像素进行填充,直到到达边界像素为止。
    4. 将上述填充区段的左右端点的横坐标分别记为xleft和xright.
    5. 在与当前扫描线相邻的上下两条扫描线的[xleft,xright]范围内进行检查,
    看看是否全部为边界像素或已填充像素,若存在着非边界且未填充的像素,那么将该区段的最右端像素作为种子点入栈。
    

    在这里插入图片描述

     1 // 扫描线种子填充算法(四连通)
     2 void ScanFill(int x, int y)
     3 {
     4     if (a[x][y]!=0)
     5     {
     6         return;
     7     }
     8     Pos first(x, y);
     9     s.push(first);
    10     while (!s.empty())
    11     {
    12         int rightX = 0;
    13         int leftX = 0;
    14         Pos cur = s.top();
    15         s.pop();
    16         a[cur.x][cur.y] = 2;
    17         // 遍历当前行
    18         for (int i = 1; i < 24; i++)
    19         {
    20             if (cur.x + i < 24)
    21             {
    22                 if (a[cur.x + i][cur.y] == 0)
    23                     a[cur.x + i][cur.y] = 2;
    24                 else
    25                 {
    26                     rightX = cur.x + i - 1;
    27                     break;
    28                 }
    29             }
    30             else
    31             {
    32                 rightX = 23;
    33             }
    34         }
    35         for (int i = 1; i < 24; i++)
    36         {
    37             if (cur.x - i > -1) 
    38             {
    39                 if (a[cur.x - i][cur.y] == 0)
    40                     a[cur.x - i][cur.y] = 2;
    41                 else
    42                 {
    43                     leftX = cur.x - i + 1;
    44                     break;
    45                 }
    46             }
    47             else
    48             {
    49                 leftX = 0;
    50             }
    51         }
    52 
    53         cout << leftX <<","<<rightX << endl;
    54 
    55         // 判断上行
    56         int upRightX = -1;
    57         for (int i = leftX;i<=rightX;i++)
    58         {
    59             upRightX = -1;
    60             if (a[i][cur.y+1]==0 && cur.y+1<24)
    61             {
    62                 upRightX = i;
    63             }
    64             if (upRightX != -1)
    65             {
    66                 Pos temPos(upRightX, cur.y + 1);
    67                 s.push(temPos);
    68             }
    69         }
    70 
    71         // 判断下行
    72         int downRightX = -1;
    73         for (int i = leftX; i <= rightX; i++)
    74         {
    75             downRightX = -1;
    76             if (a[i][cur.y - 1] == 0 && cur.y - 1 >=0)
    77             {
    78                 downRightX = i;
    79             }
    80             if (downRightX != -1)
    81             {
    82                 Pos temPos(downRightX, cur.y - 1);
    83                 s.push(temPos);
    84             }
    85         }
    86 
    87     }
    88 }

    完整代码:

      1 #include <cmath>
      2 #include <stack>
      3 #include "gl/glut.h"
      4 #include "iostream"
      5 using namespace std;
      6 
      7 #define PI 3.14
      8 
      9 struct Pos
     10 {
     11     int x;
     12     int y;
     13     Pos(int mx, int my) :x(mx), y(my) {};
     14     Pos() :x(0), y(0) {};
     15 };
     16 
     17 stack<Pos> s;
     18 int a[24][24] = { 0 };
     19 
     20 void init(void)
     21 {
     22     glClearColor(1.0, 1.0, 1.0, 1.0);
     23     glMatrixMode(GL_PROJECTION);//设置投影矩阵
     24     gluOrtho2D(0.0, 600.0, 0.0, 600.0);//二维视景区域
     25     glPointSize(12.0f);
     26 }
     27 // 画棋子
     28 void Drawtri(int x,int y,int color)
     29 {
     30     double n = 200;//分段数
     31     float R = 10;//半径
     32     int i;
     33     if (color == 1)
     34     {
     35         glColor3f(1.0, 0.0, 0.0);
     36     }
     37     else if (color == 2)
     38     {
     39         glColor3f(0.0, 1.0, 0.0);
     40     }
     41     glBegin(GL_POLYGON);
     42     glVertex2f(x, y);
     43     for (i = 0; i <= n; i++)
     44         glVertex2f(R*cos(2 * PI / n * i)+x, R*sin(2 * PI / n * i)+y);
     45     glEnd();
     46     glPopMatrix();
     47 }
     48 
     49 // 绘制格线
     50 void playMap()
     51 {
     52     glColor3f(0.0, 0.0, 0.0);
     53     glBegin(GL_LINES);
     54     for (int i = 0; i < 600; i += 25)
     55     {
     56         glVertex2f(i, 0);
     57         glVertex2f(i, 600);
     58     }
     59     for (int j = 0; j < 600; j += 25)
     60     {
     61         glVertex2f(0, j);
     62         glVertex2f(600, j);
     63     }
     64     glEnd();
     65     for (int k = 0; k < 24; k++)
     66     {
     67         for (int l = 0; l < 24; l++)
     68         {
     69             if (a[k][l] == 1)
     70             {
     71                 Drawtri(k * 25 + 12, l * 25 + 12,1);
     72             }
     73             else if (a[k][l] == 2)
     74             {
     75                 Drawtri(k * 25 + 12, l * 25 + 12, 2);
     76             }
     77         }
     78     }
     79 }
     80 
     81 // 简单深度搜索填充 (四连通)
     82 void DfsFill(int x, int y)
     83 {
     84     if (x < 0 || y < 0 || x>23 || y>23)
     85     {
     86         return;
     87     }
     88     if (a[x][y] == 0)
     89     {
     90         a[x][y] = 2;
     91         DfsFill(x - 1, y);
     92         DfsFill(x + 1, y);
     93         DfsFill(x, y - 1);
     94         DfsFill(x, y + 1);
     95     }
     96 }
     97 
     98 // 扫描线种子填充算法(四连通)
     99 void ScanFill(int x, int y)
    100 {
    101     if (a[x][y]!=0)
    102     {
    103         return;
    104     }
    105     Pos first(x, y);
    106     s.push(first);
    107     while (!s.empty())
    108     {
    109         int rightX = 0;
    110         int leftX = 0;
    111         Pos cur = s.top();
    112         s.pop();
    113         a[cur.x][cur.y] = 2;
    114         // 遍历当前行
    115         for (int i = 1; i < 24; i++)
    116         {
    117             if (cur.x + i < 24)
    118             {
    119                 if (a[cur.x + i][cur.y] == 0)
    120                     a[cur.x + i][cur.y] = 2;
    121                 else
    122                 {
    123                     rightX = cur.x + i - 1;
    124                     break;
    125                 }
    126             }
    127             else
    128             {
    129                 rightX = 23;
    130             }
    131         }
    132         for (int i = 1; i < 24; i++)
    133         {
    134             if (cur.x - i > -1) 
    135             {
    136                 if (a[cur.x - i][cur.y] == 0)
    137                     a[cur.x - i][cur.y] = 2;
    138                 else
    139                 {
    140                     leftX = cur.x - i + 1;
    141                     break;
    142                 }
    143             }
    144             else
    145             {
    146                 leftX = 0;
    147             }
    148         }
    149 
    150         cout << leftX <<","<<rightX << endl;
    151 
    152         // 判断上行
    153         int upRightX = -1;
    154         for (int i = leftX;i<=rightX;i++)
    155         {
    156             upRightX = -1;
    157             if (a[i][cur.y+1]==0 && cur.y+1<24)
    158             {
    159                 upRightX = i;
    160             }
    161             if (upRightX != -1)
    162             {
    163                 Pos temPos(upRightX, cur.y + 1);
    164                 s.push(temPos);
    165             }
    166         }
    167 
    168         // 判断下行
    169         int downRightX = -1;
    170         for (int i = leftX; i <= rightX; i++)
    171         {
    172             downRightX = -1;
    173             if (a[i][cur.y - 1] == 0 && cur.y - 1 >=0)
    174             {
    175                 downRightX = i;
    176             }
    177             if (downRightX != -1)
    178             {
    179                 Pos temPos(downRightX, cur.y - 1);
    180                 s.push(temPos);
    181             }
    182         }
    183 
    184     }
    185 }
    186 
    187 void displayFcn(void)
    188 {
    189     glClear(GL_COLOR_BUFFER_BIT);
    190     playMap();
    191     glFlush();
    192 }
    193 
    194 
    195 void mouse(GLint button, GLint action, GLint x, GLint y)
    196 {
    197     int curX, curY;
    198     if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN)
    199     {
    200         curX = x / 25;
    201         curY = (600 - y) / 25;
    202         a[curX][curY] = 1;
    203         glutPostRedisplay();//重绘窗口
    204     }
    205     if (button == GLUT_RIGHT_BUTTON && action == GLUT_DOWN)
    206     {
    207         curX = x / 25;
    208         curY = (600 - y) / 25;
    209         ScanFill(curX, curY);
    210         
    211         glutPostRedisplay();//重绘窗口
    212     }
    213 }
    214 
    215 
    216 void main(int argc, char** argv)
    217 {
    218     glutInit(&argc, argv);
    219     glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    220     glutInitWindowPosition(300, 100);
    221     glutInitWindowSize(600, 600);
    222     glutCreateWindow("mouse");
    223 
    224     init();
    225     glutDisplayFunc(displayFcn);
    226 
    227     glutMouseFunc(mouse);
    228 
    229     glutMainLoop();
    230 
    231 }
  • 相关阅读:
    01-HTML控件
    08-多线程
    07-Log日志
    06-File-文件
    05-函数式编程
    04-异常使用处理
    03-常用包模块
    02-包
    Java NIO(六) Selector
    Java NIO(四) Scatter/Gather
  • 原文地址:https://www.cnblogs.com/ruoh3kou/p/9893423.html
Copyright © 2011-2022 走看看