OpenGL 불규칙 영역 충전 알고리즘 구현
간단 한 귀환
Dfs 를 이용 하여 간단 한 재 귀적 충전 을 실현 합 니 다.
핵심 코드:
// ( )
void DfsFill(int x, int y)
{
if (x < 0 || y < 0 || x>23 || y>23)
{
return;
}
if (a[x][y] == 0)
{
a[x][y] = 2;
DfsFill(x - 1, y);
DfsFill(x + 1, y);
DfsFill(x, y - 1);
DfsFill(x, y + 1);
}
}
2.스캐닝 라인 피 드 충전 알고리즘(4 연결)1.피 드 포인트(x,y)를 창고 에 넣는다.
2.스 택 꼭대기 요소(x,y)는 스 택 을 피 드 포인트 로 합 니 다.
3.피 드 점(x,y)부터 스캐닝 라인 을 따라 좌우 두 방향 으로 픽 셀 을 하나씩 채 워 경계 픽 셀 에 도달 할 때 까지 채 웁 니 다.
4.상기 충전 구간 의 좌우 점 의 가로 좌 표를 각각 xleft 와 xright 로 기록한다.
5.현재 스 캔 라인 과 인접 한 상하 두 스 캔 라인 의[xleft,xright]범위 내 에서 모두 경계 픽 셀 이나 채 워 진 픽 셀 인지 확인 합 니 다.경계 가 아 닌 채 워 지지 않 은 픽 셀 이 존재 한다 면 이 구간 의 맨 오른쪽 픽 셀 을 피 드 점 으로 스 택 에 넣 습 니 다.
void ScanFill(int x, int y)
{
if (a[x][y]!=0)
{
return;
}
Pos first(x, y);
s.push(first);
while (!s.empty())
{
int rightX = 0;
int leftX = 0;
Pos cur = s.top();
s.pop();
a[cur.x][cur.y] = 2;
//
for (int i = 1; i < 24; i++)
{
if (cur.x + i < 24)
{
if (a[cur.x + i][cur.y] == 0)
a[cur.x + i][cur.y] = 2;
else
{
rightX = cur.x + i - 1;
break;
}
}
if (i==23)
{
rightX = 23;
}
}
for (int i = 1; i < 24; i++)
{
if (cur.x - i > -1)
{
if (a[cur.x - i][cur.y] == 0)
a[cur.x - i][cur.y] = 2;
else
{
leftX = cur.x - i + 1;
break;
}
}
if (i == 0)
{
leftX = 0;
}
}
cout << leftX <<","<<rightX << endl;
//
int upRightX = -1;
for (int i = leftX;i<=rightX;i++)
{
if (a[i][cur.y+1]==0 && cur.y+1<24)
{
upRightX = i;
}
}
if (upRightX!=-1)
{
Pos temPos(upRightX,cur.y+1);
s.push(temPos);
}
//
int downRightX = -1;
for (int i = leftX; i <= rightX; i++)
{
if (a[i][cur.y - 1] == 0 && cur.y - 1 >=0)
{
downRightX = i;
}
}
if (downRightX != -1)
{
Pos temPos(downRightX, cur.y - 1);
s.push(temPos);
}
}
}
전체 코드:
#include <cmath>
#include <stack>
#include "gl/glut.h"
#include "iostream"
using namespace std;
#define PI 3.14
struct Pos
{
int x;
int y;
Pos(int mx, int my) :x(mx), y(my) {};
Pos() :x(0), y(0) {};
};
stack<Pos> s;
int a[24][24] = { 0 };
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);//
gluOrtho2D(0.0, 600.0, 0.0, 600.0);//
glPointSize(12.0f);
}
//
void Drawtri(int x,int y,int color)
{
double n = 200;//
float R = 10;//
int i;
if (color == 1)
{
glColor3f(1.0, 0.0, 0.0);
}
else if (color == 2)
{
glColor3f(0.0, 1.0, 0.0);
}
glBegin(GL_POLYGON);
glVertex2f(x, y);
for (i = 0; i <= n; i++)
glVertex2f(R*cos(2 * PI / n * i)+x, R*sin(2 * PI / n * i)+y);
glEnd();
glPopMatrix();
}
//
void playMap()
{
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINES);
for (int i = 0; i < 600; i += 25)
{
glVertex2f(i, 0);
glVertex2f(i, 600);
}
for (int j = 0; j < 600; j += 25)
{
glVertex2f(0, j);
glVertex2f(600, j);
}
glEnd();
for (int k = 0; k < 24; k++)
{
for (int l = 0; l < 24; l++)
{
if (a[k][l] == 1)
{
Drawtri(k * 25 + 12, l * 25 + 12,1);
}
else if (a[k][l] == 2)
{
Drawtri(k * 25 + 12, l * 25 + 12, 2);
}
}
}
}
// ( )
void DfsFill(int x, int y)
{
if (x < 0 || y < 0 || x>23 || y>23)
{
return;
}
if (a[x][y] == 0)
{
a[x][y] = 2;
DfsFill(x - 1, y);
DfsFill(x + 1, y);
DfsFill(x, y - 1);
DfsFill(x, y + 1);
}
}
// ( )
void ScanFill(int x, int y)
{
if (a[x][y]!=0)
{
return;
}
Pos first(x, y);
s.push(first);
while (!s.empty())
{
int rightX = 0;
int leftX = 0;
Pos cur = s.top();
s.pop();
a[cur.x][cur.y] = 2;
//
for (int i = 1; i < 24; i++)
{
if (cur.x + i < 24)
{
if (a[cur.x + i][cur.y] == 0)
a[cur.x + i][cur.y] = 2;
else
{
rightX = cur.x + i - 1;
break;
}
}
if (i==23)
{
rightX = 23;
}
}
for (int i = 1; i < 24; i++)
{
if (cur.x - i > -1)
{
if (a[cur.x - i][cur.y] == 0)
a[cur.x - i][cur.y] = 2;
else
{
leftX = cur.x - i + 1;
break;
}
}
if (i == 0)
{
leftX = 0;
}
}
cout << leftX <<","<<rightX << endl;
//
int upRightX = -1;
for (int i = leftX;i<=rightX;i++)
{
if (a[i][cur.y+1]==0 && cur.y+1<24)
{
upRightX = i;
}
}
if (upRightX!=-1)
{
Pos temPos(upRightX,cur.y+1);
s.push(temPos);
}
//
int downRightX = -1;
for (int i = leftX; i <= rightX; i++)
{
if (a[i][cur.y - 1] == 0 && cur.y - 1 >=0)
{
downRightX = i;
}
}
if (downRightX != -1)
{
Pos temPos(downRightX, cur.y - 1);
s.push(temPos);
}
}
}
void displayFcn(void)
{
glClear(GL_COLOR_BUFFER_BIT);
playMap();
glFlush();
}
void mouse(GLint button, GLint action, GLint x, GLint y)
{
int curX, curY;
if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN)
{
curX = x / 25;
curY = (600 - y) / 25;
a[curX][curY] = 1;
glutPostRedisplay();//
}
if (button == GLUT_RIGHT_BUTTON && action == GLUT_DOWN)
{
curX = x / 25;
curY = (600 - y) / 25;
ScanFill(curX, curY);
glutPostRedisplay();//
}
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(300, 100);
glutInitWindowSize(600, 600);
glutCreateWindow("mouse");
init();
glutDisplayFunc(displayFcn);
glutMouseFunc(mouse);
glutMainLoop();
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Common Lisp에서 GPU 벡터 기반 글꼴 렌더링그때 조금만 쓴 문자열 드로잉 라이브러리의 소개입니다. 브라우저의 렌더링 엔진을 만드는데 있어서, 취급하기 쉬운 묘화 백엔드가 필요했다. Gecko는 Cairo를 사용하는 것처럼 보였습니다 (과거의 이야기?) 그래서...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.